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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org