我有一个包含5个类的jar文件。我只想改变那门课程中的一个逻辑。
BaseClass是我需要解决的问题。请检查以下基础结构。
我只需删除一行并在changeMe
方法中添加3行。
班级结构
package com.temp;
public class BaseClass{
public interface IClassA{ String sayRaw(String raw); }
private BaseClass(){}
protected static class ClassToFix extends ClassParent {
@Override public void changeMe () {
........
}
}
}
//---------Source from jar file--------------
package com.temp;
public class ClassA implements IClassA{
public static final BaseClass.IClassA ABC = ....;
String sayRaw(String raw){
}
}
我尝试了什么
我在src目录中创建了相同的包并复制了类定义并添加了我的修复。此修复程序适用于动态Web项目,但不适用于Maven Java项目。它表示链接错误
ClassA是BaseClass的接口(IClassA)的实现 是经过修改的来源。
java.lang.LinkageError:加载器约束违规:解析时 字段“ABC”类加载器(实例) 组织/ springframework的的/ boot / devtools /重启/类加载器/ RestartClassLoader) 引用类,com / temp / ClassA和类加载器 (字段的sun / misc / Launcher $ AppClassLoader的实例) 已解析的类型,com / temp / BaseClass $ IClassA,具有不同的类 该类型的对象
建议我是否有其他方法可以解决此问题。
答案 0 :(得分:0)
您无法在运行时创建在编译时不允许创建的类。 JVM在加载之前验证任何类,并且将禁止您尝试的内容。
使用Byte Buddy或Javassist,您可以定义一个可以在启动时添加的所谓Java代理。这样做,您可以在首次加载时重新定义ClassToFix
。
Byte Buddy包含AgentBuilder
抽象,这使得这很容易实现。你可以找到tutorials on how to implement an agent online。 Javassist不提供定义Java代理的机制,但它允许您在创建自己的ClassFileTransformer
时重新定义类。
答案 1 :(得分:0)
你试过方面吗? Aspect为任何非final类的对象创建代理(但我不确定它是否适用于私有构造函数)并允许您拦截任何方法的请求。所以你可以编写自定义逻辑。