java自定义类库,用自定义版本替换Java类库中的类

The class BasicLabelUI in javax/swing/plaf/basic is affected by a confirmed bug.

In my application I need functionality provided by the fixed version (filed for v9).

Due to both legal and technical reasons, I'm still bound to the affected JDK version.

My approach was to create a package javax/swing/plaf/basic inside my project, containing the fixed version.

How can I force my project to favor my included version of the class over the defective class in the installed JDK?

This has to be somewhat portable as the fixed class also has to be working on customer side and the defective class in the JDK installation has to be disregarded. Therefore, I dont want to modify the JDK, but rather bypass this particular class.

解决方案

As mentioned by the other answers, you could in theory of course unzip your JVM's rt.jar file and replace the file with a compatible bugfixed version.

Any classes of the Java Class library such as those of Swing are loaded by the bootstrap class loader which looks up its classes from this rt.jar. You can generally not prepend classes to this classpath without adding them to this file. There is a (non-standard) VM option

-Xbootclasspath/jarWithPatchedClass.jar:path

where you would prepend a jar file that includes the patched version, but this does not necessarily work on any Java virtual machine. Also, it is illegal to deploy an application that changes this hehavior! As it is stated in the official documentation:

Do not deploy applications that use this option to override a class in

rt.jar because this violates the Java Runtime Environment binary code

license.

If you however appended a class to the bootstrap class loader (what is possible without using non-standard APIs by using the instrumentation API), the runtime would still load the original class as the bootstrap class loader in this case searches the rt.jar first. It is therefore impossible to "shadow" the broken class without modifying this file.

Finally, it is always illegal to distribute a VM with a patched file, i.e. putting it into a production system for a customer. The license agreement states clearly that you need to

[...] distribute the [Java runtime] complete and unmodified and only bundled as part of your applets and applications

Changing the VM that you distribute is therefore not recommended as you might face legal consequences when this is ever uncovered.

Of course, you can in theory build your own version of the OpenJDK but you could not call the binary Java anymore when you distribute it and I assume that your customer would not allow for this by what you suggest in your answer. By experience, many secure environments compute hashes of binaries before execution what would prohibit both approaches of tweaking the executing VM.

The easiest solution for you would probably be the creation of a Java agent that you you add to your VM process on startup. In the end, this is very similar to adding a library as a class path dependency:

java -javaagent:bugFixAgent.jar -jar myApp.jar

A Java agent is capable of replacing a class's binary representation when the application is started and can therefore change the implementation of the buggy method.

In your case, an agent would look something like the following where you need to include the patched class file as a ressource:

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

}

}

});

}

}

The javadoc java.lang.instrumentation package offers a detail description of how to build and implement a Java agent. Using this approach, you can use the fixed version of the class in question without breaking the license agreement.

From experience, Java agents are a great way for fixing temporary bugs in third party libraries and in the Java Class Library without needing to deploy changes in your code or even being required to deploy a new version for a customer. As a matter of fact, this is a typical use case for using a Java agent.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值