From b357a04fb11cb500565ea823f8aa8cca2804f8e6 Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Mon, 18 Nov 2024 22:15:15 -0800 Subject: [PATCH 1/3] Upgrade to Angus Mail 2.0.3 --- announcements/build.gradle | 2 +- api/build.gradle | 48 ++++++++------ .../notification/NotificationService.java | 5 +- api/src/org/labkey/api/util/MailHelper.java | 63 ++++++++++++------- core/build.gradle | 4 +- issues/build.gradle | 2 +- pipeline/build.gradle | 2 +- query/build.gradle | 2 +- study/build.gradle | 2 +- 9 files changed, 78 insertions(+), 52 deletions(-) diff --git a/announcements/build.gradle b/announcements/build.gradle index 5cd030b168e..8a5778b8fd8 100644 --- a/announcements/build.gradle +++ b/announcements/build.gradle @@ -3,7 +3,7 @@ plugins { } dependencies { - implementation "com.sun.mail:jakarta.mail:${javaMailVersion}" + implementation "org.eclipse.angus:angus-mail:${angusMailVersion}" } // TODO move resources files into resources directory to avoid this overlap diff --git a/api/build.gradle b/api/build.gradle index 33ee415b5bb..250936665ab 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -52,8 +52,6 @@ List runtime = [ configurations { // Exclude the bundled org.json library from com.fasterxml.jackson.datatype:jackson-datatype-json-org dependency all*.exclude group: "org.apache.geronimo.bundles", module: "json" - // Avoid pulling in the Activation API because we don't want to conflict with one loaded from $CATALINA_HOME/lib - all*.exclude group: "jakarta.activation", module: "jakarta.activation-api" // this configuration and its artifact are declared because the default outgoing variant for the api // module (runtimeElements) does not include all the class files since the classes compiled from @@ -98,11 +96,25 @@ dependencies { runtimeOnly runtime BuildUtils.addTomcatBuildDependencies(project, "implementation") - // the following two libraries are required for compilation but we don't want extra ones in the classpath, so we exclude - // them from external dependencies in favor of the versions in the tomcat directory (FIXME seems somewhat sketchy...) + + // needed for compilation but Tomcat provides the implementation api "jakarta.servlet:jakarta.servlet-api:${servletApiVersion}" - api "com.sun.mail:jakarta.mail:${javaMailVersion}" + // Angus Mail is an implementation of the Jakarta Mail API, which it pulls in as a dependency + BuildUtils.addExternalDependency( + project, + new ExternalDependency( + "org.eclipse.angus:angus-mail:${angusMailVersion}", + "Angus Mail", + "Eclipse Foundation", + "https://eclipse-ee4j.github.io/angus-mail/", + "Eclipse Public License 2.0", + "https://projects.eclipse.org/license/epl-2.0", + "Implementation of the Jakarta Mail API", + ) + ) + + // Angus Activation is an implementation of the Jakarta Activation API, which it pulls in as a dependency BuildUtils.addExternalDependency( project, new ExternalDependency( @@ -281,7 +293,7 @@ dependencies { "https://commons.apache.org/proper/commons-text/", ExternalDependency.APACHE_2_LICENSE_NAME, ExternalDependency.APACHE_2_LICENSE_URL, - "String algorithms", + "String algorithms" ) ) @@ -294,21 +306,21 @@ dependencies { "http://jakarta.apache.org/commons/validator/", ExternalDependency.APACHE_2_LICENSE_NAME, ExternalDependency.APACHE_2_LICENSE_URL, - "Data validation and error messages", + "Data validation and error messages" ) ) BuildUtils.addExternalDependency( - project, - new ExternalDependency( - "org.apache.commons:commons-vfs2:${commonsVfs2Version}", - "Commons Virtual File System", - "Apache", - "https://commons.apache.org/proper/commons-vfs/", - ExternalDependency.APACHE_2_LICENSE_NAME, - ExternalDependency.APACHE_2_LICENSE_URL, - "Consistent API for accessing files of different types", - ) + project, + new ExternalDependency( + "org.apache.commons:commons-vfs2:${commonsVfs2Version}", + "Commons Virtual File System", + "Apache", + "https://commons.apache.org/proper/commons-vfs/", + ExternalDependency.APACHE_2_LICENSE_NAME, + ExternalDependency.APACHE_2_LICENSE_URL, + "Consistent API for accessing files of different types" + ) ) @@ -322,7 +334,7 @@ dependencies { "http://code.google.com/p/flying-saucer/", ExternalDependency.LGPL_LICENSE_NAME, ExternalDependency.LGPL_LICENSE_URL, - "XHTML/CSS rendering library", + "XHTML/CSS rendering library" ) ) diff --git a/api/src/org/labkey/api/admin/notification/NotificationService.java b/api/src/org/labkey/api/admin/notification/NotificationService.java index e1e9ffa9615..7ea48f57ff3 100644 --- a/api/src/org/labkey/api/admin/notification/NotificationService.java +++ b/api/src/org/labkey/api/admin/notification/NotificationService.java @@ -15,6 +15,7 @@ */ package org.labkey.api.admin.notification; +import jakarta.mail.MessagingException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.data.Container; @@ -25,15 +26,11 @@ import org.labkey.api.util.MailHelper; import org.labkey.api.view.ActionURL; -import jakarta.mail.MessagingException; -import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.util.List; /** * Service for adding/getting/removing user notifications attached to specific objects. - * User: cnathe - * Date: 9/14/2015 */ public interface NotificationService { diff --git a/api/src/org/labkey/api/util/MailHelper.java b/api/src/org/labkey/api/util/MailHelper.java index 0878194f3c2..3689713b12a 100644 --- a/api/src/org/labkey/api/util/MailHelper.java +++ b/api/src/org/labkey/api/util/MailHelper.java @@ -31,6 +31,7 @@ import jakarta.mail.internet.MimeBodyPart; import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMultipart; +import jakarta.servlet.ServletContext; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; @@ -48,16 +49,16 @@ import org.labkey.api.settings.StartupPropertyEntry; import org.labkey.api.util.emailTemplate.EmailTemplate; -import javax.naming.Context; -import javax.naming.InitialContext; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Properties; import java.util.StringTokenizer; @@ -114,31 +115,47 @@ public void handle(Collection entries) entries.forEach(entry -> properties.put("mail.smtp." + entry.getName(), entry.getValue())); } }); - if (!properties.isEmpty()) - { - session = Session.getInstance(properties); - } - else + + /* now check if specified in tomcat config instead */ + if (properties.isEmpty()) { - /* check if specified in tomcat config */ - InitialContext ctx = new InitialContext(); - Context envCtx = (Context) ctx.lookup("java:comp/env"); - session = (Session) envCtx.lookup("mail/Session"); + ServletContext context = ModuleLoader.getServletContext(); + Enumeration names = Objects.requireNonNull(context).getInitParameterNames(); + while (names.hasMoreElements()) + { + String name = names.nextElement(); + if (name.startsWith("mail.smtp.")) + properties.put(name, context.getInitParameter(name)); + } } - if ("true".equalsIgnoreCase(session.getProperty("mail.smtp.ssl.enable")) || - "true".equalsIgnoreCase(session.getProperty("mail.smtp.starttls.enable"))) + if (!properties.isEmpty()) { - String username = session.getProperty("mail.smtp.user"); - String password = session.getProperty("mail.smtp.password"); - session = Session.getInstance(session.getProperties(), new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() - { - return new PasswordAuthentication(username, password); - } - }); + session = Session.getInstance(properties); + + if ("true".equalsIgnoreCase(session.getProperty("mail.smtp.ssl.enable")) || + "true".equalsIgnoreCase(session.getProperty("mail.smtp.starttls.enable"))) + { + String username = session.getProperty("mail.smtp.user"); + String password = session.getProperty("mail.smtp.password"); + session = Session.getInstance(session.getProperties(), new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() + { + return new PasswordAuthentication(username, password); + } + }); + } } +// I couldn't get this to work once I switched to Angus Mail; kept getting this exception: +// java.util.ServiceConfigurationError: jakarta.mail.util.StreamProvider: org.eclipse.angus.mail.util.MailStreamProvider not a subtype +// else +// { +// /* check if specified in tomcat config */ +// InitialContext ctx = new InitialContext(); +// Context envCtx = (Context) ctx.lookup("java:comp/env"); +// session = (Session) envCtx.lookup("mail/Session"); +// } } catch (Exception e) { @@ -362,7 +379,7 @@ private static void handleBodyParts(MimeMessage mm, BodyPartHandler mu for (int i = 0; i < multipart.getCount(); i++) { BodyPart part = multipart.getBodyPart(i); - multipartHandler.handle(StringUtils.substringBefore(part.getDataHandler().getContentType(), ";"), part); + multipartHandler.handle(StringUtils.substringBefore(part.getContentType(), ";"), part); } } else diff --git a/core/build.gradle b/core/build.gradle index 600982d389d..db798e484ed 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -15,8 +15,8 @@ project.tasks.register("serverSideJS", ServerSideJS) { project.tasks.named('processModuleResources').configure { dependsOn(project.tasks.serverSideJS) } dependencies { - implementation "com.sun.mail:jakarta.mail:${javaMailVersion}" - jspImplementation "com.sun.mail:jakarta.mail:${javaMailVersion}" + implementation "org.eclipse.angus:angus-mail:${angusMailVersion}" + jspImplementation "org.eclipse.angus:angus-mail:${angusMailVersion}" BuildUtils.addExternalDependency( project, diff --git a/issues/build.gradle b/issues/build.gradle index d250cbd25b0..9e22ecd98ba 100644 --- a/issues/build.gradle +++ b/issues/build.gradle @@ -5,7 +5,7 @@ plugins { } dependencies { - implementation "com.sun.mail:jakarta.mail:${javaMailVersion}" + implementation "org.eclipse.angus:angus-mail:${angusMailVersion}" BuildUtils.addLabKeyDependency(project: project, config: "modules", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "experiment"), depProjectConfig: "published", depExtension: "module") BuildUtils.addLabKeyDependency(project: project, config: "modules", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "search"), depProjectConfig: "published", depExtension: "module") } diff --git a/pipeline/build.gradle b/pipeline/build.gradle index afe2086ae1c..d6e5003d4de 100644 --- a/pipeline/build.gradle +++ b/pipeline/build.gradle @@ -6,7 +6,7 @@ plugins { } dependencies { - implementation "com.sun.mail:jakarta.mail:${javaMailVersion}" + implementation "org.eclipse.angus:angus-mail:${angusMailVersion}" BuildUtils.addExternalDependency( project, new ExternalDependency( diff --git a/query/build.gradle b/query/build.gradle index 061e6147337..33289e9b980 100644 --- a/query/build.gradle +++ b/query/build.gradle @@ -12,7 +12,7 @@ configurations { dependencies { antlr "org.antlr:antlr:${antlrVersion}" jspImplementation "org.olap4j:olap4j:${olap4jVersion}" - implementation "com.sun.mail:jakarta.mail:${javaMailVersion}" + implementation "org.eclipse.angus:angus-mail:${angusMailVersion}" // we add this bridge jar because certain Mondrian classes require the log4j interface BuildUtils.addExternalDependency( project, diff --git a/study/build.gradle b/study/build.gradle index 044b93bc593..faad98fc503 100644 --- a/study/build.gradle +++ b/study/build.gradle @@ -14,7 +14,7 @@ sourceSets { } dependencies { - implementation "com.sun.mail:jakarta.mail:${javaMailVersion}" + implementation "org.eclipse.angus:angus-mail:${angusMailVersion}" BuildUtils.addLabKeyDependency(project: project, config: "implementation", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "assay"), depProjectConfig: "apiJarFile") BuildUtils.addLabKeyDependency(project: project, config: "jspImplementation", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "assay"), depProjectConfig: "apiJarFile") From 15399fe44d891ebf161cbf0ddc41530af897f9ab Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Tue, 19 Nov 2024 16:51:56 -0800 Subject: [PATCH 2/3] Likely fix for EHR notification test failures --- api/src/org/labkey/api/util/MailHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/org/labkey/api/util/MailHelper.java b/api/src/org/labkey/api/util/MailHelper.java index 3689713b12a..b51b2384cb9 100644 --- a/api/src/org/labkey/api/util/MailHelper.java +++ b/api/src/org/labkey/api/util/MailHelper.java @@ -379,7 +379,7 @@ private static void handleBodyParts(MimeMessage mm, BodyPartHandler mu for (int i = 0; i < multipart.getCount(); i++) { BodyPart part = multipart.getBodyPart(i); - multipartHandler.handle(StringUtils.substringBefore(part.getContentType(), ";"), part); + multipartHandler.handle(StringUtils.substringBefore(part.getDataHandler().getContentType(), ";"), part); } } else From 4ddc7ed5875eb7adccd932d8ab5ac329a59cebbf Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Tue, 19 Nov 2024 16:57:01 -0800 Subject: [PATCH 3/3] Remove commented out code --- api/src/org/labkey/api/util/MailHelper.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/api/src/org/labkey/api/util/MailHelper.java b/api/src/org/labkey/api/util/MailHelper.java index b51b2384cb9..c0881f92d61 100644 --- a/api/src/org/labkey/api/util/MailHelper.java +++ b/api/src/org/labkey/api/util/MailHelper.java @@ -147,15 +147,6 @@ protected PasswordAuthentication getPasswordAuthentication() }); } } -// I couldn't get this to work once I switched to Angus Mail; kept getting this exception: -// java.util.ServiceConfigurationError: jakarta.mail.util.StreamProvider: org.eclipse.angus.mail.util.MailStreamProvider not a subtype -// else -// { -// /* check if specified in tomcat config */ -// InitialContext ctx = new InitialContext(); -// Context envCtx = (Context) ctx.lookup("java:comp/env"); -// session = (Session) envCtx.lookup("mail/Session"); -// } } catch (Exception e) {