You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2020/10/02 20:11:26 UTC

[tomcat] branch 7.0.x updated: Better error messages when running under JPMS

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/7.0.x by this push:
     new ba18fcd  Better error messages when running under JPMS
ba18fcd is described below

commit ba18fcdc0a1189d7c5f0bc0b1e8d14ddc1d651d6
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Oct 2 21:07:05 2020 +0100

    Better error messages when running under JPMS
---
 .../apache/catalina/loader/LocalStrings.properties   |  5 +++--
 .../catalina/loader/WebappClassLoaderBase.java       | 18 ++++++++++++++++--
 java/org/apache/tomcat/util/compat/Jre9Compat.java   | 20 ++++++++++++++++++++
 java/org/apache/tomcat/util/compat/JreCompat.java    | 13 +++++++++++++
 webapps/docs/changelog.xml                           |  5 +++++
 5 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/java/org/apache/catalina/loader/LocalStrings.properties b/java/org/apache/catalina/loader/LocalStrings.properties
index 9639ec9..3f90c82 100644
--- a/java/org/apache/catalina/loader/LocalStrings.properties
+++ b/java/org/apache/catalina/loader/LocalStrings.properties
@@ -37,8 +37,9 @@ virtualWebappLoader.token.notDirectory=Path is skipped, because it does not exis
 virtualWebappLoader.token.notExists=Path is skipped, because it does not exist: [{0}]
 virtualWebappLoader.token.notFile=Path is skipped, because it does not exist or is not a file: [{0}]
 
-webappClassLoader.addExportsRmi=When running on Java 9 you need to add "--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED" to the JVM command line arguments to enable RMI Target memory leak detection. Alternatively, you can suppress this warning by disabling RMI Target memory leak detection.
-webappClassLoader.addExportsThreadLocal=When running on Java 9 you need to add "--add-opens=java.base/java.lang=ALL-UNNAMED" to the JVM command line arguments to enable ThreadLocal memory leak detection. Alternatively, you can suppress this warning by disabling ThreadLocal memory leak detection.
+webappClassLoader.addExportsJavaIo=When running on Java 9 or later you need to add "--add-opens=java.base/java.io={0}" to the JVM command line arguments to enable ObjectStream cache memory leak protection. Alternatively, you can suppress this warning by disabling ObjectStream class cache memory leak protection.
+webappClassLoader.addExportsRmi=When running on Java 9 or later you need to add "--add-opens=java.rmi/sun.rmi.transport={0}" to the JVM command line arguments to enable RMI Target memory leak detection. Alternatively, you can suppress this warning by disabling RMI Target memory leak detection.
+webappClassLoader.addExportsThreadLocal=When running on Java 9 or later you need to add "--add-opens=java.base/java.lang={0}" to the JVM command line arguments to enable ThreadLocal memory leak detection. Alternatively, you can suppress this warning by disabling ThreadLocal memory leak detection.
 webappClassLoader.addTransformer=Added class file transformer [{0}] to web application [{1}].
 webappClassLoader.addTransformer.duplicate=Duplicate call to add class file transformer [{0}] to web application [{1}] ignored.
 webappClassLoader.addTransformer.illegalArgument=The web application [{0}] attempted to add a null class file transformer.
diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
index fc36d74..c8d0683 100644
--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
@@ -2795,7 +2795,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
             if (jreCompat.isInstanceOfInaccessibleObjectException(t)) {
                 // Must be running on Java 9 without the necessary command line
                 // options.
-                log.warn(sm.getString("webappClassLoader.addExportsThreadLocal"));
+                String currentModule = JreCompat.getInstance().getModuleName(this.getClass());
+                log.warn(sm.getString("webappClassLoader.addExportsThreadLocal", currentModule));
             } else {
                 ExceptionUtils.handleThrowable(t);
                 log.warn(sm.getString(
@@ -3057,7 +3058,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
             if (jreCompat.isInstanceOfInaccessibleObjectException(e)) {
                 // Must be running on Java 9 without the necessary command line
                 // options.
-                log.warn(sm.getString("webappClassLoader.addExportsRmi"));
+                String currentModule = JreCompat.getInstance().getModuleName(this.getClass());
+                log.warn(sm.getString("webappClassLoader.addExportsRmi", currentModule));
             } else {
                 // Re-throw all other exceptions
                 // Have to wrap this below Java 7
@@ -3090,6 +3092,18 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
         } catch (ClassNotFoundException e) {
             log.warn(sm.getString(
                     "webappClassLoader.clearObjectStreamClassCachesFail", getContextName()), e);
+        } catch (RuntimeException e) {
+            JreCompat jreCompat = JreCompat.getInstance();
+            if (jreCompat.isInstanceOfInaccessibleObjectException(e)) {
+                // Must be running on Java 9 without the necessary command line
+                // options.
+                String currentModule = JreCompat.getInstance().getModuleName(this.getClass());
+                log.warn(sm.getString("webappClassLoader.addExportsJavaIo", currentModule));
+                return;
+            } else {
+                // Re-throw all other exceptions
+                throw e;
+            }
         }
     }
 
diff --git a/java/org/apache/tomcat/util/compat/Jre9Compat.java b/java/org/apache/tomcat/util/compat/Jre9Compat.java
index 66650c8..8663355 100644
--- a/java/org/apache/tomcat/util/compat/Jre9Compat.java
+++ b/java/org/apache/tomcat/util/compat/Jre9Compat.java
@@ -56,6 +56,7 @@ class Jre9Compat extends Jre8Compat {
     private static final Method canAccessMethod;
     private static final Method getModuleMethod;
     private static final Method isExportedMethod;
+    private static final Method getNameMethod;
 
     static {
         Class<?> c1 = null;
@@ -74,6 +75,7 @@ class Jre9Compat extends Jre8Compat {
         Method m16 = null;
         Method m17 = null;
         Method m18 = null;
+        Method m19 = null;
 
         try {
             // Order is important for the error handling below.
@@ -105,6 +107,7 @@ class Jre9Compat extends Jre8Compat {
             m17 = Class.class.getMethod("getModule");
             Class<?> moduleClass = Class.forName("java.lang.Module");
             m18 = moduleClass.getMethod("isExported", String.class);
+            m19 = moduleClass.getMethod("getName");
 
         } catch (SecurityException e) {
             // Should never happen
@@ -154,6 +157,7 @@ class Jre9Compat extends Jre8Compat {
         canAccessMethod = m16;
         getModuleMethod = m17;
         isExportedMethod = m18;
+        getNameMethod = m19;
     }
 
 
@@ -281,4 +285,20 @@ class Jre9Compat extends Jre8Compat {
             return false;
         }
     }
+
+
+    @Override
+    public String getModuleName(Class<?> type) {
+        try {
+            Object module = getModuleMethod.invoke(type);
+            return (String) getNameMethod.invoke(module);
+        } catch (IllegalArgumentException e) {
+            // See below
+        } catch (IllegalAccessException e) {
+            // See below
+        } catch (InvocationTargetException e) {
+            // See below
+        }
+        return "ERROR";
+    }
 }
diff --git a/java/org/apache/tomcat/util/compat/JreCompat.java b/java/org/apache/tomcat/util/compat/JreCompat.java
index 32835c5..b9514cb 100644
--- a/java/org/apache/tomcat/util/compat/JreCompat.java
+++ b/java/org/apache/tomcat/util/compat/JreCompat.java
@@ -403,4 +403,17 @@ public class JreCompat {
     public boolean isExported(Class<?> type) {
         return true;
     }
+
+
+    /**
+     * What is the module of the given class?
+     *
+     * @param type  The class to test
+     *
+     * @return Always {@code true} for Java 8. {@code true} if the enclosing
+     *         package is exported for Java 9+
+     */
+    public String getModuleName(Class<?> type) {
+        return "NO_MODULE_JAVA_8";
+    }
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 5d00cd1..5345516 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -78,6 +78,11 @@
         <code>renewThreadsWhenStoppingContext</code> is enabled for the web
         application. (markt)
       </fix>
+      <add>
+        Improve the error messages when running under JPMS without the necessary
+        options to enable reflection required by the memory leak prevention /
+        detection code. (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Web applications">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org