为什么在作为 JAR 执行时会出现 NoSuchMethodException?

Why do I get a NoSuchMethodException when executing as JAR?

当我在 IDE 中使用我的 URLClassLoader 时,我没有遇到任何问题。当我尝试将我的代码作为 jar 应用程序 (java -jar myApp.jar) 执行时,class 加载器无法正常工作。

详细地说,只有 getMethod() 方法在作为 jar 执行时以及仅当我使用自己的 class 作为参数时才能正常工作。

URL url = DAPBPropertyBuilder.class.getProtectionDomain().getCodeSource().getLocation().toURI().toURL();
URLClassLoader cl = URLClassLoader.newInstance(new URL[]{url});
Class<?>  c = cl.loadClass("my.path.to.class.Myclass);
Constructor constructor = c.getConstructor();
Object dapbBuilderInstance = constructor.newInstance();
Class[] cArg = new Class[4];
cArg[0] = java.lang.String.class;
cArg[1] = java.util.List.class;

//Here the curious part: When I add the MyDTO.class as parameter, it throws an java.lang.NoSuchMethodException. When I reduce this parameter, everything works fine (also when executing as JAR).
cArg[2] = MyDTO.class;
cArg[3] = java.util.Map.class;


//This is throwing an exception only when executed as JAR
java.lang.reflect.Method method = dapbBuilderInstance.getClass().getMethod("builder", cArg);

正如上面源代码中所写,我已经可以确定问题出在MyDTO.class参数上。当我减少 "builder" 方法中的参数以便此 class 不再是参数时,它工作正常。

我试图找出哪里可能不匹配并写了以下几行:

// Give me all methods you know.
Method[] m =  dapbBuilderInstance.getClass().getMethods();
for(int i =0; i<m.length;i++){
   System.out.println( "Found method: " +m[i].getName());
   //Found parameter:
   System.out.println("params: " + Arrays.toString( m[i].getParameterTypes()));
   //Used parameter for getMethod():
   System.out.println("params: " +Arrays.toString( cArg ));
}

此处输出:

MethodName: builder
param: [class java.lang.String, interface java.util.List, class my.path.to.class.MyDTO, interface java.util.Map]
param: [class java.lang.String, interface java.util.List, class my.path.to.class.MyDTO, interface java.util.Map]

因此,应该没问题,但我仍然遇到异常:

java.lang.NoSuchMethodException: my.path.to.class.MyClass.builder(java.lang.String, java.util.List, my.path.to.class.MyDTO, java.util.Map)
        at java.lang.Class.getMethod(Unknown Source)
       ...
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at javax.el.BeanELResolver.invoke(BeanELResolver.java:158)
        at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:79)
        at org.apache.el.parser.AstValue.getValue(AstValue.java:159)
        at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190)
        at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:115)
        at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:200)
        at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:187)
        at javax.faces.component.UIOutput.getValue(UIOutput.java:179)
        at javax.faces.component.UIInput.getValue(UIInput.java:311)
        at org.primefaces.util.ComponentUtils.getValueToRender(ComponentUtils.java:97)
        at org.primefaces.util.ComponentUtils.getValueToRender(ComponentUtils.java:61)
        at org.primefaces.extensions.component.codemirror.CodeMirrorRenderer.encodeMarkup(CodeMirrorRenderer.java:103)
        at org.primefaces.extensions.component.codemirror.CodeMirrorRenderer.encodeEnd(CodeMirrorRenderer.java:87)
        at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949)
        at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:91)
        at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:73)
        at org.primefaces.component.dialog.DialogRenderer.encodeContent(DialogRenderer.java:192)
        at org.primefaces.component.dialog.DialogRenderer.encodeMarkup(DialogRenderer.java:116)
        at org.primefaces.component.dialog.DialogRenderer.encodeEnd(DialogRenderer.java:48)
        at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912)
        at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1905)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)
        at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:491)
        at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:194)
        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:126)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:223)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:185)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:63)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Unknown Source)

也许你有一个想法,为什么Java在我使用MyDTOclass作为"builder"方法的参数时找不到方法,而java ] -jar MyApp.jar.

我有点没思路了。

谢谢!

约翰内斯找到了答案。

cArg[2] = cl.loadClass(DataSourceDescription.class.getName());

问题解决了。