ClassLoader优先级问题
最近做一个web项目,服务器用的是tomcat,需要一个动态添加jar库的功能(系统不停机),我在程序中用URLClassLoader动态加载新的jar,发现无法引用项目里面WEB-INF/lib下的jar库,老是报ClassNotFoundException,我在没有动态加载jar之前看了看原有jar中类的加载器是org.apache.catalina.loader.WebappClassLoader:
输出结果是WebappClassLoader,这个类是java.net.URLClassLoader的子类,属于最低优先级的类加载器,现在我用URLClassLoader加载新的jar文件,就出错:
不过这里抛出的异常不是className没找到,而是className的父接口没找到,className父接口所在的jar包在WEB-INF/lib目录下。我尝试了下面两个办法解决:
1.用Java Instrumentation把className父接口所在的jar包加入系统classpath中,这时loadClass正常了,但是后面无法直接调用类的方法了,必须全部用反射调用,这样需要修改大量代码,就没有继续。
2.把WEB-INF/lib里面的jar全部拷到%JRE_HOME%\lib\ext里面,现在一切都正常了,但是这样需要修改系统配置,而我更希望能在程序代码中解决这个问题,或者最多是修改项目配置。
不知道大家还有没有其它解决方法,我希望能通过在ClassLoader下手解决。谢谢!
Class<?>c = Class.forName("org.slf4j.Logger");//slf4j的jar包在WEB-INF/lib目录下
out.print(c.getClassLoader().getClass().getName());输出结果是WebappClassLoader,这个类是java.net.URLClassLoader的子类,属于最低优先级的类加载器,现在我用URLClassLoader加载新的jar文件,就出错:
String className;//类名
URL[] url;//url数组
//省略变量初始化,保证变量值正确
ClassLoader loader = new URLClassLoader(url);
Class<?> c = loader.loadClass(className);//这里抛ClassNotFoundException异常
Object obj = c.newInstance();
不过这里抛出的异常不是className没找到,而是className的父接口没找到,className父接口所在的jar包在WEB-INF/lib目录下。我尝试了下面两个办法解决:
1.用Java Instrumentation把className父接口所在的jar包加入系统classpath中,这时loadClass正常了,但是后面无法直接调用类的方法了,必须全部用反射调用,这样需要修改大量代码,就没有继续。
2.把WEB-INF/lib里面的jar全部拷到%JRE_HOME%\lib\ext里面,现在一切都正常了,但是这样需要修改系统配置,而我更希望能在程序代码中解决这个问题,或者最多是修改项目配置。
不知道大家还有没有其它解决方法,我希望能通过在ClassLoader下手解决。谢谢!
...全文
相关推荐
Java classloader和namespace详细介绍
这种方式保证了核心类库的优先级,避免了不同ClassLoader加载相同类导致的冲突问题。命名空间是每个ClassLoader特有的,由它装载的类拥有独特的标识。
maven-classloader-plugin:只是针对Maven插件中的类加载问题的实验
例如,可以指定哪些插件应该共享类加载器,或者设定特定插件的类加载优先级。这为开发者提供了更大的灵活性,解决了传统Maven类加载机制中可能出现的问题。
classloader简单例子
在实际开发中,熟练掌握类加载器的用法可以解决许多复杂的问题,提升软件的可扩展性和灵活性。
Tomcat加载顺序
与Common ClassLoader类似,但它的优先级更高,这意味着如果在两个目录下有同名的类,Shared ClassLoader加载的类将被优先考虑。#### 6.
spring boot加载资源路径配置和classpath问题解决
Classpath下lib的优先级大于classes。Spring Boot加载资源路径配置和Classpath问题解决是Java应用程序中的一个重要概念。


Java SE
