背景
有时候在阅读JDK源码的时候,需要调试修改源码,但又只有jar包。这个时候我们可以借助JAVA的endorsed技术。在官方文档如下描述。
Specifying the -Djava.endorsed.dirs=lib/endorsed system property on the Java command line will force the JVM to prefer any library it finds in the endorsed directory over its own system libraries. Copying the jars into $JAVA_HOME/jre/lib/endorsed will do the same thing.
也就是说我们将自己写好的jar包放在endorsed目录下,就可以在遇到与jdk源码冲突时,优先使用我们自己的类。
实战(以修改JDK源码中ObjectStreamClass为例)
定位endorsed目录
String property = System.getProperty("java.endorsed.dirs");
System.out.println(property);
或者时在启动的时候指定endorsed目录
-Djava.endorsed.dirs=C:\Users\admin\mmmm\
创建与JDK中ObjectStreamClass对应的同名自定义类。
以下时我修改源码的地方
编译生成jar包具体步骤如下,也可使用jar命令打包成jar包,自行选择,此处使用idea工具
使用生成的jar包
将上一步最后生成的jar包放在定位到的endorsed目录下,即可调试修改后的源码
验证
以下测试代码
B b = new B();
b.i = 2;
b.s = "b";
FileOutputStream fileOutputStream1 = new FileOutputStream("temp");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream1);
objectOutputStream.writeObject(b);
fileOutputStream1.close();
//通过文件读取obj
FileInputStream fileInputStream1 = new FileInputStream("temp");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream1);
B b2 = (B) objectInputStream.readObject();
fileInputStream1.close();
System.out.println(b2.i);
System.out.println(b2.s);
class B implements Externalizable {
private static final long serialVersionUID = 1L;
//必须要有公开无参构造函数。否则报错
// public B() {
// System.out.println("调用无参那构造方法B");
//
// }
int i;
String s;
@Override
public void writeExternal(ObjectOutput out) throws IOException {
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
}
在复制到endorsed目录之前
复制到endorsed目录之后