【问题标题】:Java getMethod "class not found"Java getMethod“找不到类”
【发布时间】:2014-10-22 01:07:04
【问题描述】:

我有一个需要动态加载一些适配器的应用程序。其中一些适配器被编译到应用程序中,而另一些则在运行时提供。有了适配器后,我想调用它的 adapt(OrderToolRequest,Object) 方法。

我的问题是,当课程在应用程序中时,我可以让它工作。但是,对于第三方适配器,我可以动态加载运行时提供的类,但我不知道如何调用该方法。我在 OrderToolResponse 上收到“找不到类”错误。我试图通过让所有适配器实现接口和强制转换以及简单地使用反射来获取方法来做到这一点。

我假设这在某种程度上与不同的类加载器有关,但我没有足够的知识来解决这个问题。谁能指出我正确的方向?

在以下代码中,在调用 getMethod() 之前一切正常。如果我们在应用程序中找到该类,这将成功。如果类是由 URLClassLoader 加载的,则会抛出类未找到的错误

Class<?> cls = null;

try
{
    // #1
    cls = Class.forName( adapterName );
}
catch ( ClassNotFoundException e )
{
    File file = new File( "Adapters" );
    URL url = file.toURI().toURL();
    URL[] urls = new URL[]{ url };

    URLClassLoader loader = new URLClassLoader( urls );
    try
    {
        // #2
        cls = loader.loadClass( adapterName );
    }
    finally 
    {
        loader.close();
    }
}

Constructor<?> constructor = cls.getConstructor();
Object instance = constructor.newInstance();

// #3 THE PROBLEM OCCURS HERE.  SUCCEEDS IF LOADED BY #1, BUT FAILS IF LOADED
// BY #2.
Method adaptMethod = cls.getMethod( "adapt", OrderToolRequest.class, Object.class );

...invoke the method, etc.

编辑以更全面地解释

如果类是通过 Class.forName(adapterName) 语句加载的,则没有问题。

如果类是通过loader.loadClass(adapterName)加载的,那就有问题了。

如果我将代码更改为:

Method adaptMethod = null;
try
{
    adaptMethod = cls.getMethod( "adapt", OrderToolRequest.class, Object.class );
}
catch ( Error e )
{
    log.error( "Didn't work" );
}

并在日志语句上设置断点,然后:

  • e.cause = "ClassNotFoundException"
  • e.detailMessage = "com/ca/eai/model/canonical/OrderToolResponse"

编辑 #2 堆栈跟踪。我不得不截断超过 30,000 个字符

您会看到由 ClassNotFoundException 引起的 NoClassDefFoundError。

java.lang.NoClassDefFoundError: com/ca/eai/model/canonical/OrderToolResponse
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)
    at java.lang.Class.getMethod0(Class.java:2685)
    at java.lang.Class.getMethod(Class.java:1620)
    at com.ca.eai.esb.transformer.orchestration.AdapterInvokingTransformer.findAdapter(AdapterInvokingTransformer.java:73)
    at com.ca.eai.esb.transformer.orchestration.AdapterInvokingTransformer.transformMessage(AdapterInvokingTransformer.java:106)
    at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:145)
    at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:93)
    at org.mule.DefaultMuleMessage.transformMessage(DefaultMuleMessage.java:1455)
    at org.mule.DefaultMuleMessage.applyAllTransformers(DefaultMuleMessage.java:1363)
    at org.mule.DefaultMuleMessage.applyTransformers(DefaultMuleMessage.java:1341)
    at org.mule.DefaultMuleMessage.applyTransformers(DefaultMuleMessage.java:1333)
    at org.mule.transformer.AbstractTransformer.process(AbstractTransformer.java:123)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:95)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:70)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.doProcess(InterceptingChainLifecycleWrapper.java:54)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:70)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.access$001(InterceptingChainLifecycleWrapper.java:26)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper$1.process(InterceptingChainLifecycleWrapper.java:70)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.process(InterceptingChainLifecycleWrapper.java:65)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:95)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:70)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.doProcess(InterceptingChainLifecycleWrapper.java:54)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:70)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.access$001(InterceptingChainLifecycleWrapper.java:26)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper$1.process(InterceptingChainLifecycleWrapper.java:70)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.process(InterceptingChainLifecycleWrapper.java:65)
    at org.mule.routing.AbstractSelectiveRouter.processEventWithProcessor(AbstractSelectiveRouter.java:312)
    at org.mule.routing.AbstractSelectiveRouter.routeWithProcessors(AbstractSelectiveRouter.java:302)
    at org.mule.routing.AbstractSelectiveRouter.process(AbstractSelectiveRouter.java:202)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:95)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:70)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:106)
    at org.mule.interceptor.AbstractEnvelopeInterceptor.process(AbstractEnvelopeInterceptor.java:55)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:106)
    at org.mule.processor.AsyncInterceptingMessageProcessor.process(AsyncInterceptingMessageProcessor.java:101)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:95)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:70)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:106)
    at org.mule.interceptor.AbstractEnvelopeInterceptor.process(AbstractEnvelopeInterceptor.java:55)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:106)
    at org.mule.processor.AbstractFilteringMessageProcessor.process(AbstractFilteringMessageProcessor.java:44)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:106)
    at org.mule.construct.AbstractPipeline$1.process(AbstractPipeline.java:112)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:95)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:70)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.doProcess(InterceptingChainLifecycleWrapper.java:54)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:70)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.access$001(InterceptingChainLifecycleWrapper.java:26)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper$1.process(InterceptingChainLifecycleWrapper.java:70)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.process(InterceptingChainLifecycleWrapper.java:65)
    at org.mule.construct.Flow$1.process(Flow.java:74)
    at org.mule.construct.Flow$1.process(Flow.java:69)
    at org.mule.execution.ExecuteCallbackInterceptor.execute(ExecuteCallbackInterceptor.java:20)
    at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:34)
    at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:18)
    at org.mule.execution.BeginAndResolveTransactionInterceptor.execute(BeginAndResolveTransactionInterceptor.java:58)
    at org.mule.execution.SuspendXaTransactionInterceptor.execute(SuspendXaTransactionInterceptor.java:54)
    at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:32)
    at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:17)
    at org.mule.execution.ErrorHandlingExecutionTemplate.execute(ErrorHandlingExecutionTemplate.java:63)
    at org.mule.execution.ErrorHandlingExecutionTemplate.execute(ErrorHandlingExecutionTemplate.java:34)
    at org.mule.construct.Flow.process(Flow.java:68)
