9

Our project is developed using Eclipse OSGi, but provides also normal JARs via jardesc files for export. The project uses the ASM library and a javaagent in order to exchange invokevirtual with invokedynamic calls.

This worked well in Java 7 and 8. Now, we upgraded to Java 9 and ported our implementation to use jdk.dynalink.

java --version`
java 9.0.4
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)

The exported parts

  • OTRE_MIN: The minimal runtime and Meta-Object-Protocol part.
  • OTRE_DYN: The dynamic weaving code (ASM) and rest of runtime.
  • OTRE_AGEND: The javaagent.

For now, OTRE_MIN also includes OTRE_DYN. So everything is put into the bootclasspath.

I start the program with following code

JVM_ARGS="-d64 -Xms1024m -Xmx4048m -ea"
MODULES="--add-reads jdk.dynalink=ALL-UNNAMED --add-reads java.base=ALL-UNNAMED"

${JAVA_HOME}bin/java $MODULES \
-Xbootclasspath/a:${OTRE_MIN} -javaagent:$OTREDYN_AGENT $JVM_ARGS \
-jar ...

However, it seems that the jdk.dynalinkpackages are not visible anymore on the bootclasspath.

java.lang.NoClassDefFoundError: jdk/dynalink/linker/GuardingDynamicLinker
at org.eclipse.objectteams.otredyn.runtime.dynamic.CallinBootstrap.<clinit>(CallinBootstrap.java:19)
at org.eclipse.objectteams.otredyn.bytecode.asm.CreateCallAllBindingsCallInOrgMethod.<clinit>(CreateCallAllBindingsCallInOrgMethod.java:115)
at org.eclipse.objectteams.otredyn.bytecode.asm.AsmWritableBoundClass.createCallAllBindingsCallInOrgMethod(AsmWritableBoundClass.java:300)
at org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass.weaveBindingInImplementedMethod(AbstractBoundClass.java:1180)
at org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass.handleTaskList(AbstractBoundClass.java:741)
at org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass.transformAtLoadTime(AbstractBoundClass.java:383)
at org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer.transform(ObjectTeamsTransformer.java:120)
at org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer.transform(ObjectTeamsTransformer.java:72)
at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:246)
at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:550)
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/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:801)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:699)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:622)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:580)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
at BankBenchmark2.setUp(BankBenchmark2.java:32)
at Run.doRuns(Run.java:55)
at Run.runBenchmark(Run.java:29)
at Harness.main(Harness.java:34)

I read other threads about Java 9 and the module system and the changes to the class loaders, but they did not provide any solution to the problem.

How can I make jdk.dynalink visible to the classes of $OTRE_MIN as pre Java 9?

lschuetze
  • 1,218
  • 10
  • 25

1 Answers1

0

The solution is to be much more careful about how your class path hierarchy is being filled and used. Java 9 makes you to think much more about this, because not all modules are always visible.

I split the jar's such that they are separated for each concern: javaagent, load-time weaving. Now, the minimal runtime (OTRE_MIN) is visible at the bootclasspath. The rest is added via OTRE_DYN to the normal class path of the application. OTRE_AGENT keeps the javaagent as before.

JVM_ARGS="-d64 -Xms1024m -Xmx4048m -ea"
MODULES="--add-reads jdk.dynalink=ALL-UNNAMED --add-reads java.base=ALL-UNNAMED"

${JAVA_HOME}bin/java $MODULES \
  -Xbootclasspath/a:${OTRE_MIN} -javaagent:$OTREDYN_AGENT $JVM_ARGS -cp ${OTRE_DYN} \
  -jar ...

However, this just avoids using jdk.dynlinkin the bootclasspath, and the question is still open to answer.

lschuetze
  • 1,218
  • 10
  • 25