1 相关的tarce,watch命令执行怎么和应用的jar不冲突
首先可以看到arthas创建了自己的agentclassLoader
private static ClassLoader getClassLoader(Instrumentation inst, File spyJarFile, File agentJarFile) throws Throwable {
// 将Spy添加到BootstrapClassLoader
inst.appendToBootstrapClassLoaderSearch(new JarFile(spyJarFile));
// 构造自定义的类加载器,尽量减少Arthas对现有工程的侵蚀
return loadOrDefineClassLoader(agentJarFile);
}
private static ClassLoader loadOrDefineClassLoader(File agentJar) throws Throwable {
if (arthasClassLoader == null) {
arthasClassLoader = new ArthasClassloader(new URL[]{
agentJar.toURI().toURL()});
}
return arthasClassLoader;
}
其中shellserver的启动通过反射调用的 ,使用的classLoader正是agentClassLoader
Class<?> classOfConfigure = agentLoader.loadClass(ARTHAS_CONFIGURE);
Object configure = classOfConfigure.getMethod(TO_CONFIGURE, String.class).invoke(null, args);
int javaPid = (Integer) classOfConfigure.getMethod(GET_JAVA_PID).invoke(configure);
Class<?> bootstrapClass = agentLoader.loadClass(ARTHAS_BOOTSTRAP);
Object bootstrap = bootstrapClass.getMethod(GET_INSTANCE, int.class, Instrumentation.class).invoke(null, javaPid, inst);
boolean isBind = (Boolean) bootstrapClass.getMethod(IS_BIND).invoke(bootstrap);
if (!isBind) {
try {
ps.println("Arthas start to bind...");
bootstrapClass.getMethod(BIND, classOfConfigure).invoke(bootstrap, configure);
ps.println("Arthas server bind success.");
return;
} catch (Exception e) {
ps.println("Arthas server port binding failed! Please check $HOME/logs/arthas/arthas.log for more details.");
throw e;
}
}
反射调用的方法如下 可以看到server 的启动过程,所以后续相关的commandHandler的执行均是在agentClassLoader这个classLoader中执行的,不会跟应用的jar包冲突
public void bind(Configure configure) throws Throwable {
long start = System.currentTimeMillis();
if (!isBindRef.compareAndSet(false, true)) {
throw new IllegalStateException("already bind");
}
String agentId = null;
try {
if (configure.getTunnelServer() != null && configure.getHttpPort() > 0