Хобрук: Ваш путь к мастерству в программировании

Миграция локального клиента EJB с JBoss 6 на Wildfly 10

Я столкнулся со следующей проблемой поиска JNDI при получении ссылки на сессионный компонент в устаревшем приложении во время миграции с JBoss 6 на WildFly 10.

Следующий код, который работает в JBoss 6, получает ссылку на сессионный компонент «OMGenEJB», который затем используется для получения прокси-объекта «genhome» для взаимодействия с этим bean-компонентом.

    try {
        InitialContext ic = new InitialContext();
        Object objRef = ic.lookup("ejb/OMGenEJB");
        OMGenEJBHome genhome = 
          (OMGenEJBHome) PortableRemoteObject.narrow ( objRef, OMGenEJBHome.class );

...

Домашний интерфейс EJB - это OMGenEJBHome.

Класс реализации EJB - OMGenBean.

Компонент определяется в "ejb-jar.xml" следующим образом:

  <session >
     <ejb-name>OMGenEJB</ejb-name>
     <home>com.irisel.oms.ejb.interfaces.OMGenEJBHome</home>
     <remote>com.irisel.oms.ejb.interfaces.OMGenEJB</remote>
     <service-endpoint>com.irisel.oms.ws.OMBrowserEndpoint</service-endpoint>
     <ejb-class>com.irisel.oms.ejb.browser.OMGenBean</ejb-class>
     <session-type>Stateless</session-type>
     <transaction-type>Bean</transaction-type>
  </session>

Теперь клиентский класс принадлежит WAR, который находится в том же EAR, что и JAR-файл EJB.

EAR развернут правильно, и сервер при запуске регистрирует следующие записи JNDI:

21:39:18,770 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-3) WFLYEJB0473: JNDI bindings for session bean named 'OMGenEJB' in deployment unit 'subdeployment "HolmesEJB-2.0.jar" of deployment "HolmesBSS-2.0.ear"' are as follows:

java:global/HolmesBSS-2.0/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJB
java:app/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJB
java:module/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJB
java:jboss/exported/HolmesBSS-2.0/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJB
java:global/HolmesBSS-2.0/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.browser.OMGenBean
java:app/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.browser.OMGenBean
java:module/OMGenEJB!com.irisel.oms.ejb.browser.OMGenBean
java:global/HolmesBSS-2.0/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJBHome
java:app/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJBHome
java:module/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJBHome
java:jboss/exported/HolmesBSS-2.0/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJBHome

Ниже приведена модификация для печати записей JNDI, как видно на клиенте, как в начальном контексте, так и в «java: comp / env».

