Skip to content

Commit c71b0db

Browse files
committed
Custom mail providers distributed under META-INF/javamail.properties are no longer loaded with Jakarta Mail 2.1.5 #812
Signed-off-by: Jorge Bescos Gascon <[email protected]>
1 parent 82f1e48 commit c71b0db

File tree

11 files changed

+232
-100
lines changed

11 files changed

+232
-100
lines changed

api/src/main/java/jakarta/mail/Provider.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
* configuring providers using the Java SE
2323
* {@link java.util.ServiceLoader ServiceLoader} mechanism.
2424
* As an alternative the values could come from the
25-
* javamail.providers and javamail.default.providers
25+
* javamail.providers, javamail.default.providers,
26+
* jakarta.providers and jakarta.default.providers
2627
* resource files. An application may also create and
2728
* register a Provider object to dynamically add support
2829
* for a new provider.

api/src/main/java/jakarta/mail/Session.java

Lines changed: 92 additions & 71 deletions
Large diffs are not rendered by default.

api/src/main/java/jakarta/mail/internet/MimeUtility.java

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import java.util.NoSuchElementException;
4141
import java.util.Properties;
4242
import java.util.StringTokenizer;
43+
import java.util.logging.Level;
44+
import java.util.logging.Logger;
4345

4446
/**
4547
* This is a utility class that provides various MIME related
@@ -139,9 +141,12 @@ public class MimeUtility {
139141
private MimeUtility() {
140142
}
141143

144+
private static final Logger LOGGER = Logger.getLogger(MimeUtility.class.getName());
145+
142146
public static final int ALL = -1;
143147

144148
// This is for backwards compatibility. Eventually we have to remove the second value of the next array.
149+
// Note this order is different than in Session arrays. This is because here the key-value pair is overwritten.
145150
private static final String[] CHARSET_MAP_RESOURCES = new String[] {"/META-INF/jakarta.charset.map", "/META-INF/javamail.charset.map"};
146151

147152
// cached map of whether a charset is compatible with ASCII
@@ -1353,29 +1358,27 @@ static String getDefaultMIMECharset() {
13531358
java2mime = new HashMap<>(40);
13541359
mime2java = new HashMap<>(14);
13551360

1356-
try {
1357-
// Use this class's classloader to load the mapping file
1358-
// XXX - we should use SecuritySupport, but it's in another package
1359-
InputStream is = resource(CHARSET_MAP_RESOURCES);
1360-
1361-
if (is != null) {
1362-
try {
1361+
// Use this class's classloader to load the mapping file
1362+
// XXX - we should use SecuritySupport, but it's in another package
1363+
for (int i = 0; i < CHARSET_MAP_RESOURCES.length; i++) {
1364+
String charsetResource = CHARSET_MAP_RESOURCES[i];
1365+
try (InputStream is = MimeUtility.class.getResourceAsStream(charsetResource)) {
1366+
if (is != null) {
13631367
LineInputStream lineInput = StreamProvider.provider().inputLineStream(is, false);
13641368

13651369
// Load the JDK-to-MIME charset mapping table
13661370
loadMappings(lineInput, java2mime);
13671371

13681372
// Load the MIME-to-JDK charset mapping table
13691373
loadMappings(lineInput, mime2java);
1370-
} finally {
1371-
try {
1372-
is.close();
1373-
} catch (Exception cex) {
1374-
// ignore
1375-
}
13761374
}
1375+
// We already know size is two, but just in case, we don't want to fail here for a logger reason
1376+
if (i == 0 && CHARSET_MAP_RESOURCES.length == 2) {
1377+
LOGGER.log(Level.WARNING, "[DEPRECATED] {0} is deprecated and will be removed. Future versions will require {1}.",
1378+
new Object[]{CHARSET_MAP_RESOURCES[0], CHARSET_MAP_RESOURCES[1]});
1379+
}
1380+
} catch (Exception ex) {
13771381
}
1378-
} catch (Exception ex) {
13791382
}
13801383

13811384
// If we didn't load the tables, e.g., because we didn't have
@@ -1444,16 +1447,6 @@ static String getDefaultMIMECharset() {
14441447
mime2java.put("gbk", "GB18030");
14451448
}
14461449
}
1447-
1448-
private static InputStream resource(String[] resources) {
1449-
for (String resource : resources) {
1450-
InputStream is = MimeUtility.class.getResourceAsStream(resource);
1451-
if (is != null) {
1452-
return is;
1453-
}
1454-
}
1455-
return null;
1456-
}
14571450

14581451
private static void loadMappings(LineInputStream is,
14591452
Map<String, String> table) {

api/src/test/java/jakarta/mail/SessionTest.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616

1717
package jakarta.mail;
1818

19+
import java.util.Arrays;
1920
import java.util.Properties;
21+
import java.util.stream.Stream;
22+
23+
import jakarta.mail.Provider.Type;
2024

2125
import org.junit.Test;
2226

@@ -25,12 +29,31 @@
2529
public class SessionTest {
2630

2731
@Test
28-
public void issue527() throws NoSuchProviderException {
32+
public void issue527And812() throws NoSuchProviderException {
2933
Session session = Session.getInstance(new Properties());
34+
Stream<Provider> providerStream = Arrays.stream(session.getProviders());
35+
// test exists in both jakarta.providers and javamail.providers
36+
long count = providerStream.filter(p -> "test".equals(p.getProtocol())).count();
37+
assertEquals(2, count);
3038
Provider provider = session.getProvider("test");
39+
// javamail.providers one has precedence in case of conflict
40+
assertEquals(JavaMail.class.getName(), provider.getClassName());
41+
provider = session.getProvider("test2");
3142
assertEquals(Jakarta.class.getName(), provider.getClassName());
43+
provider = session.getProvider("test3");
44+
assertEquals(JavaMail.class.getName(), provider.getClassName());
3245
}
3346

47+
@Test
48+
public void byProperty() throws NoSuchProviderException {
49+
Properties prop = new Properties();
50+
prop.put("mail.test4.class", Jakarta.class.getName());
51+
Session session = Session.getInstance(prop);
52+
// protocol test4 exists in both with same class, but javamail.providers has precedence
53+
Provider provider = session.getProvider("test4");
54+
assertEquals("OracleMail", provider.getVendor());
55+
}
56+
3457
public static class Jakarta extends Store {
3558

3659
protected Jakarta(Session session, URLName urlname) {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package jakarta.mail.internet;
18+
19+
import org.junit.Test;
20+
21+
import static org.junit.Assert.assertEquals;
22+
23+
public class MimeUtilityTest {
24+
25+
@Test
26+
public void issue812() {
27+
// Same value in both files
28+
assertEquals("ISO-8859-1", MimeUtility.mimeCharset("8859_1"));
29+
// Conflict value, javamail.charset.map wins
30+
assertEquals("ISO-8859-1", MimeUtility.mimeCharset("iso8859_1"));
31+
// Exists only in javamail.charset.map
32+
assertEquals("ISO-8859-3", MimeUtility.mimeCharset("8859_3"));
33+
// Exists only in jakarta.charset.map
34+
assertEquals("ISO-8859-4", MimeUtility.mimeCharset("8859_4"));
35+
}
36+
37+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#
2+
# Copyright (c) 2025 Oracle and/or its affiliates.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
8859_1 ISO-8859-1
18+
iso8859_1 ISO-8859-2
19+
8859_4 ISO-8859-4

api/src/test/resources/META-INF/jakarta.providers

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@
1414
# limitations under the License.
1515
#
1616

17-
protocol=test; type=store; class=jakarta.mail.SessionTest$Jakarta; vendor=Oracle;
17+
protocol=test; type=store; class=jakarta.mail.SessionTest$Jakarta; vendor=Oracle;
18+
protocol=test2; type=store; class=jakarta.mail.SessionTest$Jakarta; vendor=Oracle;
19+
protocol=test4; type=store; class=jakarta.mail.SessionTest$Jakarta; vendor=OracleJakarta;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#
2+
# Copyright (c) 2025 Oracle and/or its affiliates.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
8859_1 ISO-8859-1
18+
iso8859_1 ISO-8859-1
19+
8859_3 ISO-8859-3

api/src/test/resources/META-INF/javamail.providers

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@
1414
# limitations under the License.
1515
#
1616

17-
protocol=test; type=store; class=jakarta.mail.SessionTest$JavaMail; vendor=Oracle;
17+
protocol=test; type=store; class=jakarta.mail.SessionTest$JavaMail; vendor=Oracle;
18+
protocol=test3; type=store; class=jakarta.mail.SessionTest$JavaMail; vendor=Oracle;
19+
protocol=test4; type=store; class=jakarta.mail.SessionTest$Jakarta; vendor=OracleMail;

doc/release/CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ E 744 Remove SecurityManager reference from API
2727
E 758 Improve MimeMessage UTF8 handling
2828
E 804 Restore streamProvider fields for backwards compatibility
2929
E 810 InternetHeaders.InternetHeader toString()
30+
E 812 Custom mail providers distributed under META-INF/javamail.properties are no longer loaded with Jakarta Mail 2.1.5
3031

3132
CHANGES IN THE 2.1.5 RELEASE
3233
----------------------------

0 commit comments

Comments
 (0)