27 Java动态加载第三方jar包中的类

时间:2023-03-09 03:47:39
27 Java动态加载第三方jar包中的类

我加载的方法是:
//参数fileName是jar包的路径,processorName 是业务类的包名+类名
public static A load(String fileName, String processorName) {
            String filePath = fileName;
              A processor = null;
  URL url;
try {
  url = new URL(filePath);
} catch (MalformedURLException e1) {
 e1.printStackTrace();
log.error("文件不存在");
return null;
}
URLClassLoader loader = new URLClassLoader(new URL[] { url });
try {
Class<?> processorClass = loader.loadClass(processorName);
processor = (A)processorClass.newInstance();
} catch (Exception e) {
log.error("创建业务类失败");
e.printStackTrace();
return null;
}
return processor;
}
问题:用main方法来调用这个load方法是能加载jar包中业务类a的,但是如果在自己系统里面按照正常流程走的时候调用load方法的时候 却报错:接口类A找不到, 但是接口类A是明明定义在系统内部的,(两次调用load方法的入参都是一样的)

解决方法:

parentClassLoader,即Thread.currentThread().getContextClassLoader(),就能从当前程序中查找接口类A

package com.main.java;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader; /**
*/
public class TestClassLoad2 {
private static Logger LOGGER = LoggerFactory.getLogger(TestClassLoad2.class);
public static void main(String[] args) {
args=new String[]{"file://F:/bin/lib/test.jar","com.main.java.TestProcess"};
LOGGER.info("start");
load(args[],args[]);
}
public static Process load(String fileName, String processorName) {
String filePath = fileName;
Process processor = null;
URL url;
try {
url = new URL(filePath);
} catch (MalformedURLException e1) {
e1.printStackTrace();
LOGGER.info("文件不存在");
return null;
}
URLClassLoader loader = new URLClassLoader(new URL[]{url},Thread.currentThread().getContextClassLoader());
//URLClassLoader loader = new URLClassLoader(new URL[] { url });
try {
Class<?> processorClass = loader.loadClass(processorName);
processor = (Process)processorClass.newInstance();
processor.display();
} catch (Exception e) {
LOGGER.info("创建业务类失败");
e.printStackTrace();
return null;
}
return processor;
}
}
package com.main.java;

public interface Process {
void display();
}

另一个jar包的类

package com.main.java;
public class TestProcess implements Process {
@Override
public void display() {
System.out.println("test testProcess");
}
}

注意事项: 两个jar包的Process接口,包路径必须一致

file://F:/bin/lib/ 也可以