protected void init2(Credentials creds) throws SQLException, ConfigException, RemoteException {

    logger = org.apache.log4j.Logger.getLogger(this.getClass());

    try {

        logger.info("Connecting to ejb/OMGenEJB");

        InitialContext ic = new InitialContext();

        // this code lists the entries in the initial context
        NamingEnumeration<NameClassPair> list = ic.list("");
        while (list.hasMore()) {
          System.out.println(list.next().getName());
        }


        Context envCtx = (Context)ic.lookup("java:comp/env");

        // this code lists the entries in java:comp/env context
        list = envCtx.list("");
        while (list.hasMore()) {
              System.out.println(list.next().getName());
        }

        Object objRef2 = envCtx.lookup("ejb/OMGenEJB");

        logger.info("Narrowing to class OMGenEJBHome #"+OMGenEJBHome.class.hashCode());
        OMGenEJBHome genhome = (OMGenEJBHome)PortableRemoteObject.narrow(objRef2, OMGenEJBHome.class);

...

Измененный код создает эти журналы:

23:23:43,445 INFO  [com.irisel.oms.olapi.CLEJBBrowser] (default task-16) Connecting to ejb/OMGenEJB
23:23:44,274 INFO  [stdout] (default task-16) Mail

23:23:44,669 INFO  [stdout] (default task-16) TransactionManager

Оказывается, исходным контекстом является «java:», потому что Mail и TransactionManager имеют имена JNDI «java: / Mail» и «java: / TransactionManager» соответственно. Однако я бы ожидал, что относительный путь будет относительно java: comp / env.

Рядом с этим мы видим запись «ejb»:

23:23:46,163 INFO  [stdout] (default task-16) com.irisel.oms.ws.server.KnockKnockImpl

23:23:46,789 INFO  [stdout] (default task-16) ejb

23:23:50,146 INFO  [stdout] (default task-16) com.irisel.oms.ws.server.HolmesImpl

У меня вопрос

  1. почему "java: comp / env" больше не является контекстом по умолчанию, а "java:",
  2. почему поиск "ejb / OMGenEJB" также не выполняется в коде изменения

    23: 23: 51,680 ИНФОРМАЦИЯ [stdout] (задача по умолчанию-16) Исключение: WFLYNAM0062: Не удалось найти env / ejb / OMGenEJB

Если вместо этого мы попытаемся найти "ejb", поиск будет работать нормально.

Так что я тоже попробовал:

    try {
        logger.info("Connecting to ejb/OMGenEJB");
        InitialContext ic = new InitialContext();
        NamingEnumeration<NameClassPair> list = ic.list("");
        while (list.hasMore()) {
          System.out.println("ic entry:"+list.next().getName());
        }
        Context envCtx = (Context)ic.lookup("java:comp/env/ejb");
        list = envCtx.list("");
        while (list.hasMore()) {
              System.out.println("envCtx entry:"+list.next().getName());
        }
        Object objRef2 = envCtx.lookup("OMGenEJB");
        logger.info("Narrowing to class OMGenEJBHome #"+OMGenEJBHome.class.hashCode());
        OMGenEJBHome genhome = (OMGenEJBHome)PortableRemoteObject.narrow(objRef2, OMGenEJBHome.class);

        //browser = genhome.create();
        //className = browser.getClassNames();

        genejb = genhome.create();
        appvo = (AppVO) AppVO.readObject64(this.genejb.exec("getApp",null,null));

    } catch (Exception ex) {
        System.out.println("Exception :"+ ex.getMessage());
        ConfigException ce = new ConfigException("Cannot initialize remote EJB client");
        ce.initCause(ex);
        throw ce;
    } 

Что производит эти журналы:

00:35:52,048 INFO  [com.irisel.oms.olapi.CLEJBBrowser] (default task-2) Connecting to ejb/OMGenEJB
00:35:52,823 INFO  [stdout] (default task-2) ic entry:Mail

00:35:53,123 INFO  [stdout] (default task-2) ic entry:TransactionManager

00:35:53,992 INFO  [stdout] (default task-2) envCtx entry:OMBrowserEJB

00:35:54,314 INFO  [stdout] (default task-2) envCtx entry:OMGenEJB

00:36:25,649 INFO  [stdout] (default task-2) Exception :WFLYNAM0062: Failed to lookup env/ejb/OMGenEJB

00:36:25,650 ERROR [stderr] (default task-2) com.irisel.util.ConfigException: Cannot initialize remote EJB client

00:36:25,650 ERROR [stderr] (default task-2)    at com.irisel.oms.olapi.CLEJBBrowser.init2(CLEJBBrowser.java:82)
...
00:36:25,671 ERROR [stderr] (default task-2) Caused by: javax.naming.NamingException: WFLYNAM0062: Failed to lookup env/ejb/OMGenEJB [Root exception is java.lang.RuntimeException: javax.naming.NameNotFoundException: ejb/OMGenEJB -- service jboss.naming.context.java.ejb.OMGenEJB]

00:36:25,671 ERROR [stderr] (default task-2)    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:157)

... ... 39 more

00:36:25,672 ERROR [stderr] (default task-2) Caused by: java.lang.RuntimeException: javax.naming.NameNotFoundException: ejb/OMGenEJB -- service jboss.naming.context.java.ejb.OMGenEJB

00:36:25,672 ERROR [stderr] (default task-2)    at org.jboss.as.ejb3.deployment.processors.EjbLookupInjectionSource$1.getReference(EjbLookupInjectionSource.java:99)

00:36:25,672 ERROR [stderr] (default task-2)    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:143)

00:36:25,676 ERROR [stderr] (default task-2)    ... 44 more

00:36:25,676 ERROR [stderr] (default task-2) Caused by: javax.naming.NameNotFoundException: ejb/OMGenEJB -- service jboss.naming.context.java.ejb.OMGenEJB

