修补java.base结果导致java.lang.LinkageError [英] Patching java.base results in java.lang.LinkageError

查看:201
本文介绍了修补java.base结果导致java.lang.LinkageError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Java 11中执行与Java 9以前版本中的-Xbootclasspath/p:path相同的操作.

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

作为一个简单的示例,我修改了java.lang.IntegervalueOf方法之一,并使用以下代码编译了项目:

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

那行得通,我看到了所显示的修改(我从valueOf做的简单打印输出).

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

但是,当我尝试使用java.lang.ClassLoader做同样的事情时,在执行程序时(编译工作),出现以下错误:

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.

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

我什至不需要在java.lang.ClassLoader中进行更改.我的补丁程序文件夹中该类的绝对存在似乎正在引发此错误. (我只想在课程的底部添加一个字段)

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)

注意:我只是想知道ClassLoader类是使用Eclipse编译的,它可以工作.我知道的几个区别之一是,Eclipse编译器似乎还没有遵循 JEP 280 .但是在javac产生的字节码中也有invokedynamic指令,所以我怀疑这是问题所在.

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.

推荐答案

您确实已经指出了正确的方向.当您使用当前版本的Eclipse编译该类时,它可以工作,因为该编译器不会遵循 JEP 280 ,因此它不使用invokedynamic进行字符串连接.

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.

这并不意味着在ClassLoader中使用invokedynamic通常是有问题的.只是在java.lang.invoke软件包的引导过程中执行的某些关键代码路径中存在问题,并且显然,此类确实在此代码路径上使用字符串连接.

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.

对于javac,您可以通过选项
强制使用旧的字符串连接代码. -XDstringConcat=inline.查看JDK随附的ClassLoader.class的字节码,似乎已经使用此选项编译了该类.实际上,看一些示例,似乎整个java.base模块已经使用该选项进行了编译,与之相反,例如java.desktop,其类使用invokedynamic进行字符串连接.

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.

因此得出的结论是,要修补java.base模块中的类(在OpenJDK及其衍生物中),请在使用javac时使用-XDstringConcat=inline选项对其进行编译.

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.

这篇关于修补java.base结果导致java.lang.LinkageError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