Java EE: Прокси не может быть преобразован в локальный интерфейс, возможно, проблема с загрузкой классов? - PullRequest
2 голосов
/ 02 ноября 2011

В настоящее время я "переставляю" свое приложение Java EE, которое состоит из трех компонентов:

  • MyAppInterface: в основном POJO с аннотациями JPA и JAXB, а также некоторые локальные интерфейсы EJB
  • MyAppServer: JPA Фасады, EJB, ресурсы Джерси
  • MyAppWeb: внешний интерфейс GWT, обменивается данными с MyAppServer через HTTP / REST через loadbalancer

И MyAppServer, и MyAppWeb используют классы, определенные в MyAfaceter;MyAppServer «экспортирует» некоторые из своих EJB-компонентов через локальные интерфейсы в MyAppInterface.MyAppInterface является своего рода API, это то, что вам нужно для работы с MyAppServer.

В Maven я упаковываю MyAppInterface как jar, и MyAppServer, и MyAppWeb упаковываются как war с зависимостью от MyAppInterface вcompile сфера.Таким образом, MyAppInterface.jar заканчивается в обоих war-файлах.

Когда я развертываю оба war-файла как отдельные приложения на одном Glassfish, развертывание проходит успешно.Связь между ними через JAXB-Jersey работает, поэтому я должен предположить, что оба приложения могут загружать MyAppInterface.

Но в одном случае я хотел бы получить доступ к MyAppServer-EJB из MyAppWeb.Поиск JNDI через InitialContext работает, но когда я пытаюсь привести полученный прокси к локальному интерфейсу, я получаю исключение ClassCast:

com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class: class com.skalio.bonusapp.web.server.StoreServiceImpl
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:315)
    at com.sun.enterprise.web.WebContainer.createServletInstance(WebContainer.java:717)
    at com.sun.enterprise.web.WebModule.createServletInstance(WebModule.java:1959)
...
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:307)
    ... 28 more
Caused by: java.lang.ClassCastException: $Proxy365 cannot be cast to com.skalio.bonusapp.beans.SettingsBeanLocal
    at com.skalio.bonusapp.web.server.StoreServiceImpl.getServerSettings(StoreServiceImpl.java:85)
    at com.skalio.bonusapp.web.server.StoreServiceImpl.(StoreServiceImpl.java:47)
    ... 33 more

Google заставляет меня поверить, что это может быть проблемой загрузки классов, возможно, связано с дублированием включения MyAppInterface.jar.Это верно?Что вы предлагаете делать?

Как бы вы распределили и упаковали компоненты?

Примечание. В настоящее время я бы хотел избежать создания EAR и сохранить гибкость выбора компонентов.развернуть где ...

1 Ответ

1 голос
/ 02 ноября 2011

Да, для локального EJB интерфейс JAR должен находиться в общем расположении для загрузки класса. Спецификация EJB фактически не требует, чтобы локальные EJB-компоненты были доступны через приложения (или автономные модули), но большинство серверов приложений реализуют локальный EJB-компонент с простыми прокси.

Вам либо нужно упаковать свои модули в EAR с JAR в каталоге lib, либо организовать загрузку JAR загрузчиком классов всего продукта, который виден обоим приложениям.

...