JavaWeb项目加载resources(WEB-INF/classes/)目录下的jar/zip包到classpath
需要两个步骤
- 新建一个Listener,用于在容器初始化时扫描WEB-INF/classes/目录下的jar包。
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class LoadingJarListener implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce) {
//加载resource下的jar
System.out.println("loading resources jar...");
String path = this.getClass().getResource("/").getPath();
System.out.println(path);
// jar的路径
File libPath = new File(path);
// 获取所有的.jar和.zip文件
File[] jarFiles = libPath.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar") || name.endsWith(".zip");
}
});
if (jarFiles != null) {
// 从URLClassLoader类中获取类所在文件夹的方法
// 对于jar文件,可以理解为一个存放class文件的文件夹
Method method = null;
boolean accessible = false;
try {
method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
accessible = method.isAccessible(); // 获取方法的访问权限
if (accessible == false) {
method.setAccessible(true); // 设置方法的访问权限
}
//加载jar到classpath
URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
for (File file : jarFiles) {
URL url = file.toURI().toURL();
try {
method.invoke(classLoader, url);
System.out.println(String.format("加载jar文件[name=%s]", file.getName()));
} catch (Exception e) {
System.err.println(String.format("加载jar文件[name=%s]失败", file.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(method != null){
method.setAccessible(accessible);
}
}
}
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
2.在web.xml中配置刚才写的listener。
<listener>
<listener-class>LoadingJarListener</listener-class>
</listener>
提醒:此方法是通过IO读取jar/zip文件,发布的war包必须解压后运行才管用。