package agent;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.javaRasp.commons.config;
public class HotSwap {
public static void hotSwap(final Instrumentation inst) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
// 获取jar包中的class文件加载时间,轮询修改项,实现热加载
while (true) {
try {
Thread.sleep(2000);
Class<?>[] loadClasses = LoadClasses.getLoadClasses();
if (loadClasses.length > 0) {
for (int i = 0; i < loadClasses.length; i++) {
System.out.println("[[[[[[[[[[-666-" + loadClasses[i] + "-666-]]]]]]]]]]");
}
inst.redefineClasses(TransforSysClass.redefineClasses(inst, loadClasses));
}
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
});
thread.setDaemon(true);
thread.start();
}
}
class LoadClasses {
// 缓存加载class文件的最后最新修改时间
public static Map<String, Long> cacheLastModifyTimeMap = new HashMap<String, Long>();
public static Class<?>[] getLoadClasses() {
Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
JarFile jar;
try {
jar = new JarFile("E:\\datacloudWorkspace8\\raspHotSwap\\target\\raspHotSwap.jar");
Enumeration<JarEntry> entries = jar.entries();
// 同样的进行循环迭代
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
Long currentMillis = entry.getLastModifiedTime().toMillis();
String clazzName = entry.getName();// agent/classAdapter/FileAdapter.class
if (clazzName.endsWith(".class") && !entry.isDirectory()) {
Long cacheTime = cacheLastModifyTimeMap.get(clazzName);
if (cacheTime == null) {
cacheLastModifyTimeMap.put(clazzName, currentMillis);
} else if (!cacheTime.equals(currentMillis)) {
cacheLastModifyTimeMap.put(clazzName, currentMillis);
System.out.println(clazzName);
classes.add(Thread.currentThread().getContextClassLoader().loadClass(clazzName));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return classes.toArray(new Class[classes.size()]);
}
}