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