Интерфейс не виден из ClassLoader при использовании прокси? - PullRequest
13 голосов
/ 17 октября 2008

При попытке использовать динамический прокси появляется следующее исключение

 com.intellij.rt.execution.application.AppMain DynamicProxy.DynamicProxy
Exception in thread "main" java.lang.IllegalArgumentException: interface Interfaces.IPerson is not visible from class loader
    at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
    at DynamicProxy.Creator.getProxy(Creator.java:18)
    at DynamicProxy.DynamicProxy.main(DynamicProxy.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

Любая идея, что мне нужно сделать, чтобы ее решить

Ответы [ 2 ]

11 голосов
/ 14 ноября 2012

Если это веб-приложение, вам следует использовать загрузчик классов веб-приложения при создании динамического прокси. Так, например, вместо:

Proxy.newProxyInstance(
  ClassLoader.getSystemClassLoader(),
  new Class < ? >[] {MyInterface.class},
  new InvocationHandler() {
    // (...)
});

попробовать:

Proxy.newProxyInstance(
  this.getClass().getClassLoader(), // here is the trick
  new Class < ? >[] {MyInterface.class},
  new InvocationHandler() {
    // (...)
});

Например, иерархия загрузчиков классов tomcat (аналогичные имеют другие веб-контейнеры):

      Bootstrap
          |
       System
          |
       Common
       /     \
  Webapp1   Webapp2 ... 

И это загрузчик классов веб-приложения, который содержит классы и ресурсы в каталоге / WEB-INF / classes вашего веб-приложения, а также классы и ресурсы в файлах JAR в каталоге / WEB-INF / lib вашего веб-приложения.

5 голосов
/ 17 октября 2008

Когда ваш DynamicProxy пытается выполнить Class.forName(youInterfaceClass.getName()), результирующий экземпляр java.lang.Class отличается от того, который вы пропустили при создании прокси. Другими словами, у вас есть два объекта класса с одинаковым именем, и прокси не уверен, какой из них правильный (не имеет значения, одинаковы ли они).

Обычно это происходит, когда интерфейс, который вы пытаетесь использовать в качестве прокси-сервера, находится в библиотеке, загруженной через два разных загрузчика классов (то есть «общие» и «приложения» Tomcat).

Если это не поможет, пожалуйста, опубликуйте дополнительную информацию о вашем приложении, особенно если вы используете какой-либо сервер приложений, Spring или OSGi.

...