jdk.dynalink non visible depuis bootclasspath en Java 9


Notre projet est développé en utilisant Eclipse OSGi, mais fournit également des fichiers JAR normaux via jardesc pour l'exportation. Le projet utilise l'ASM bibliothèque et un javaagent afin d'échanger invokevirtual avec invokedynamic appels.

Cela a bien fonctionné en Java 7 et 8. Maintenant, nous avons mis à niveau vers Java 9 et porté notre implémentation pour utiliser 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)

Les pièces exportées

  • OTRE_MIN: La partie minimale d'exécution et de protocole Méta-objet.
  • OTRE_DYN: Le code de tissage dynamique (ASM) et reste de l'exécution.
  • OTRE_AGEND: Le javaagent.

Maintenant, OTRE_MIN comprend également OTRE_DYN. Donc, tout est mis dans le bootclasspath.

Je démarre le programme avec le code suivant

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 ...

Cependant, il semble que les paquets jdk.dynalink ne soient plus visibles sur le 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)

J'ai lu d'autres threads sur Java 9 et le système de modules et les modifications apportées aux chargeurs de classe, mais ils n'ont fourni aucune solution pour problème.

Comment puis-je rendre jdk.dynalink visible aux classes de $OTRE_MIN en tant que pré Java 9?

Author: lschuetze, 2018-07-17

1 answers

La solution est d'être beaucoup plus prudent sur la façon dont votre hiérarchie de chemin de classe est remplie et utilisée. Java 9 vous fait réfléchir beaucoup plus à ce sujet, car tous les modules ne sont pas toujours visibles.

Je divise les jars de telle sorte qu'ils soient séparés pour chaque préoccupation: javaagent, tissage en temps de chargement. Maintenant, le runtime minimal (OTRE_MIN) est visible dans le bootclasspath. Le reste est ajouté via OTRE_DYN au chemin de classe normal de l'application. OTRE_AGENT conserve le javaagent comme avant.

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 ...

Cependant, cela évite simplement d'utiliser jdk.dynlink dans le bootclasspath, et la question est toujours ouverte pour répondre.

 0
Author: lschuetze, 2018-07-26 14:06:22