2014-10-21 2 views
2

У меня есть приложение, которое должно динамически загружать некоторые адаптеры. Некоторые из этих адаптеров скомпилированы в приложение, а некоторые - во время выполнения. Как только у меня есть адаптер, я хочу вызвать метод адаптации (OrderToolRequest, Object) на нем.Java getMethod "class not found"

Моя проблема в том, что я могу заставить это работать, когда класс находится в приложении. Однако для сторонних адаптеров я могу динамически загружать класс, поставляемый во время выполнения, но я не могу понять, как вызвать этот метод. Я получаю ошибки «class not found» в 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. 

EDIT, чтобы объяснить более полно

Если класс загружается заявление Class.forName (adapterName), то нет проблем.

Если класс загружен loader.loadClass (имя_адаптера), тогда возникает проблема.

Если я изменить код следующим образом:

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 символов.

Вы увидите NoClassDefFoundError, вызванное ClassNotFoundException.

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 
+0

Как ваш компилятор знает, что такое OrderToolRequest? Это в файле сборки? – kmac

+0

Это в банке, которая находится в пути класса, введенном через зависимость от Maven. – Tad

+0

Как можно [метод getMethod (имя строки, класс ... parameterTypes)] (http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getMethod-java.lang .String-java.lang.Class ...-) выбросить исключение класса не найденное? – A4L

ответ

1

Не закрывайте погрузчик. Javadoc:

Закрывает URLClassLoader, так что он больше не может быть использован для загрузки новых классов или ресурсов, которые определены этим загрузчиком.

+0

Не этот класс уже загружен? – Brandon

+0

@Joop: Я пробовал это. Это не решило проблему. – Tad

+0

'URLClassLoader loader = new URLClassLoader (urls, ClassLoader.getSystemClassLoader());' была бы моей следующей идеей. Предоставление класса cls не только URLClassLoader, но и загрузчика системного класса. Или 'getClass.getClassLoader()'. –

0

Не видя класс или метод, который мы пытаемся получить, но, глядя на исключение причины вы предоставили, я не верю, что Class#getMethod бросает ClassNotFoundException.

Вместо этого у целевого метода «адаптация», вероятно, есть тип возврата com.ca.eai.model.canonical.OrderToolResponse, и этот класс не находится в пути к классам.

+0

Хммм, этот класс находится в тот же банку, что и OrderToolRequest.Я могу вставить строку «OrderToolResponse response = new OrderToolResponse();» в свой код в этой функции, и она отлично работает. Связано ли это с тем, что URLClassLoader не имеет этой банки в один из его путей? – Tad

+0

Не больно попробовать, но с тем, как вы определили его, URLClassLoader должен делегировать загрузчику по умолчанию, и он должен найти что-то в пути к классам. Если бы вы создали экземпляр URLClassLoader с помощью нового URLClassLoader (URL-адреса , null), он не будет делегировать, тогда я ожидал бы такого поведения ... –

+0

URLClassLoader loader = new URLClassLoader (urls, OrderToolResponse.class.getClass Loader()); работал. – Tad

0

Построение загрузчика URL следующим образом решает мою проблему.

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

Я все еще не уверен, почему загрузчик класса по умолчанию не работает.