[英]URLClassLoader not loading jar file
我當前正在使用Web應用程序,該應用程序必須從本地驅動器上的目錄加載jar文件。 經過一些研究, URLClassLoaders
似乎是最合適的解決方案。
牛肉:
public @Slf4j class ActionLoader {
private static void addFilesToClassPath(File path) {
URLClassLoader clazzLoader = null;
try {
clazzLoader = new URLClassLoader(new URL[] {path.toURI().toURL()},
ActionLoader.class.getClassLoader());
try {
Class.forName("de.befoe.xyz.ActionTest", false, clazzLoader);
} catch (ClassNotFoundException e) {
log.error("Class not found", e);
}
try {
clazzLoader.loadClass("de.befoe.xyz.ActionTest");
} catch (ClassNotFoundException e) {
log.error("Class not found", e);
}
} catch (SecurityException e) {
log.error("Access denied", e);
} catch (MalformedURLException e) {
log.error("Malformed URL", e);
} finally {
if (clazzLoader != null) {
try {
clazzLoader.close();
} catch (IOException e) {
log.error("Error closing the class loader", e);
}
}
}
}
}
First ClassNotFoundException
:
java.lang.ClassNotFoundException: de.befoe.xyz.ActionTest
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at de.procrm.speedindexer.scr.ActionLoader.addFilesToClassPath(ActionLoader.java:80)
at de.procrm.speedindexer.scr.ActionLoader.loadActions(ActionLoader.java:31)
at de.procrm.speedindexer.scr.Init.contextInitialized(Init.java:39)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4842)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:940)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:467)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1612)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1451)
at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:724)
at org.apache.catalina.manager.ManagerServlet.doPut(ManagerServlet.java:423)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:651)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:614)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
第二類ClassNotFoundException
:
java.lang.ClassNotFoundException: de.befoe.xyz.ActionTest
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at de.procrm.speedindexer.scr.ActionLoader.addFilesToClassPath(ActionLoader.java:81)
at de.procrm.speedindexer.scr.ActionLoader.loadActions(ActionLoader.java:31)
at de.procrm.speedindexer.scr.Init.contextInitialized(Init.java:39)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4842)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:940)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:467)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1612)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1451)
at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:724)
at org.apache.catalina.manager.ManagerServlet.doPut(ManagerServlet.java:423)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:651)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:614)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
路徑變量指向包含jar文件的目錄(我也嘗試使用直接指向jar文件的URL初始化類加載器)。
現在,當我嘗試從一個jar文件訪問一個類時,出現ClassNotFoundException
。 在調試器中檢查類加載器時,我還可以看到,packages和classes-字段均為空,因此看起來好像類加載器沒有加載任何內容。
首先,我認為這與缺少依賴項有關,因此我創建了一個沒有依賴項的第二個jar文件,並將類的父類加載器添加到構造函數中,但是它什么也沒有改變。
有想法嗎?
E:經過一番研究,似乎我的第一個想法(依賴性)是正確的。 我有另一個供Web應用程序和加載的jar文件使用的庫。 如果我將此庫添加到要添加到URLClassLoader的jar列表中,則可以很好地加載jar。 但是可以肯定的是,這不是我想要做的,因為從技術上講,我的Web應用程序使用的不是jar文件,而是其他類,這會導致其他問題。
現在的問題是為什么父類加載器類未正確使用。 經過進一步研究,似乎我通過調用ActionLoader.class.getClassLoader()使用的父類加載器不是正確的加載器。 因此,在eclipse調試器中,我看到了一個稱為委托的字段,該字段設置為false。 因此,我改為使用此類的父級加載器,並且文件加載也很好。
我沒有您的JAR文件,因此我已經在自定義路徑上對我的一個JAR文件進行了測試,並且使用systemClassLoader正確加載了該類。
這是示例代碼:
addFilesToClassPath(new File("C:/Users/Domenico/.m2/repository/com/doctorchat/core/0.1.ALPHA/core-0.1.ALPHA.jar"));
private static void addFilesToClassPath(File path) {
try(URLClassLoader clazzLoader = new URLClassLoader(new URL[]{path.toURI().toURL()}, ClassLoader.getSystemClassLoader())) {
Class c = clazzLoader.loadClass("com.doctorchat.core.exceptions.NotImplementedException");
System.out.println(c);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// clazzLoader.getResource()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.