Jboss AS 6 - Как найти EJB через JNDI - PullRequest
2 голосов
/ 20 декабря 2011

Я пробую простой EJB 2.1 HelloWorld, используя Jboss AS 6. Я создал файл EJB jar со следующей структурой:

HelloWorldEjb
    |-ex1
        |-ejb21
            |-ejb.jar.xml
            |-Hello.java
            |-HelloBean.java
            |-HelloHome.java
            |-HelloLocal.java
            |-HelloLocalHome.java

Я также создал клиентский автономный класс java для тестирования вышеуказанного ejb. Я развернул файл jar с помощью консоли администратора Jboss 6 в разделе «Приложения> EJB2 jars» и нажал «Добавить новый ресурс». Когда я добавляю jar-файл, он дает мне это сообщение, поэтому я предполагаю, что он был правильно развернут.

Resource HelloWorldEjb.jar created successfully! 

Теперь, когда я запускаю клиент, я получаю эту ошибку:

log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
javax.naming.NameNotFoundException: HelloHome not bound
    at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
    at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
    at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
    at org.jnp.server.NamingServer.lookup(NamingServer.java:443)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
    at java.lang.Thread.run(Thread.java:619)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
    at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)
    at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728)
    at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at client.HelloClient.main(HelloClient.java:58)
Exception in thread "main" java.lang.NullPointerException
    at client.HelloClient.main(HelloClient.java:72)

Первоначально я подумал, что мне нужно настроить ресурс JNDI, для которого клиент будет использовать соединение для поиска EJB на сервере приложений. Это не обязательно? Пример, который я использую, использует имя EJB в операторе поиска. Вот раздел кода клиента для установления соединения. :

    Properties env = new Properties();

env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory" );
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
env.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");

    //env = new InitialContext(env);

InitialContext ctx = null;

try {
    ctx = new InitialContext(env);
} catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}       

Object obj = null;

try {
    obj = ctx.lookup("HelloHome");
} catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

HelloHome home = (HelloHome) javax.rmi.PortableRemoteObject.narrow(obj, HelloHome.class);

А вот содержимое файла ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instalce"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
    version="2.1">

    <enterprise-beans>
        <session>
            <ejb-name>HelloWorldEJB</ejb-name>
            <home>ex1.ejb21.HelloHome</home>
            <remote>ex1.ejb21.Hello</remote>
            <local-home>ex1.ejb21.HelloLocalHome</local-home>
            <local>ex1.ejb21.HelloLocal</local>
            <ejb-class>ex1.ejb21.HelloBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>
        </session>  
    </enterprise-beans>

</ejb-jar>

Одна вещь, которая мне показалась интересной, это то, что когда я компилировал клиентский класс, он отказывался компилироваться, если у него не было ссылки на класс HelloHome. Для решения этой проблемы мне пришлось добавить файл ejb jar в classpath класса клиента. Это как это должно работать? файл ejb jar должен находиться на пути к классам клиента?

В терминах имени jndi, используемого для поиска, мне нужно создать новое имя? В приведенном выше примере, похоже, имя EJB используется в качестве поиска.

Редактировать

В настоящее время я изучаю книгу об EJB 3.0. Часть введения в EBJ 3.0 состоит в том, чтобы познакомить меня с вариантом 2.0, поэтому я и пробую этот пример. Я думаю, что имеет смысл хотя бы немного понять, как они работают, даже если я не планирую использовать EJB2.

Я посмотрел на консоль список развернутых приложений и не вижу свое приложение в пункте меню EJB2.0. Я думаю, это означает, что файл JAR не был правильно развернут. Журналы Jboss показывают, что он был развернут (см. 4-ю строку ниже).

16:36:50,982 INFO  [org.rhq.core.pc.PluginContainer] Plugin Container initialized.
16:36:50,987 INFO  [org.jboss.on.embedded.manager.pc.PluginContainerResourceManager] Discovering Resources...
16:36:50,988 INFO  [org.rhq.core.pc.inventory.AutoDiscoveryExecutor] Executing server discovery scan...
16:36:53,920 INFO  [org.rhq.core.pc.inventory.InventoryManager] Detected new Server [Resource[id=-3, type=JBossAS Server, key=C:\bin\appservers\jboss-6.1.0.Final\server\default, name=JBoss AS 6 (default), parent=<null>, version=6.1.0.Final]] - adding to local inventory...
16:36:54,032 INFO  [org.rhq.core.pc.inventory.AutoDiscoveryExecutor] Found 0 servers.
16:36:54,032 INFO  [org.rhq.core.pc.inventory.RuntimeDiscoveryExecutor] Running runtime discovery scan rooted at [platform]
16:36:54,093 INFO  [org.rhq.core.pc.inventory.InventoryManager] Detected new Server [Resource[id=-4, type=JBoss AS JVM, key=JVM, name=JVM, parent=<null>, version=1.6.0_07]] - adding to local inventory...
16:36:54,097 INFO  [org.rhq.plugins.jmx.JMXServerComponent] Starting connection to JMX Server JVM
16:36:54,695 INFO  [org.rhq.core.pc.inventory.RuntimeDiscoveryExecutor] Scanned [0] servers and found [0] total descendant Resources.