...SOME STUFF REMOVED HERE...
Caused by: java.lang.ClassNotFoundException: com.ca.eai.model.canonical.OrderToolResponse
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    ... 260 more

【问题讨论】:

  • 您的编译器如何知道 OrderToolRequest 是什么?它在构建文件中吗?
  • 它在一个 jar 中,位于通过 Maven 依赖项引入的类路径中。
  • Method getMethod(String name, Class<?>... parameterTypes) 怎么会抛出类未找到异常?
  • @A4L:如果没有找到参数类型。
  • @Ali C:注意我没有说它抛出异常;我说它抛出一个错误。尽管如此,我还是编辑了帖子以包含堆栈跟踪。

标签: java reflection classloader classnotfoundexception


【解决方案1】:

不要关闭加载器。 Javadoc:

关闭此 URLClassLoader,使其无法再用于加载 此加载器定义的新类或资源。

【讨论】:

  • URLClassLoader loader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader()); 将是我的下一个想法。不仅为 cls 类提供 URLClassLoader,还为系统类加载器提供。或getClass.getClassLoader().
  • 但是,这种想法确实使我找到了解决方法。通过更改为 URLClassLoader loader = new URLClassLoader( urls, OrderToolResponse.class.getClassLoader() );我让它工作了。
【解决方案2】:

没有看到我们试图检索的类或方法,但查看了您提供的异常原因,我不相信Class#getMethod 正在抛出 ClassNotFoundException。

相反,目标方法“adapt”的返回类型可能为 com.ca.eai.model.canonical.OrderToolResponse,并且该类不在类路径中。

【讨论】:

  • 嗯,该类与 OrderToolRequest 在同一个 jar 中。我可以插入“OrderToolResponse response = new OrderToolResponse();”行在这个函数中进入我的代码,它工作得很好。这是否与 URLClassLoader 在其路径之一中没有该 jar 的事实有关?
  • 尝试并没有什么坏处,但是按照您定义它的方式,URLClassLoader 应该委托给默认的类加载器,并且应该能够在类路径中找到东西。如果您使用 new URLClassLoader(urls, null) 实例化 URLClassLoader,它不会委托,那么我会期望这种行为......
  • URLClassLoader loader = new URLClassLoader( urls, OrderToolResponse.class.getClassLoader() );工作。
【解决方案3】:

如下构造 URL 加载器解决了我的问题。

URLClassLoader loader = new URLClassLoader( urls, OrderToolResponse.class.getClassLoader() );

我仍然不确定为什么默认的类加载器不工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 2012-08-19
    • 2011-12-01
    相关资源
    最近更新 更多