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:08:23 UTC

[tomcat] branch 9.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 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


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

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

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

diff --git a/java/org/apache/catalina/loader/LocalStrings.properties b/java/org/apache/catalina/loader/LocalStrings.properties
index 900695f..7c6c976 100644
--- a/java/org/apache/catalina/loader/LocalStrings.properties
+++ b/java/org/apache/catalina/loader/LocalStrings.properties
@@ -13,8 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-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.addPermissionNoCanonicalFile=Unable to obtain a canonical file path from the URL [{0}]
 webappClassLoader.addPermissionNoProtocol=The protocol [{0}] in the URL [{1}] is not supported so no read permission was granted for resources located at this URL
 webappClassLoader.addTransformer=Added class file transformer [{0}] to web application [{1}].
diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
index 65fa8b6..340f214 100644
--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
@@ -1978,7 +1978,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(
@@ -2240,7 +2241,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
                 throw e;
@@ -2257,6 +2259,18 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
         } catch (ReflectiveOperationException | SecurityException | ClassCastException e) {
             log.warn(sm.getString(
                     "webappClassLoader.clearObjectStreamClassCachesFail", getContextName()), e);
+        } catch (Exception 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 11122fa..87a3c38 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 JreCompat {
     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 JreCompat {
         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 JreCompat {
             m17 = Class.class.getMethod("getModule");
             Class<?> moduleClass = Class.forName("java.lang.Module");
             m18 = moduleClass.getMethod("isExported", String.class);
+            m19 = moduleClass.getMethod("getName");
 
         } catch (ClassNotFoundException e) {
             if (c1 == null) {
@@ -142,6 +145,7 @@ class Jre9Compat extends JreCompat {
         canAccessMethod = m16;
         getModuleMethod = m17;
         isExportedMethod = m18;
+        getNameMethod = m19;
     }
 
 
@@ -243,4 +247,15 @@ class Jre9Compat extends JreCompat {
             return false;
         }
     }
+
+
+    @Override
+    public String getModuleName(Class<?> type) {
+        try {
+            Object module = getModuleMethod.invoke(type);
+            return (String) getNameMethod.invoke(module);
+        } catch (ReflectiveOperationException e) {
+            return "ERROR";
+        }
+    }
 }
diff --git a/java/org/apache/tomcat/util/compat/JreCompat.java b/java/org/apache/tomcat/util/compat/JreCompat.java
index 099ee87..af2ccb8 100644
--- a/java/org/apache/tomcat/util/compat/JreCompat.java
+++ b/java/org/apache/tomcat/util/compat/JreCompat.java
@@ -268,4 +268,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 6f911e9..e6ea547 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -100,6 +100,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="Coyote">


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