用自定义版本替换Java类库中的类
类 BasicLabelUI 中 的javax /秋千/ PLAF /基本
是通过影响已确认的bug。在我的应用程序中,我
需要
固定版本(适用于v9)提供的功能。由于法律和技术方面的原因,我仍然受受影响的JDK版本的约束。
我的方法是在项目内部创建一个包含固定版本的包 javax / swing / plaf / basic 。
与已安装的JDK中的缺陷类相比,我该如何强迫我的项目偏爱包含的类版本?
这必须具有一定的可移植性,因为固定类也必须在客户端使用,并且必须忽略JDK安装中的缺陷类。因此,我不想修改JDK,而是绕过此特定类。
回答:
正如其他的答案中提到,您 在过程中解压缩到JVM的理论 rt.jar的 文件,并兼容bugfixed版本替换该文件。
引导类加载器 会加载Java类库的所有类(例如Swing的 类),该类加载器 会从 rt.jar
查找其类。如果不将类添加到此文件中,通常不能将它们添加到 路径中。有(非标准)VM选项
-Xbootclasspath/jarWithPatchedClass.jar:path
您可能会在其中添加一个包含修补程序版本的jar文件,但这在任何Java虚拟机上都不一定有效。另外, 更改此行为 也是
!如官方文档中所述:
不要部署使用此选项覆盖rt.jar中的类的应用程序,因为这违反了Java Runtime Environment二进制代码许可证。
但是,如果您将一个类附加到引导类加载器(通过使用仪表API不使用非标准API的情况下可以实现),则运行时仍会加载原始类,因为引导类加载器在这种情况下首先搜索
rt.jar 。因此,如果不修改此文件就无法“遮盖”损坏的类。
最后,分发带有补丁文件的VM(即将其放入客户的生产系统中)始终是非法的。许可协议明确指出您需要
[…]完整且未经修改地分发[Java运行时],仅捆绑为小程序和应用程序的一部分
因此,不建议更改分发的VM,因为一旦发现它,您可能会面临法律后果。
当然,从理论上讲,您可以构建自己的OpenJDK版本,但是在分发二进制 Java
时,您再也不能调用它了,并且我认为您的客户在您的回答中所建议的不允许这样做。根据经验,许多安全环境会在执行之前计算二进制哈希,这将阻止两种方法来调整正在执行的VM。
对您而言,最简单的解决方案可能是创建一个Java代理,然后在启动时将其添加到VM进程中。最后,这与将库添加为类路径依赖项非常相似:
java -javaagent:bugFixAgent.jar -jar myApp.jar
启动应用程序时,Java代理能够替换类的二进制表示形式,因此可以更改越野车方法的实现。
在您的情况下,代理将如下所示,您需要将修补的类文件作为资源包括在内:
public static class BugFixAgent { public static void premain(String args, Instrumentation inst) {
inst.addClassFileTransformer(new ClassFileTransformer() {
@Override
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) {
if (className.equals("javax/swing/plaf/basic/BasicLabelUI")) {
return patchedClassFile; // as found in the repository
// Consider removing the transformer for future class loading
} else {
return null; // skips instrumentation for other classes
}
}
});
}
}
javadoc
java.lang.instrumentation
软件包提供了有关如何构建和实现Java代理的详细描述。使用这种方法,您可以使用相关类的固定版本,
。
从经验来看,Java代理是修复第三方库和Java类库中的临时错误的好方法,而无需部署代码中的更改,甚至不需要为客户部署新版本。实际上,这是使用Java代理的典型用例。
以上是 用自定义版本替换Java类库中的类 的全部内容, 来源链接: utcz.com/qa/427330.html