From edae19d86af0068ca54c342a9acd2a9e592dfdea Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Mon, 4 Mar 2024 10:53:13 +0100 Subject: [PATCH 1/8] Multipart performs blocking call in every instantiation #699 Signed-off-by: Jorge Bescos Gascon --- api/src/main/java/jakarta/mail/Message.java | 33 ++++++++++++++++++- api/src/main/java/jakarta/mail/Multipart.java | 32 ++++++++++++++++-- .../jakarta/mail/internet/MimeMessage.java | 19 ----------- .../jakarta/mail/internet/MimeMultipart.java | 6 ++-- 4 files changed, 64 insertions(+), 26 deletions(-) diff --git a/api/src/main/java/jakarta/mail/Message.java b/api/src/main/java/jakarta/mail/Message.java index 05d2713c..aa6ec409 100644 --- a/api/src/main/java/jakarta/mail/Message.java +++ b/api/src/main/java/jakarta/mail/Message.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -17,11 +17,13 @@ package jakarta.mail; import jakarta.mail.search.SearchTerm; +import jakarta.mail.util.StreamProvider; import java.io.InvalidObjectException; import java.io.ObjectStreamException; import java.io.Serializable; import java.util.Date; +import java.util.ServiceConfigurationError; /** * This class models an email message. This is an abstract class. @@ -705,4 +707,33 @@ protected void setExpunged(boolean expunged) { public boolean match(SearchTerm term) throws MessagingException { return term.match(this); } + + /** + * Obtains the {@link StreamProvider} from the session, if exists. + * Otherwise it obtains it from + * {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}. + * + * @return the StreamProvider implementation from the session. + * @throws MessagingException if errors. + * + * @since JavaMail 2.2 + */ + protected StreamProvider provider() throws MessagingException { + try { + try { + final Session s = this.session; + if (s != null) { + return s.getStreamProvider(); + } else { + return Session.getDefaultInstance(System.getProperties(), + null).getStreamProvider(); + } + } catch (ServiceConfigurationError sce) { + throw new IllegalStateException(sce); + } + } catch (RuntimeException re) { + throw new MessagingException("Unable to get " + + StreamProvider.class.getName(), re); + } + } } diff --git a/api/src/main/java/jakarta/mail/Multipart.java b/api/src/main/java/jakarta/mail/Multipart.java index ef634454..fc72a715 100644 --- a/api/src/main/java/jakarta/mail/Multipart.java +++ b/api/src/main/java/jakarta/mail/Multipart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -21,6 +21,8 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Multipart is a container that holds multiple body parts. Multipart @@ -42,6 +44,7 @@ public abstract class Multipart { + private static final Logger LOGGER = Logger.getLogger(Multipart.class.getName()); /** * Vector of BodyPart objects. */ @@ -64,9 +67,9 @@ public abstract class Multipart { /** * Instance of stream provider. * - * @since JavaMail 2.1 + * @since JavaMail 2.2 */ - protected final StreamProvider streamProvider = StreamProvider.provider(); + private volatile StreamProvider streamProvider; /** * Default constructor. An empty Multipart object is created. @@ -266,4 +269,27 @@ public synchronized Part getParent() { public synchronized void setParent(Part parent) { this.parent = parent; } + + protected StreamProvider provider() { + if (streamProvider == null) { + synchronized (this) { + if (streamProvider == null) { + if (parent != null && parent instanceof Message) { + try { + streamProvider = ((Message)parent).provider(); + } catch (MessagingException e) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Cannot reuse streamProvider", e); + } + } + } + } + if (streamProvider == null) { + streamProvider = StreamProvider.provider(); + } + } + } + return streamProvider; + } + } diff --git a/api/src/main/java/jakarta/mail/internet/MimeMessage.java b/api/src/main/java/jakarta/mail/internet/MimeMessage.java index e832b097..73b7c4c7 100644 --- a/api/src/main/java/jakarta/mail/internet/MimeMessage.java +++ b/api/src/main/java/jakarta/mail/internet/MimeMessage.java @@ -2322,23 +2322,4 @@ protected MimeMessage createMimeMessage(Session session) throws MessagingException { return new MimeMessage(session); } - - private StreamProvider provider() throws MessagingException { - try { - try { - final Session s = this.session; - if (s != null) { - return s.getStreamProvider(); - } else { - return Session.getDefaultInstance(System.getProperties(), - null).getStreamProvider(); - } - } catch (ServiceConfigurationError sce) { - throw new IllegalStateException(sce); - } - } catch (RuntimeException re) { - throw new MessagingException("Unable to get " - + StreamProvider.class.getName(), re); - } - } } diff --git a/api/src/main/java/jakarta/mail/internet/MimeMultipart.java b/api/src/main/java/jakarta/mail/internet/MimeMultipart.java index 88a149a1..4a555e6e 100644 --- a/api/src/main/java/jakarta/mail/internet/MimeMultipart.java +++ b/api/src/main/java/jakarta/mail/internet/MimeMultipart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -520,7 +520,7 @@ public synchronized void writeTo(OutputStream os) String boundary = "--" + (new ContentType(contentType)).getParameter("boundary"); - LineOutputStream los = streamProvider.outputLineStream(os, false); + LineOutputStream los = provider().outputLineStream(os, false); // if there's a preamble, write it out if (preamble != null) { byte[] pb = MimeUtility.getBytes(preamble); @@ -601,7 +601,7 @@ protected synchronized void parse() throws MessagingException { try { // Skip and save the preamble - LineInputStream lin = streamProvider.inputLineStream(in, false); + LineInputStream lin = provider().inputLineStream(in, false); StringBuilder preamblesb = null; String line; while ((line = lin.readLine()) != null) { From cfaadd3d8074b1a4f147123862d5fe5d412af38c Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Wed, 6 Mar 2024 09:11:37 +0100 Subject: [PATCH 2/8] Redesign of StreamProvider in Part Signed-off-by: Jorge Bescos Gascon --- api/src/main/java/jakarta/mail/BodyPart.java | 19 ++- api/src/main/java/jakarta/mail/Message.java | 19 +-- api/src/main/java/jakarta/mail/Multipart.java | 45 ++--- api/src/main/java/jakarta/mail/Part.java | 16 +- .../jakarta/mail/internet/MimeBodyPart.java | 5 +- .../jakarta/mail/internet/MimeMessage.java | 9 +- .../jakarta/mail/internet/MimeMultipart.java | 4 +- .../mail/internet/PreencodedMimeBodyPart.java | 4 +- api/src/test/java/jakarta/mail/PartTest.java | 154 ++++++++++++++++++ 9 files changed, 209 insertions(+), 66 deletions(-) create mode 100644 api/src/test/java/jakarta/mail/PartTest.java diff --git a/api/src/main/java/jakarta/mail/BodyPart.java b/api/src/main/java/jakarta/mail/BodyPart.java index 975a393e..876a2214 100644 --- a/api/src/main/java/jakarta/mail/BodyPart.java +++ b/api/src/main/java/jakarta/mail/BodyPart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -39,13 +39,6 @@ public abstract class BodyPart implements Part { */ protected Multipart parent; - /** - * Instance of stream provider. - * - * @since JavaMail 2.1 - */ - protected final StreamProvider streamProvider = StreamProvider.provider(); - /** * Creates a default {@code BodyPart}. */ @@ -74,4 +67,14 @@ public Multipart getParent() { void setParent(Multipart parent) { this.parent = parent; } + + @Override + public StreamProvider getStreamProvider() throws MessagingException { + if (parent != null) { + return parent.getStreamProvider(); + } else { + return Part.super.getStreamProvider(); + } + } + } diff --git a/api/src/main/java/jakarta/mail/Message.java b/api/src/main/java/jakarta/mail/Message.java index aa6ec409..f6dd263c 100644 --- a/api/src/main/java/jakarta/mail/Message.java +++ b/api/src/main/java/jakarta/mail/Message.java @@ -708,32 +708,21 @@ public boolean match(SearchTerm term) throws MessagingException { return term.match(this); } - /** - * Obtains the {@link StreamProvider} from the session, if exists. - * Otherwise it obtains it from - * {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}. - * - * @return the StreamProvider implementation from the session. - * @throws MessagingException if errors. - * - * @since JavaMail 2.2 - */ - protected StreamProvider provider() throws MessagingException { + @Override + public StreamProvider getStreamProvider() throws MessagingException { try { try { final Session s = this.session; if (s != null) { return s.getStreamProvider(); } else { - return Session.getDefaultInstance(System.getProperties(), - null).getStreamProvider(); + return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); } } catch (ServiceConfigurationError sce) { throw new IllegalStateException(sce); } } catch (RuntimeException re) { - throw new MessagingException("Unable to get " - + StreamProvider.class.getName(), re); + throw new MessagingException("Unable to get " + StreamProvider.class.getName(), re); } } } diff --git a/api/src/main/java/jakarta/mail/Multipart.java b/api/src/main/java/jakarta/mail/Multipart.java index fc72a715..f119cbe3 100644 --- a/api/src/main/java/jakarta/mail/Multipart.java +++ b/api/src/main/java/jakarta/mail/Multipart.java @@ -21,8 +21,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Vector; -import java.util.logging.Level; -import java.util.logging.Logger; /** * Multipart is a container that holds multiple body parts. Multipart @@ -44,7 +42,6 @@ public abstract class Multipart { - private static final Logger LOGGER = Logger.getLogger(Multipart.class.getName()); /** * Vector of BodyPart objects. */ @@ -64,13 +61,6 @@ public abstract class Multipart { */ protected Part parent; - /** - * Instance of stream provider. - * - * @since JavaMail 2.2 - */ - private volatile StreamProvider streamProvider; - /** * Default constructor. An empty Multipart object is created. */ @@ -270,26 +260,23 @@ public synchronized void setParent(Part parent) { this.parent = parent; } - protected StreamProvider provider() { - if (streamProvider == null) { - synchronized (this) { - if (streamProvider == null) { - if (parent != null && parent instanceof Message) { - try { - streamProvider = ((Message)parent).provider(); - } catch (MessagingException e) { - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.log(Level.FINE, "Cannot reuse streamProvider", e); - } - } - } - } - if (streamProvider == null) { - streamProvider = StreamProvider.provider(); - } - } + /** + * Obtains the {@link StreamProvider} from the parent, if possible. + * Otherwise it obtains it from + * {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}. + * + * @return the StreamProvider implementation from the session. + * @throws MessagingException if errors. + * + * @since JavaMail 2.2 + */ + protected StreamProvider getStreamProvider() throws MessagingException { + Part parent = this.parent; + if (parent != null) { + return parent.getStreamProvider(); + } else { + return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); } - return streamProvider; } } diff --git a/api/src/main/java/jakarta/mail/Part.java b/api/src/main/java/jakarta/mail/Part.java index 9743ed1b..d99562c7 100644 --- a/api/src/main/java/jakarta/mail/Part.java +++ b/api/src/main/java/jakarta/mail/Part.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -17,6 +17,7 @@ package jakarta.mail; import jakarta.activation.DataHandler; +import jakarta.mail.util.StreamProvider; import java.io.IOException; import java.io.InputStream; @@ -453,4 +454,17 @@ Enumeration
getMatchingHeaders(String[] header_names) */ Enumeration
getNonMatchingHeaders(String[] header_names) throws MessagingException; + + /** + * Obtains the {@link StreamProvider}. + * It defaults to {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}. + * + * @return the StreamProvider. + * @throws MessagingException if errors. + * + * @since JavaMail 2.2 + */ + default StreamProvider getStreamProvider() throws MessagingException { + return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); + } } diff --git a/api/src/main/java/jakarta/mail/internet/MimeBodyPart.java b/api/src/main/java/jakarta/mail/internet/MimeBodyPart.java index 7c6c3a67..b0fa7a50 100644 --- a/api/src/main/java/jakarta/mail/internet/MimeBodyPart.java +++ b/api/src/main/java/jakarta/mail/internet/MimeBodyPart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -30,7 +30,6 @@ import jakarta.mail.Multipart; import jakarta.mail.Part; import jakarta.mail.util.LineOutputStream; -import jakarta.mail.util.StreamProvider; import jakarta.mail.util.StreamProvider.EncoderTypes; import java.io.BufferedInputStream; @@ -1641,7 +1640,7 @@ static void writeTo(MimePart part, OutputStream os, String[] ignoreList) } else { Map params = new HashMap<>(); params.put("allowutf8", allowutf8); - los = StreamProvider.provider().outputLineStream(os, allowutf8); + los = part.getStreamProvider().outputLineStream(os, allowutf8); } // First, write out the header diff --git a/api/src/main/java/jakarta/mail/internet/MimeMessage.java b/api/src/main/java/jakarta/mail/internet/MimeMessage.java index 73b7c4c7..b9ab9f50 100644 --- a/api/src/main/java/jakarta/mail/internet/MimeMessage.java +++ b/api/src/main/java/jakarta/mail/internet/MimeMessage.java @@ -29,7 +29,6 @@ import jakarta.mail.Multipart; import jakarta.mail.Session; import jakarta.mail.util.LineOutputStream; -import jakarta.mail.util.StreamProvider; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -45,8 +44,6 @@ import java.util.Enumeration; import java.util.List; import java.util.Properties; -import java.util.ServiceConfigurationError; - /** * This class represents a MIME style email message. It implements @@ -245,7 +242,7 @@ public MimeMessage(MimeMessage source) throws MessagingException { strict = source.strict; source.writeTo(bos); bos.close(); - try (InputStream bis = provider().inputSharedByteArray(bos.toByteArray())) { + try (InputStream bis = getStreamProvider().inputSharedByteArray(bos.toByteArray())) { parse(bis); } saved = true; @@ -1410,7 +1407,7 @@ protected InputStream getContentStream() throws MessagingException { if (contentStream != null) return ((SharedInputStream) contentStream).newStream(0, -1); if (content != null) { - return provider().inputSharedByteArray(content); + return getStreamProvider().inputSharedByteArray(content); } throw new MessagingException("No MimeMessage content"); } @@ -1917,7 +1914,7 @@ public void writeTo(OutputStream os, String[] ignoreList) // Else, the content is untouched, so we can just output it // First, write out the header Enumeration hdrLines = getNonMatchingHeaderLines(ignoreList); - LineOutputStream los = provider().outputLineStream(os, allowutf8); + LineOutputStream los = getStreamProvider().outputLineStream(os, allowutf8); while (hdrLines.hasMoreElements()) los.writeln(hdrLines.nextElement()); diff --git a/api/src/main/java/jakarta/mail/internet/MimeMultipart.java b/api/src/main/java/jakarta/mail/internet/MimeMultipart.java index 4a555e6e..dee43113 100644 --- a/api/src/main/java/jakarta/mail/internet/MimeMultipart.java +++ b/api/src/main/java/jakarta/mail/internet/MimeMultipart.java @@ -520,7 +520,7 @@ public synchronized void writeTo(OutputStream os) String boundary = "--" + (new ContentType(contentType)).getParameter("boundary"); - LineOutputStream los = provider().outputLineStream(os, false); + LineOutputStream los = getStreamProvider().outputLineStream(os, false); // if there's a preamble, write it out if (preamble != null) { byte[] pb = MimeUtility.getBytes(preamble); @@ -601,7 +601,7 @@ protected synchronized void parse() throws MessagingException { try { // Skip and save the preamble - LineInputStream lin = provider().inputLineStream(in, false); + LineInputStream lin = getStreamProvider().inputLineStream(in, false); StringBuilder preamblesb = null; String line; while ((line = lin.readLine()) != null) { diff --git a/api/src/main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java b/api/src/main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java index 48f663f8..19cdce4c 100644 --- a/api/src/main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java +++ b/api/src/main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -78,7 +78,7 @@ public void writeTo(OutputStream os) if (os instanceof LineOutputStream) { los = (LineOutputStream) os; } else { - los = streamProvider.outputLineStream(os, false); + los = getStreamProvider().outputLineStream(os, false); } // First, write out the header diff --git a/api/src/test/java/jakarta/mail/PartTest.java b/api/src/test/java/jakarta/mail/PartTest.java new file mode 100644 index 00000000..1613e23b --- /dev/null +++ b/api/src/test/java/jakarta/mail/PartTest.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package jakarta.mail; + +import static org.junit.Assert.assertEquals; + +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; +import jakarta.mail.util.DummyStreamProvider; +import jakarta.mail.util.LineInputStream; +import jakarta.mail.util.LineOutputStream; +import jakarta.mail.util.StreamProvider; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Properties; + +import org.junit.Test; + +public class PartTest { + + // Sessions with different StreamProviders + private static final Session SESSION_DEFAULT = Session.getDefaultInstance(new Properties()); + private static final Session SESSION_1; + private static final Session SESSION_2; + + static { + SESSION_1 = Session.getDefaultInstance(new Properties()); + System.setProperty(StreamProvider.class.getName(), CustomStreamProvider.class.getName()); + SESSION_2 = Session.getInstance(new Properties()); + System.clearProperty(StreamProvider.class.getName()); + } + + @Test + public void streamProvidersChecker() { + assertEquals(DummyStreamProvider.class, SESSION_DEFAULT.getStreamProvider().getClass()); + assertEquals(DummyStreamProvider.class, SESSION_1.getStreamProvider().getClass()); + assertEquals(CustomStreamProvider.class, SESSION_2.getStreamProvider().getClass()); + assertEquals(SESSION_DEFAULT.getStreamProvider(), SESSION_1.getStreamProvider()); + } + + @Test + public void sameInstance() throws MessagingException { + MimeBodyPart body = new MimeBodyPart(); + MimeMultipart multiPart = new MimeMultipart(); + assertEquals(SESSION_DEFAULT.getStreamProvider(), body.getStreamProvider()); + assertEquals(SESSION_DEFAULT.getStreamProvider(), multiPart.getStreamProvider()); + } + + @Test + public void specifySession1() throws MessagingException { + Message message = new MimeMessage(SESSION_1); + Multipart multipart = new MimeMultipart(); + message.setContent(multipart); + assertEquals(SESSION_1.getStreamProvider(), multipart.getStreamProvider()); + } + + @Test + public void specifySession2() throws MessagingException { + Message message = new MimeMessage(SESSION_2); + Multipart multipart = new MimeMultipart(); + message.setContent(multipart); + assertEquals(SESSION_2.getStreamProvider(), multipart.getStreamProvider()); + } + + public static class CustomStreamProvider implements StreamProvider { + + @Override + public InputStream inputBase64(InputStream in) { + return null; + } + + @Override + public OutputStream outputBase64(OutputStream out) { + return null; + } + + @Override + public InputStream inputBinary(InputStream in) { + return null; + } + + @Override + public OutputStream outputBinary(OutputStream out) { + return null; + } + + @Override + public OutputStream outputB(OutputStream out) { + return null; + } + + @Override + public InputStream inputQ(InputStream in) { + return null; + } + + @Override + public OutputStream outputQ(OutputStream out, boolean encodingWord) { + return null; + } + + @Override + public LineInputStream inputLineStream(InputStream in, boolean allowutf8) { + return null; + } + + @Override + public LineOutputStream outputLineStream(OutputStream out, boolean allowutf8) { + return null; + } + + @Override + public InputStream inputQP(InputStream in) { + // TODO Auto-generated method stub + return null; + } + + @Override + public OutputStream outputQP(OutputStream out) { + return null; + } + + @Override + public InputStream inputSharedByteArray(byte[] buff) { + return null; + } + + @Override + public InputStream inputUU(InputStream in) { + return null; + } + + @Override + public OutputStream outputUU(OutputStream out, String filename) { + return null; + } + } +} From 13d931446e8ef50a23007899c5624b6266663f7e Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Thu, 7 Mar 2024 09:05:45 +0100 Subject: [PATCH 3/8] CHANGES.txt Signed-off-by: Jorge Bescos Gascon --- doc/release/CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release/CHANGES.txt b/doc/release/CHANGES.txt index efaf7d43..089a457c 100644 --- a/doc/release/CHANGES.txt +++ b/doc/release/CHANGES.txt @@ -19,6 +19,10 @@ Bug IDs that start with "G" can be found in the GlassFish Issue Tracker Seven digit bug numbers are from the old Sun bug database, which is no longer available. + CHANGES IN THE 2.2.0 RELEASE + ---------------------------- +E 699 Multipart performs blocking call in every instantiation + CHANGES IN THE 2.1.3 RELEASE ---------------------------- E 631 Session.getService does not use proper classloader in OSGI environment From 2bf41f6e9ec6e19ac1938ab4b99ecb5b2db299b6 Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Thu, 7 Mar 2024 09:10:42 +0100 Subject: [PATCH 4/8] Comment reviews Signed-off-by: Jorge Bescos Gascon --- api/src/main/java/jakarta/mail/Multipart.java | 11 ++++++++++- api/src/main/java/jakarta/mail/Part.java | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/jakarta/mail/Multipart.java b/api/src/main/java/jakarta/mail/Multipart.java index f119cbe3..73083e44 100644 --- a/api/src/main/java/jakarta/mail/Multipart.java +++ b/api/src/main/java/jakarta/mail/Multipart.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.OutputStream; +import java.util.ServiceConfigurationError; import java.util.Vector; /** @@ -275,7 +276,15 @@ protected StreamProvider getStreamProvider() throws MessagingException { if (parent != null) { return parent.getStreamProvider(); } else { - return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); + try { + try { + return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); + } catch (ServiceConfigurationError sce) { + throw new IllegalStateException(sce); + } + } catch (RuntimeException re) { + throw new MessagingException("Unable to get " + StreamProvider.class.getName(), re); + } } } diff --git a/api/src/main/java/jakarta/mail/Part.java b/api/src/main/java/jakarta/mail/Part.java index d99562c7..4a18e28c 100644 --- a/api/src/main/java/jakarta/mail/Part.java +++ b/api/src/main/java/jakarta/mail/Part.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; +import java.util.ServiceConfigurationError; /** * The Part interface is the common base interface for @@ -465,6 +466,14 @@ Enumeration
getNonMatchingHeaders(String[] header_names) * @since JavaMail 2.2 */ default StreamProvider getStreamProvider() throws MessagingException { - return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); + try { + try { + return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); + } catch (ServiceConfigurationError sce) { + throw new IllegalStateException(sce); + } + } catch (RuntimeException re) { + throw new MessagingException("Unable to get " + StreamProvider.class.getName(), re); + } } } From d389798a2b1fde3dfc799c8bb068c862de6f8fbc Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Thu, 7 Mar 2024 16:58:27 +0100 Subject: [PATCH 5/8] NoSuchProviderException Signed-off-by: Jorge Bescos Gascon --- api/src/main/java/jakarta/mail/BodyPart.java | 2 +- api/src/main/java/jakarta/mail/Message.java | 4 ++-- api/src/main/java/jakarta/mail/Multipart.java | 6 +++--- api/src/main/java/jakarta/mail/Part.java | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/jakarta/mail/BodyPart.java b/api/src/main/java/jakarta/mail/BodyPart.java index 876a2214..77ec3c2f 100644 --- a/api/src/main/java/jakarta/mail/BodyPart.java +++ b/api/src/main/java/jakarta/mail/BodyPart.java @@ -69,7 +69,7 @@ void setParent(Multipart parent) { } @Override - public StreamProvider getStreamProvider() throws MessagingException { + public StreamProvider getStreamProvider() throws NoSuchProviderException { if (parent != null) { return parent.getStreamProvider(); } else { diff --git a/api/src/main/java/jakarta/mail/Message.java b/api/src/main/java/jakarta/mail/Message.java index f6dd263c..e1f915d6 100644 --- a/api/src/main/java/jakarta/mail/Message.java +++ b/api/src/main/java/jakarta/mail/Message.java @@ -709,7 +709,7 @@ public boolean match(SearchTerm term) throws MessagingException { } @Override - public StreamProvider getStreamProvider() throws MessagingException { + public StreamProvider getStreamProvider() throws NoSuchProviderException { try { try { final Session s = this.session; @@ -722,7 +722,7 @@ public StreamProvider getStreamProvider() throws MessagingException { throw new IllegalStateException(sce); } } catch (RuntimeException re) { - throw new MessagingException("Unable to get " + StreamProvider.class.getName(), re); + throw new NoSuchProviderException("Unable to get " + StreamProvider.class.getName(), re); } } } diff --git a/api/src/main/java/jakarta/mail/Multipart.java b/api/src/main/java/jakarta/mail/Multipart.java index 73083e44..18750a24 100644 --- a/api/src/main/java/jakarta/mail/Multipart.java +++ b/api/src/main/java/jakarta/mail/Multipart.java @@ -267,11 +267,11 @@ public synchronized void setParent(Part parent) { * {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}. * * @return the StreamProvider implementation from the session. - * @throws MessagingException if errors. + * @throws NoSuchProviderException if errors. * * @since JavaMail 2.2 */ - protected StreamProvider getStreamProvider() throws MessagingException { + protected StreamProvider getStreamProvider() throws NoSuchProviderException { Part parent = this.parent; if (parent != null) { return parent.getStreamProvider(); @@ -283,7 +283,7 @@ protected StreamProvider getStreamProvider() throws MessagingException { throw new IllegalStateException(sce); } } catch (RuntimeException re) { - throw new MessagingException("Unable to get " + StreamProvider.class.getName(), re); + throw new NoSuchProviderException("Unable to get " + StreamProvider.class.getName(), re); } } } diff --git a/api/src/main/java/jakarta/mail/Part.java b/api/src/main/java/jakarta/mail/Part.java index 4a18e28c..612e28ec 100644 --- a/api/src/main/java/jakarta/mail/Part.java +++ b/api/src/main/java/jakarta/mail/Part.java @@ -461,11 +461,11 @@ Enumeration
getNonMatchingHeaders(String[] header_names) * It defaults to {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}. * * @return the StreamProvider. - * @throws MessagingException if errors. + * @throws NoSuchProviderException if errors. * * @since JavaMail 2.2 */ - default StreamProvider getStreamProvider() throws MessagingException { + default StreamProvider getStreamProvider() throws NoSuchProviderException { try { try { return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); @@ -473,7 +473,7 @@ default StreamProvider getStreamProvider() throws MessagingException { throw new IllegalStateException(sce); } } catch (RuntimeException re) { - throw new MessagingException("Unable to get " + StreamProvider.class.getName(), re); + throw new NoSuchProviderException("Unable to get " + StreamProvider.class.getName(), re); } } } From 7849e77b295d7967c38c6f55c9deed1649418e62 Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Fri, 8 Mar 2024 06:27:01 +0100 Subject: [PATCH 6/8] Update MessagingException Signed-off-by: Jorge Bescos Gascon --- api/src/main/java/jakarta/mail/BodyPart.java | 2 +- api/src/main/java/jakarta/mail/Message.java | 2 +- api/src/main/java/jakarta/mail/Multipart.java | 4 ++-- api/src/main/java/jakarta/mail/Part.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/jakarta/mail/BodyPart.java b/api/src/main/java/jakarta/mail/BodyPart.java index 77ec3c2f..876a2214 100644 --- a/api/src/main/java/jakarta/mail/BodyPart.java +++ b/api/src/main/java/jakarta/mail/BodyPart.java @@ -69,7 +69,7 @@ void setParent(Multipart parent) { } @Override - public StreamProvider getStreamProvider() throws NoSuchProviderException { + public StreamProvider getStreamProvider() throws MessagingException { if (parent != null) { return parent.getStreamProvider(); } else { diff --git a/api/src/main/java/jakarta/mail/Message.java b/api/src/main/java/jakarta/mail/Message.java index e1f915d6..b12586e7 100644 --- a/api/src/main/java/jakarta/mail/Message.java +++ b/api/src/main/java/jakarta/mail/Message.java @@ -709,7 +709,7 @@ public boolean match(SearchTerm term) throws MessagingException { } @Override - public StreamProvider getStreamProvider() throws NoSuchProviderException { + public StreamProvider getStreamProvider() throws MessagingException { try { try { final Session s = this.session; diff --git a/api/src/main/java/jakarta/mail/Multipart.java b/api/src/main/java/jakarta/mail/Multipart.java index 18750a24..5702c64a 100644 --- a/api/src/main/java/jakarta/mail/Multipart.java +++ b/api/src/main/java/jakarta/mail/Multipart.java @@ -267,11 +267,11 @@ public synchronized void setParent(Part parent) { * {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}. * * @return the StreamProvider implementation from the session. - * @throws NoSuchProviderException if errors. + * @throws MessagingException if errors. * * @since JavaMail 2.2 */ - protected StreamProvider getStreamProvider() throws NoSuchProviderException { + protected StreamProvider getStreamProvider() throws MessagingException { Part parent = this.parent; if (parent != null) { return parent.getStreamProvider(); diff --git a/api/src/main/java/jakarta/mail/Part.java b/api/src/main/java/jakarta/mail/Part.java index 612e28ec..68cb4680 100644 --- a/api/src/main/java/jakarta/mail/Part.java +++ b/api/src/main/java/jakarta/mail/Part.java @@ -461,11 +461,11 @@ Enumeration
getNonMatchingHeaders(String[] header_names) * It defaults to {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}. * * @return the StreamProvider. - * @throws NoSuchProviderException if errors. + * @throws MessagingException if errors. * * @since JavaMail 2.2 */ - default StreamProvider getStreamProvider() throws NoSuchProviderException { + default StreamProvider getStreamProvider() throws MessagingException { try { try { return Session.getDefaultInstance(System.getProperties(), null).getStreamProvider(); From 956ce9b79fee06fae74313dbec37e33a1bf2d354 Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Fri, 8 Mar 2024 06:37:01 +0100 Subject: [PATCH 7/8] Add test Signed-off-by: Jorge Bescos Gascon --- api/src/test/java/jakarta/mail/PartTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/api/src/test/java/jakarta/mail/PartTest.java b/api/src/test/java/jakarta/mail/PartTest.java index 1613e23b..cce883ae 100644 --- a/api/src/test/java/jakarta/mail/PartTest.java +++ b/api/src/test/java/jakarta/mail/PartTest.java @@ -78,6 +78,22 @@ public void specifySession2() throws MessagingException { assertEquals(SESSION_2.getStreamProvider(), multipart.getStreamProvider()); } + @Test + public void multipartBodyPart() throws Exception { + MimeMessage m = new MimeMessage(SESSION_2); + MimeMultipart mmp = new MimeMultipart("mixed"); + MimeBodyPart mbp = new MimeBodyPart(); + mbp.setDisposition(Part.INLINE); + mbp.setText("none"); + mmp.addBodyPart(mbp); + m.setContent(mmp); + + StreamProvider root = SESSION_2.getStreamProvider(); + assertEquals(root, m.getStreamProvider()); + assertEquals(root, mmp.getStreamProvider()); + assertEquals(root, mbp.getStreamProvider()); + } + public static class CustomStreamProvider implements StreamProvider { @Override From f2095fc782f76218233dff645ffb39790df082a0 Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Mon, 10 Feb 2025 09:13:00 +0100 Subject: [PATCH 8/8] Copyrights 2025 Signed-off-by: Jorge Bescos Gascon --- api/src/main/java/jakarta/mail/BodyPart.java | 2 +- api/src/main/java/jakarta/mail/Message.java | 2 +- api/src/main/java/jakarta/mail/Multipart.java | 2 +- api/src/main/java/jakarta/mail/Part.java | 2 +- api/src/main/java/jakarta/mail/internet/MimeBodyPart.java | 2 +- api/src/main/java/jakarta/mail/internet/MimeMessage.java | 2 +- api/src/main/java/jakarta/mail/internet/MimeMultipart.java | 2 +- .../main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java | 2 +- api/src/test/java/jakarta/mail/PartTest.java | 2 +- doc/release/CHANGES.txt | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/jakarta/mail/BodyPart.java b/api/src/main/java/jakarta/mail/BodyPart.java index 876a2214..83be89b0 100644 --- a/api/src/main/java/jakarta/mail/BodyPart.java +++ b/api/src/main/java/jakarta/mail/BodyPart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/api/src/main/java/jakarta/mail/Message.java b/api/src/main/java/jakarta/mail/Message.java index b12586e7..e1f0a9e0 100644 --- a/api/src/main/java/jakarta/mail/Message.java +++ b/api/src/main/java/jakarta/mail/Message.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/api/src/main/java/jakarta/mail/Multipart.java b/api/src/main/java/jakarta/mail/Multipart.java index 5702c64a..e20ffa93 100644 --- a/api/src/main/java/jakarta/mail/Multipart.java +++ b/api/src/main/java/jakarta/mail/Multipart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/api/src/main/java/jakarta/mail/Part.java b/api/src/main/java/jakarta/mail/Part.java index 68cb4680..9a2042d3 100644 --- a/api/src/main/java/jakarta/mail/Part.java +++ b/api/src/main/java/jakarta/mail/Part.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/api/src/main/java/jakarta/mail/internet/MimeBodyPart.java b/api/src/main/java/jakarta/mail/internet/MimeBodyPart.java index b0fa7a50..ca0567cd 100644 --- a/api/src/main/java/jakarta/mail/internet/MimeBodyPart.java +++ b/api/src/main/java/jakarta/mail/internet/MimeBodyPart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/api/src/main/java/jakarta/mail/internet/MimeMessage.java b/api/src/main/java/jakarta/mail/internet/MimeMessage.java index b9ab9f50..220db2a2 100644 --- a/api/src/main/java/jakarta/mail/internet/MimeMessage.java +++ b/api/src/main/java/jakarta/mail/internet/MimeMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/api/src/main/java/jakarta/mail/internet/MimeMultipart.java b/api/src/main/java/jakarta/mail/internet/MimeMultipart.java index dee43113..b5326f3d 100644 --- a/api/src/main/java/jakarta/mail/internet/MimeMultipart.java +++ b/api/src/main/java/jakarta/mail/internet/MimeMultipart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/api/src/main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java b/api/src/main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java index 19cdce4c..25f028b3 100644 --- a/api/src/main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java +++ b/api/src/main/java/jakarta/mail/internet/PreencodedMimeBodyPart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/api/src/test/java/jakarta/mail/PartTest.java b/api/src/test/java/jakarta/mail/PartTest.java index cce883ae..6b0f6708 100644 --- a/api/src/test/java/jakarta/mail/PartTest.java +++ b/api/src/test/java/jakarta/mail/PartTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/doc/release/CHANGES.txt b/doc/release/CHANGES.txt index 089a457c..c4ae504f 100644 --- a/doc/release/CHANGES.txt +++ b/doc/release/CHANGES.txt @@ -19,7 +19,7 @@ Bug IDs that start with "G" can be found in the GlassFish Issue Tracker Seven digit bug numbers are from the old Sun bug database, which is no longer available. - CHANGES IN THE 2.2.0 RELEASE + CHANGES IN THE 2.1.4 RELEASE ---------------------------- E 699 Multipart performs blocking call in every instantiation