Интерфейс не виден из ClassLoader при использовании прокси?

Я вижу следующее исключение, когда пытаюсь использовать динамический прокси

 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)

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
14
0
23 498
3

Ответы 3

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

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

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

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

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 ... 

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

У меня была такая же проблема с весенней загрузкой, я ее решаю, вводя ResourceLoader, получая его загрузчик классов.

@Autowired
private ResourceLoader resourceLoader;

....
ClassLoader classLoader = resourceLoader.getClassLoader();
...


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

Другие вопросы по теме