gwtproject / gwt

GWT Open Source Project
http://www.gwtproject.org
1.52k stars 373 forks source link

JettyLauncher throws exception with Java 9 for "jrt:" URL #9582

Open gwtuser opened 6 years ago

gwtuser commented 6 years ago

GWT version: 2.8.2 Browser (with version): N/A Operating System: OpenSUSE 42.2 64-bit


Description

When GWT Plugin v3 is run in SuperDevMode with Eclipse Oxygen, JDK9.0.1, and GWT 2.8.2, the built-in Jetty server (or its launcher) crashes with the following trace:

Found resouce but unrecognized URL format: 'jrt:/java.sql/javax/sql/DataSource.class' Java.lang.NoClassDefFoundError: javax/sql/DataSource at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1007) at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174) at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:545) at java.base/java.net.URLClassLoader.access$100(URLClassLoader.java:83) at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:453) at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:447) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:446) at org.eclipse.jetty.webapp.WebAppClassLoader.findClass(WebAppClassLoader.java:510) at com.google.gwt.dev.shell.jetty.JettyLauncher$WebAppContextWithReload$WebAppClassLoaderExtension.findClass(JettyLauncher.java:480) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:441) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:403) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:375)

Note that due to the misspelling of "resouce" this message is easily traced back to JettyServer.java, which appears to be GWT's wrapper code. It doesn't appear to recognize the "jrt:" format.

Steps to reproduce

Trigger loading of javax.sql.DataSource in JDK9.0.1

gwtuser commented 6 years ago

Note the Jetty team confirms that this must be a GWT JettyLauncher isssue, since Jetty 9.4.7 should handle "jrt:" URLs OK: https://github.com/eclipse/jetty.project/issues/1498

dmac000 commented 5 years ago

Are there any ideas on a solution to this? I'm not familiar with the GWT internals but trying to solve this to upgrade the JDK.

As far as I can see, the issue is that With JDK 9, the javax.sql classes are no longer available from bootStrapOnlyClassLoader. They're found in systemClassLoader but as "jrt:" URLs which can't be resolved in the WebAppClassLoader.

I've tried adding "javax.sql." to allowedFromSystemClassLoader which seems to work but don't know if there are drawbacks to this.

Alternatively, according to: Java 9 Migration:

The changes in JDK 9 may impact code that creates class loaders with null (that is, the bootstrap class loader) as the parent class loader and assumes that all platform classes are visible to the parent. Such code may need to be changed to use the platform class loader as the parent (see ClassLoader.getPlatformClassLoader).

We can change bootStrapOnlyClassLoader to use getPlatformClassLoader instead. Maybe looked up using reflection so that it's backward compatible with earlier JDKs.

tbroyer commented 5 years ago

Fwiw, this is one of the many reasons I don't want to maintain JettyLauncher anymore, and recommend you switch to using CodeServer and a separate servlet container.

The alternative would be to remove all that classloading code from JettyLauncher, using only what's in WEB-INF/ and ignoring the DevMode classpath.

eliasbalasis commented 1 year ago

Adding "javax.sql." to "allowedFromSystemClassLoader" seemed to work at first but not fully. I faced classpath resolution issues with this approach on JDK11 and GWT 2.9.0.

Couldn't we make GWT understand a more elegant way of assigning "allowedFromSystemClassLoader" at runtime ?

niloc132 commented 1 year ago

Give 2.10 a try, as some of this was changed as part of updating Jetty.

That said, we still don't encourage this, it is very hard to make this be all things to all people. Consider either running your own server and using the CodeServer main instead of DevMode (or pass -noserver to DevMode), or implementing your own launcher as a subclass of com.google.gwt.core.ext.ServletContainerLauncher, and pass that to DevMode with -server your.classname.GoesHere.

eliasbalasis commented 1 year ago

Thanks @niloc132

The problem I had after extending "allowedFromSystemClassLoader" with "javax.sql." and setting "bootStrapOnlyClassLoader" to "null", was the discovery of the same resource (db-changelog.xml) in multiple classloaders failing my app bootstrap.

I have changed the JettyLauncher further, returning only one resource and I can now use the "GWT Eclipse Plugin" saving myself and my teams from the transformation pain, for now.

Unfortunately, I cannot try with GWT 2.10.0 because it is not recognized by the current version of the "GWT Eclipse Plugin". I am hoping the next release of the "GWT Eclipse Plugin" will support this. see (https://github.com/gwt-plugins/gwt-eclipse-plugin/issues/406)

If this doesn't work, without changes to JettyLauncher, then I would suggest adding a feature to GWT to control "allowedFromSystemClassLoader" at runtime.

If everything in the end fails and "GWT Eclipse Plugin" dies permanently then I will inevitably embrace the pain of transforming our applications and teach our teams new ways.

I hope this explains my situation better.

niloc132 commented 1 year ago

We're working on the plugin - the net result of the changes in motion and the Eclipse Marketplace policy is that we likely will release a new plugin, encouraging users to move to that instead of the existing one. We aren't far off, but end of the year holidays will slow us down a bit.

quantmode commented 1 year ago

I had the same issue. Can confirm that modifying JettyLauncher to allow javax.sql in "allowedFromSystemClassLoader" works for me. I am using GWT Eclipse Plugin 4.0.0 and GWT 2.10.0.

RGeorgy commented 1 year ago

I had the same issue. Can confirm that modifying JettyLauncher to allow javax.sql in "allowedFromSystemClassLoader" works for me. I am using GWT Eclipse Plugin 4.0.0 and GWT 2.10.0.

Quantmode, can you please explain in more detail what you have done. Facing the same problem with GWT plugin 4.0 und GWT 2.10.0 + Java 17 in Eclipse 23-03 with function Debug as - Development mode with Jetty . Desperately seeking a solution ....

twwva commented 1 year ago

I had the same issue and what quantmode suggested also worked for me. Specifically added "javax.sql." to the list of strings in allowedFromSystemClassLoader in class com.google.gwt.dev.shell.jetty.JettyLauncher.

niloc132 commented 1 year ago

@twwva Perhaps we could introduce a patch to let a system property add additional elements to the array, so projects can control this as needed without forking?

amir10058 commented 1 year ago

@twwva could you please send me com.google.gwt.dev.shell.jetty.JettyLauncher bytecode class file?

quantmode commented 1 year ago

In JettyLauncher.java:

   private final ClasspathPattern allowedFromSystemClassLoader = new ClasspathPattern(new String[] {
       "org.eclipse.jetty.",
       "javax.websocket.",
       // Jasper
       "org.apache.jasper.",
       "org.apache.juli.logging.",
       "org.apache.tomcat.",
       "org.apache.el.",
       // Xerces
       "org.apache.xerces.",
       "javax.xml.", // Used by Jetty for jetty-web.xml parsing
       "javax.sql.", //<--------- ADD THIS ---------- //
   });
Alexander-ac commented 1 year ago

Hello guys, I have checked out the main branch. (https://github.com/gwtproject/gwt) Then i adapted this class gwt/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java.

In next step i tried to build the package. ( ant clean dist-dev) Build process was successful, but when I run the decompiler, I don't see my change. Which Java version did you build it with? How did you compile it?

RGeorgy commented 9 months ago

Now it seems you have resolved this issue. Is there any easy way to get hold of the modified plugin to install in Eclipse. You can easily upload to https://hidrive.ionos.com/upl/MZyTTytb ...