Проблема JNDI / Classpath в Glassfish

Я нахожусь в процессе преобразования большого приложения J2EE (называемого ниже AeApp) из EJB 2 в EJB 3 (все сессионные bean-компоненты без сохранения состояния, с использованием Glassfish 2.1.1), и у меня заканчиваются идеи.

Первый преобразованный мной EJB (назовем его Foo) работал без серьезных проблем (он был единственным в своем модуле ejb, и я мог полностью заменить дескриптор развертывания аннотациями), и приложение работало нормально. Но после преобразования второго (назовем его Bar, одного из нескольких в другом ejb-модуле) возникает странная комбинация проблем:

  • AeApp развертывается без ошибок (в логах тоже ничего). В журнале я получаю сообщения инициализации как для Foo, так и для Bar, но дальнейшие сообщения о разрешениях методов и имени JNDI только для Foo:

    [#|2010-05-10T12:26:13.234+0200|FINE|sun-appserver2.1|javax.enterprise.system.core.security|_ThreadID=25;_ThreadName=Thread-2821;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=initialize;_RequestID=1801c4ff-90fe-4406-aaac-219c669be8c1;|Codebase (module id for ejb Foo) = null|#]
    [#|2010-05-10T12:26:11.625+0200|FINE|sun-appserver2.1|javax.enterprise.system.core.security|_ThreadID=25;_ThreadName=Thread-2821;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=initialize;_RequestID=1801c4ff-90fe-4406-aaac-219c669be8c1;|Codebase (module id for ejb Bar) = null|#]
    [#|2010-05-10T12:26:13.234+0200|FINE|sun-appserver2.1|javax.enterprise.system.core.security|_ThreadID=25;_ThreadName=Thread-2821;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=fooMethod;_RequestID=1801c4ff-90fe-4406-aaac-219c669be8c1;|JACC DD conversion: EJBMethodPermission ->(Foo fooMethod,Remote,java.lang.Long,java.util.Locale)protected by role -> FOOUSER|#]
    [#|2010-05-10T12:26:19.312+0200|INFO|sun-appserver2.1|javax.enterprise.system.container.ejb|_ThreadID=17;_ThreadName=httpWorkerThread-14848-1;|**RemoteBusinessJndiName: com.example.Foo; remoteBusIntf: com.example.Foo|#]
    
  • Ошибка при поиске Bar через JNDI

  • При просмотре дерева JNDI в административной консоли Glassfish Bar вообще отсутствует.
  • Другие EJB в том же модуле появляются, как и Foo.
  • В журналах есть исключения, касающиеся Foo, но они уже появились, когда он еще работал.

Есть идеи, что могло вызвать это или как диагностировать это дальше? Бобы довольно просты:

@Stateless(name = "Foo")
@RolesAllowed("FOOUSER")
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class FooImpl extends BaseBean implements Foo {

У меня также есть некоторые проблемы с дескриптором развертывания для Bar: я бы хотел его устранить, но Glassfish, похоже, не любит, когда bean-компонент отображается только в sun-ejb-jar.xml или имеет некоторые beans в модуль, объявленный в дескрипторе, и другие используют только аннотации.

Изменить: EAR имеет такую ​​структуру:

AeApp.ear
    AeApp.war
    Foo.jar (Foo.class and FooImpl.class present here)
    Bar.jar (Bar.class and BarImpl.class present here, also BaseBean.class)
    (some more EJB module JARs)
    (lots of library JARs)

AeApp.ear не имеет (и у AFAIK никогда не было, даже когда он работал) META-INF / MANIFEST.MF. Его application.xml выглядит так:

<application>
  <description>AE EAR</description>
  <display-name>AE EAR</display-name>
  <module><ejb>Foo.jar</ejb></module>
  <module><ejb>Bar.jar</ejb></module>
  <module><ejb>Baz.jar</ejb></module>
  <module><ejb>Doh.jar</ejb></module>
  <module><web>
      <web-uri>AeApp.war</web-uri>
      <context-root>/</context-root>
  </web></module>
</application>

person Michael Borgwardt    schedule 06.05.2010    source источник
comment
Можете ли вы показать структуру вашего уха? Где пропал класс XXX? Можете ли вы предоставить анонимную версию вашего EAR для воспроизведения?   -  person Pascal Thivent    schedule 09.05.2010
comment
@Pascal: Я добавил некоторую информацию о структуре EAR. XXX был артефактом анонимности, он должен был быть Foo, который присутствует в JAR. Я не думаю, что смогу опубликовать EAR, так как это очень большое коммерчески разработанное приложение - анонимизировать его при сохранении всего, что может быть актуально, было бы более или менее невозможно.   -  person Michael Borgwardt    schedule 10.05.2010
comment
FooImpl расширяет BaseBean. Как добавить BaseBean.class в путь к классам Foo?   -  person Chris Lercher    schedule 10.05.2010
comment
@chris_l: Я почти уверен, что теперь эти исключения были отвлекающим маневром и убрали их из вопроса; Я обнаружил, что они уже появились после того, как Foo был преобразован в EJB 3, и приложение работало нормально.   -  person Michael Borgwardt    schedule 10.05.2010


Ответы (2)


После некоторых проб и ошибок я сузил проблему, и коллега направил меня на верный путь. Проблема заключалась не в путях к классам или самих EJB. Это было намного глупее.

В моем ejb-jar.xml был EJBv2 DOCTYPE. Это привело к тому, что glassfish молча игнорировал EJB, используя только аннотации, и не мог поместить их в дерево JNDI, когда они были объявлены в дескрипторе развертывания. Все, что мне нужно было сделать, это заменить это:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar
<?xml version="1.0" encoding="UTF-8"?>
     <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                                  http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
0.dtd"> <ejb-jar>

С этим:

<?xml version="1.0" encoding="UTF-8"?>
     <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                                  http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
person Michael Borgwardt    schedule 10.05.2010

Я не видел точных сообщений об ошибках, которые вы публиковали раньше, но они кажутся мне так, как будто "foo-ejb.jar" отсутствует в атрибуте META-INF / MANIFEST.MF Class-Path бара. Можно скомпилировать bar, используя другие средства для помещения Foo в его путь к классам, но это не сработает при запуске приложения.

Но я согласен с Паскалем, нам действительно может понадобиться дополнительная информация о структуре вашего проекта. Очень краткое описание (или, может быть, диаграмма) о том, какие jar-файлы у вас есть, какие из соответствующих классов (Foo / Bar / FooImpl / BaseBean / ..) находятся в каком jar, как они связаны + их аннотации, вероятно, будет достаточно.

person Chris Lercher    schedule 09.05.2010
comment
В манифесте действительно нет пути к классу, но его никогда не было, даже когда приложение все еще работало. Возможно ли, что это станет необходимым при использовании EJB-компонентов на основе аннотаций? - person Michael Borgwardt; 10.05.2010
comment
@ Майкл: Я не уверен, но это возможно. Приложения EJB 2, которые у меня были, всегда состояли из одного модуля ejb (и я, честно говоря, не помню всех деталей развертывания, это было слишком давно). Для своих приложений EJB 3.1 я всегда использую атрибут Class-Path МАНИФЕСТА - насколько я понимаю, это стандартный механизм для зависимостей модулей JavaEE, и без него он не будет работать. - person Chris Lercher; 10.05.2010
comment
Я подозреваю, что ClassNotFoundError - отвлекающий маневр или, по крайней мере, симптом настоящей проблемы, а не ее причины, поскольку он возникает только при отображении дерева JNDI, в то время как EJB Foo фактически обнаруживается и инициализируется при развертывании приложения (см. Добавленное записывать сообщения в вопросе); настоящая проблема в том, что Bar EJB - нет. - person Michael Borgwardt; 10.05.2010