Есть что-то, что выглядит неправильно в структуре, которую я описал выше?

Редактировать

Хорошо, мне удалось решить эту проблему с помощью комментариев от richj. Похоже, у меня был файл ejb-jar.xml в неправильном месте. Он должен был находиться в папке META-INF. Я скопировал его из ext1 / ejb21 в / META-INF, и jboss поднял файл jar.

17:21:44,376 INFO  [org.rhq.core.pc.inventory.RuntimeDiscoveryExecutor] Scanned [0] servers and found [0] total descendant Resources.
17:21:45,301 INFO  [org.jboss.ejb.plugins.local.BaseLocalProxyFactory] Unbind EJB LocalHome 'HelloWorldEJB' from jndi 'local/HelloWorldEJB@21777607'
17:21:45,349 INFO  [org.jboss.proxy.ejb.ProxyFactory] Unbind EJB Home 'HelloWorldEJB' from jndi 'HelloWorldEJB'
17:21:45,358 INFO  [org.jboss.ejb.EjbModule] Undeployed HelloWorldEJB
17:21:45,437 INFO  [org.jboss.ejb.deployers.EjbDeployer] installing bean: ejb/#HelloWorldEJB,uid10624357
17:21:45,438 INFO  [org.jboss.ejb.deployers.EjbDeployer]   with dependencies:
17:21:45,439 INFO  [org.jboss.ejb.deployers.EjbDeployer]   and supplies:
17:21:45,440 INFO  [org.jboss.ejb.deployers.EjbDeployer]        jndi:HelloWorldEJB/ex1.ejb21.Hello
17:21:45,441 INFO  [org.jboss.ejb.deployers.EjbDeployer]        jndi:local/HelloWorldEJB@28622485
17:21:45,442 INFO  [org.jboss.ejb.deployers.EjbDeployer]        jndi:HelloWorldEJB/ex1.ejb21.HelloLocal
17:21:45,443 INFO  [org.jboss.ejb.deployers.EjbDeployer]        jndi:HelloWorldEJB
17:21:45,466 INFO  [org.jboss.ejb.EjbModule] Deploying HelloWorldEJB
17:21:45,495 INFO  [org.jboss.ejb.plugins.local.BaseLocalProxyFactory] Bound EJB LocalHome 'HelloWorldEJB' to jndi 'local/HelloWorldEJB@28622485'
17:21:45,503 INFO  [org.jboss.proxy.ejb.ProxyFactory] Bound EJB Home 'HelloWorldEJB' to jndi 'HelloWorldEJB'

Я также внес небольшое изменение в файл xml, поскольку в используемых пространствах имен произошла опечатка.

Я использовал HelloWorldEJB в качестве имени jndi для клиента, и это, наконец, сработало.

Спасибо.

1 Ответ

4 голосов
/ 20 декабря 2011

Я думаю, что ваше исключение означает либо:

  • код клиента использует неверное имя для поиска EJB, или ...
  • EJB не зарегистрирован в JNDI

Это работает?

obj = ctx.lookup("HelloHomeEJB");

Можно определить имя JNDI для удаленного дома, используя тег (и имя JNDI для локального дома, используя тег .)

Это как это должно работать? т.е. файл ejb jar должен быть на пути к классам клиента?

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

Редактировать - файл JAR не развернут

Когда EJB развернут, в файл журнала должно быть записано что-то подобное:

18:49:33,979 INFO  [EjbDeployer] installing bean: ejb/helloworld-ejb.jar#HelloWorld,uid181111540
18:49:33,979 INFO  [EjbDeployer]   with dependencies:
18:49:33,980 INFO  [EjbDeployer]   and supplies:
18:49:33,980 INFO  [EjbDeployer]        jndi:HelloWorldLocal
18:49:33,980 INFO  [EjbDeployer]        jndi:HelloWorld

Обычный способ развертывания EJB-файла JAR - это перетаскивание его в каталог развертывания используемого вами сервера (будьте осторожны, стандартная установка JBoss обычно предоставляет более одной конфигурации сервера.) В моей системе каталог развертывания это:

/usr/local/jboss/server/default/deploy

Иногда несколько файлов jar упакованы в файл ear. Метод развертывания такой же, но файл jar должен быть указан в дескрипторе развертывания META-INF / application.xml файла ear.

...