00:36:25,676 ERROR [stderr] (default task-2)    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:106)

00:36:25,677 ERROR [stderr] (default task-2)    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)

00:36:25,677 ERROR [stderr] (default task-2)    at org.jboss.as.naming.InitialContext$DefaultInitialContext.lookup(InitialContext.java:235)

00:36:25,677 ERROR [stderr] (default task-2)    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)

00:36:25,677 ERROR [stderr] (default task-2)    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)

00:36:25,677 ERROR [stderr] (default task-2)    at javax.naming.InitialContext.lookup(InitialContext.java:417)

00:36:25,677 ERROR [stderr] (default task-2)    at javax.naming.InitialContext.lookup(InitialContext.java:417)

00:36:25,677 ERROR [stderr] (default task-2)    at org.jboss.as.ejb3.deployment.processors.EjbLookupInjectionSource$1.getReference(EjbLookupInjectionSource.java:81)

00:36:25,677 ERROR [stderr] (default task-2)    ... 45 more

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

"java:global/HolmesBSS-2.0/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJBHome"
"java:app/HolmesEJB-2.0/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJBHome"

Эти не работают

"java:module/OMGenEJB!com.irisel.oms.ejb.browser.OMGenBean"
"java:module/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJBHome"
"java:comp/env/ejb/OMGenEJB"

Я хотел бы узнать у вас, соответствует ли это требованиям спецификации Java-7.

Спасибо


Ответы:


1

Переносимое имя JNDI для Java EE 7 имеет вид:

java:global/<app-name>/<module-name>/<bean-name>!<fully-qualified-bean-interface-name>

Имя приложения по умолчанию - это имя уха без расширения (.ear). Вы можете установить имя приложения в application.xml

<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
    <application-name>myApp</application-name>
</application>

Имя модуля по умолчанию - это имя ejb-jar без расширения (.jar). Вы можете изменить его в файле ejb-jar.xml.

<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee" 
         version = "3.1"
         xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
    <module-name>myModule</module-name>
</ejb-jar>

Итак, результат:

java:global/myApp/myModule/OMGenEJB!com.irisel.oms.ejb.interfaces.OMGenEJBHome

Примечание: вы не можете использовать mappedName в ejb-jar.xml для привязки к другому имени JNDI, поскольку Wildfly не позволяет этого. Wildfly разрешает только вышеупомянутую форму.

05.07.2016
Новые материалы

Шлюз с лицензией OSS, совместимый с Apollo Federation v2, появится в WunderGraph
Сегодня мы рады сообщить, что мы сотрудничаем с поддерживаемой YC Tailor Technologies, Inc. для внедрения Apollo Federation v2. Реализация будет лицензирована MIT (Engine) и Apache 2.0..

Это оно
Ну, я официально уволился с работы! На этой неделе я буду лихорадочно выполнять последние требования Думающего , чтобы я мог сосредоточиться на поиске работы. Что именно это значит?..

7 полезных библиотек JavaScript, которые вы должны использовать в своем следующем проекте
Усильте свою разработку JavaScript Есть поговорка «Не нужно изобретать велосипед». Библиотеки — лучший тому пример. Это поможет вам написать сложные и трудоемкие функции простым способом...

Базовое руководство по переносу концепций обучения в глубокое обучение
Обзор По мере того, как машинное обучение становится все более мощным и продвинутым, модели, обеспечивающие эту расширенную возможность, становятся все больше и начинают требовать огромного..

C в C.R.U.D с использованием React-Redux
Если вы использовали React, возможно, вы знакомы с головной болью, связанной с обратным потоком данных. Передача состояния реквизитам от родительских компонентов к дочерним компонентам может..

5 обязательных элементов современного инструмента конвейера данных
В цифровом мире предприятия используют конвейеры данных для перемещения, преобразования и хранения огромных объемов данных. Эти конвейеры составляют основу бизнес-аналитики и играют..

Случай использования npm3 вместо npm2 для разработки библиотеки
Некоторое время назад я создал библиотеку на NodeJS, чтобы упростить рендеринг на стороне сервера и клиента. Он использует React и React Router для отображения соответствующего HTML на веб-сайте...