Unexpected ClassnotFoundException on reflective Class#getMethod

Alan Bateman Alan.Bateman at oracle.com
Thu Mar 31 11:09:50 UTC 2016


On 31/03/2016 11:20, Sanne Grinovero wrote:
> Thanks Alex,
> that clarifies a lot, I was just about to try with a different dependency.
>
> So this is not a reflection bug, but I'm just realising now that has
> quite significant impact on JavaEE:
> the Synchronization type is defined as public API of the specification [1].
>
> Changing the JavaEE API isn't going to be very popular, so I guess the
> expectation is for
> containers to regularly override the modules?
> This won't affect just the regular EE application servers, as these
> APIs are often used also
> in standalone JavaSE applications, as many components of the JavaEE spec can
> be run in "standalone" or "embedded" modes.
>
> For example Hibernate will now have to require the application launcher to apply
> customizations to the JVM boot parameters, and probably so any other JPA
> implementation.
>
> 1 - http://docs.oracle.com/javaee/7/api/javax/transaction/Synchronization.html
>
Java EE implementations have always upgraded/replaced a number of APIs 
that are "shared" with Java SE. The JSR-250 defined "Common Annotations" 
is another example where Java SE defines a subset of the API and Java EE 
implementations need the deploy with the full API.  So there isn't 
anything forcing anyone to change APIs, this is really just about how to 
compile or run with the Java EE versions of these components.

With JDK 8 and older then the only supported way of upgrading these 
components was the Endorsed Standards Override Mechanism. It turns out 
that this wasn't widely used and instead app servers and others have 
been putting JAR files on the class path with these components. 
Incredibly this worked even though it wasn't actually overriding the 
classes in the Java SE defined subset.

Moving to modules means that EE servers will need to deploy with the EE 
versions of these modules. Adding the class path isn't going to work 
because the module system will prohibit splitting packages between 
modules and the class path. The way to do this is, as Alex mentioned, is 
the upgrade module path.

Patching will work too, at least to get something going. In this case 
you can patch the java.transaction module with:

    -Xpatch:java.transaction=transaction-api_1.2.jar

There aren't any additional packages exported in the EE version so 
-XaddExports isn't neded. The equivalent with the Common Annotations 
would need -XaddExports because the EE version has APIs in packages that 
Java SE does not define.

One final thing to mention is that there is a proposal in the works to 
not resolve the EE modules when compiling code in the unnamed module or 
running code where the initial class is on the class path. For existing 
deployments then it would looking like that the JDK doesn't have the EE 
modules. This isn't fully implemented in the current builds but it is a 
proposal that will make migration to JDK 9 much easier for many. For 
those using the EE components outside the context of an app server then 
it would mean using `-addmods java.se.ee` so that all of the EE modules 
are resolved. I'm sure there will be more on this topic soon.

-Alan










More information about the jigsaw-dev mailing list