Я столкнулся со следующей проблемой поиска 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
У меня вопрос
- почему "java: comp / env" больше не является контекстом по умолчанию, а "java:",
почему поиск "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.
Спасибо