java 运行时动态修改classpath添加外部jar

百度上的方法最多是破坏封装性的直接通过setAccessible加jar url。setAccessible 简单暴力,但是破坏了封装性,jdk版本随便改一下,可能就挂了。

还有一种方法是通过urlclassloader类,手动管理jar。但是这种方法会导致agent失效,从而导致程序无法正常运行。

Instrumentation 方法

最完美的方法是利用java agent的Instrumentation接口的appendToSystemClassLoaderSearch方法。

我找了很久才找到这个方法,线索是AppClassLoader的appendToClassPathForInstrumentation方法。

在项目里新建一个类

import java.lang.instrument.Instrumentation;

public class InstrumentationHolder {

public static Instrumentation instrumentation;

public static void premain(String agentOps, Instrumentation inst)  {

    instrumentation = inst;

}

}

把这个编译好的class按包名目录添加到一个zip中

然后在压缩包里添加META-INF/MANIFEST.MF文件

内容为

Manifest-Version: 1.0

Premain-Class: org.tomorrow.InstrumentationHolder

Can-Redefine-Classes: true

Premain-Class为之前新建的类名

然后可以把jar放到项目的资源目录

然后在IDE里面添加jvm参数

-javaagent:.\target\classes\agent.jar(zip文件路径)

这里以eclipse为例


然后只要启动,就可以通过在项目里通过这个Class获得Instrumentation了

之后只要用这个class操作就行了

Instrumentation只能加入jar,如果是文件夹就自己压缩一下

你可能感兴趣的:(java 运行时动态修改classpath添加外部jar)