Gradle is broken by JDK9 application class loader

Continuing the discussion from ClassCastException from org.gradle.process.internal.child.BootstrapSecurityManager:

2 Likes

We plan to fix this for 9 sometime soon.

@Mandy_Chung, we are in the process of investigating JDK 9 support and ClassLoader compatibility. We are particularly interested in what has or will change with the application/system ClassLoader. Would appreciate your insights!

W.r.t. class loader related change in JDK 9, you are probably safe if you donā€™t depend on the internal implementation. JEP 220 [1] documents the compatibility risks due to the Modular Runtime Image change. A few things worth mentioning:

  1. the built-in classloader may not be URLClassLoader as this bug reports.
  2. Custom class loader with null parent

It is the implementation detail if system classes are loaded by null or non-null class loader.

More system classes will be deprivileged. i.e. the defining class loader of system classes may be changed from the boot class loader to the extension class loader. Any custom ClassLoader delegates to null as the parent class loader may run into ClassNotFoundException. [2][3] is one example.

[3] tools.jar no longer exists in JDK 9. All JDK classes are linked into the modular runtime image and visible to the system class loader. itā€™s not uncommon for existing code to create a URLClassLoader to find classes from tools.jar. It will run into CNFE if such URLClassLoader delegates to null. That will be impacted.

[1] http://openjdk.java.net/jeps/220
[2] https://bugs.openjdk.java.net/browse/JDK-8042244
[3] https://bugs.eclipse.org/bugs/show_bug.cgi?id=466683

This didnā€™t get a Gradle 2.5 fix, will we be seeing a 2.6 fix?

Also, I can confirm that Mandy is right in the impicaiton that this section of code totally blows up gradle and makes it unusable in JDK 9.

But using a Security Manager to front load your testing classes?

http://www.livememe.com/238iwyp

Iā€™m not even mad, thatā€™s amazing!

Unfortunately no. We are tracking all JDK9 releated issues however as support for JDK9 is very important to us. We plan to start work on this soon. There are a number of things we want to do, including first-class support for the new features provided by jigsaw. You can take a look at the preliminary design spec here:

https://github.com/gradle/gradle/blob/master/design-docs/jdk9-support.md

Keep an eye on JEP 238 (Multi-Release JAR Files) - http://openjdk.java.net/jeps/238 - if it ships then that may provide a mechanism to have JDK 9 things done in a way that older versions of gradle donā€™t need to see. But at the expense of making the build process a bit more complex. I see that itā€™s in your plan to support JDK 9 features in that linked story but it could provide a cleaner ā€œon this JVM do this insteadā€ logic for JDK 9 + stuff so it may be worth using not just supporting.

This will be part of the new software model. This is essential the notion of ā€œvariantsā€. This concept already exists in the native world when building C/C++ projects with Gradle. We are currently in the process of adding support for JVM projects to this model. You can take a look at the spec for this as well if youā€™re curious. Much of this capability exists in Gradle master too if you want to test it out yourself.

https://github.com/gradle/gradle/blob/master/design-docs/dependency-management-for-jvm-components.md

I just updated the bug outlining a rather ā€œsimpleā€ fix using @argfile.
@argfile was recently introduced in JDK9 for java, (has been around for while for javac)

Details in https://issues.gradle.org/browse/GRADLE-3287

In version 2.13 the bug exist continue. Why is the issue closed: https://issues.gradle.org/browse/GRADLE-3287

Error occurred during initialization of VM
java.lang.ClassCastException: jdk.internal.loader.ClassLoaders$AppClassLoader (in module: java.base) cannot be cast to java.net.URLClassLoader (in module: java.base)
	at jarjar.org.gradle.process.internal.child.BootstrapSecurityManager.checkPermission(BootstrapSecurityManager.java:58)
	at java.lang.SecurityManager.checkPropertyAccess(java.base@9-ea/SecurityManager.java:1285)
	at java.lang.System.getProperty(java.base@9-ea/System.java:759)
	at java.lang.ClassLoader.initSystemClassLoader(java.base@9-ea/ClassLoader.java:1728)
	at java.lang.System.initPhase3(java.base@9-ea/System.java:1970)
1 Like