Patching java.base results in java.lang.LinkageError

流过昼夜 提交于 2020-01-13 11:09:09

问题


I am trying to do the same thing in Java 11 that could be done with -Xbootclasspath/p:path in pre java 9.

As a simple example I modified one of the valueOf methods of java.lang.Integer and compiled the project with:

javac --module-source-path=src/java.base --patch-module java.base=src/java.base -d mods $(find src -name '*.java')

I then ran a simple sample using:

java --patch-module java.base=<pathToMyModifiedJavaBaseClasses> -p lib -m my.moduleA/my.moduleA.Main

That worked an I'm seeing the modifications displayed (a simple print out I did from valueOf).

When I try, however, to do the same thing with java.lang.ClassLoader I get the following error when executing the program (compile works):

Error occurred during initialization of boot layer java.lang.LinkageError: loader 'bootstrap' attempted duplicate class definition for java.lang.invoke.SimpleMethodHandle.

I do not even need to make changes in java.lang.ClassLoader. The sheer existence of that class in my patch folder seems to be provocing this error. (I only wanted to add a field though at the bottom of the class)

NOTE: I just figured that it works when the ClassLoader class is compiled with Eclipse. One of the few differences I know is that the Eclipse compiler does not seem to follow JEP 280 yet. But there are invokedynamic instructions in the bytecode resulting from javac as well, so I doubt that this is the problem.


回答1:


You did already point into the right direction. It works when you compile the class with your current version of Eclipse, because that compiler does not follow JEP 280 yet, so it doesn’t use invokedynamic for string concatenation.

This does not imply that using invokedynamic in ClassLoader is problematic in general. It is only problematic in certain critical code paths executed during the bootstrapping of the java.lang.invoke package and apparently, this class does use string concatenation on this code path.

In case of javac, you can force the use of the old string concatenation code via the option
-XDstringConcat=inline. Looking into the bytecode of the ClassLoader.class as shipped with the JDK, it seems this class has been compiled with this option. In fact, looking at some samples, it seems the entire java.base module has been compiled with that option, in contrast to, e.g. java.desktop, whose classes use invokedynamic for string concatenation.

So the conclusion is, to patch classes in the java.base module (in OpenJDK and derivatives), compile them using the -XDstringConcat=inline option when using javac.



来源:https://stackoverflow.com/questions/54635667/patching-java-base-results-in-java-lang-linkageerror

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!