JarsLink版本:1.6.1.20180301
在前两篇介绍中,主要说明了jarslink动态加载jar包的方式及部分实现代码,在测试的过程中,发现已经加载的jar包,卸载模块后不能解除stream引用,也就是已经加载的jar包,卸载模块后不能删除已经加载的jar包。
经过测试,结果如下:
需要在卸载模块的时候,将加载过程中使用的classLoader关闭并设置为null,并执行一次System.gc();测试代码如下:
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import com.alipay.jarslink.api.Action;
public class TestLoad {
private static URLClassLoader loader = null;
private static Class<?> c = null;
private static Action<String, Boolean> o = null;
private static List<URL> urls = new ArrayList<URL>();
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
File f = new File("C:\\Users\\luqiye\\eclipse-workspace-other\\JarLinkDemo\\build\\lib1");
if(!f.exists()){
System.out.println(f.getAbsolutePath()+" not exist");
return;
}
urls = new ArrayList<URL>();
if(f.isFile()) {
try{urls.add(f.toURI().toURL());}catch(Exception e) {}
}else if(f.isDirectory()) {
addURL(urls,f);
if(urls.size() == 0) {
System.out.println(f.getAbsolutePath()+" not have jars");
return;
}
}else {
System.out.println(f.getAbsolutePath()+" not file or dir");
return;
}
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
String line = sc.nextLine();
if("q".equals(line) || "quit".equals(line) || "exit".equals(line) || "e".equals(line)) {
break;
}else if("load".equals(line)) {
loadModule();
}else if("unload".equals(line)) {
unLoadModule();
}else if("start".equals(line)) {
startModule();
}else if("stop".equals(line)) {
stopModule();
}else if("print".equals(line)) {
printModule();
}
}
}
private static void unLoadModule() {
if(o != null) {
try{o.execute("stop");}catch(Exception e) {}
o = null;
}
if(c != null) {
c = null;
}
if(loader != null){
try{loader.close();}catch(Exception e) {
e.printStackTrace();
}
loader = null;
}
System.gc();
}
private static void printModule() {
// TODO Auto-generated method stub
}
private static void stopModule() {
if(o == null)
return;
System.out.println("Test: result--" + o.execute("stop"));
}
private static void startModule() {
if(o == null)
return;
System.out.println("Test: result--" + o.execute("init"));
System.out.println("Test: result--" + o.execute("start"));
}
private static void loadModule() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
loader = new URLClassLoader(urls.toArray(new URL[] {}));
c = loader.loadClass("com.hanbon.jarlink.TestOne");
o = (Action<String, Boolean>)c.newInstance();
}
//一个小递归
private static void addURL(List<URL> result,File folder) {
for(File f : folder.listFiles()) {
if(f.isDirectory()) {
addURL(result,folder);
}else if(f.isFile() && f.getName().endsWith(".jar")) {
try {
result.add(f.toURI().toURL());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
}
}