JNDI Нет приемника EJB, доступного для обработки

У меня проблема с моим EJBTest.

Я установил WildFly и настроил управление пользователями и приложениями.

Я написал EJB 3.0 и развернул его:

@Stateless
@Remote(NewSessionBeanRemote.class)
public class NewSessionBean implements NewSessionBeanRemote {

    List<String> bookShielf;

    /**
     * Default constructor. 
     */
    public NewSessionBean() {
        bookShielf = new ArrayList<String>();
    }

    @Override
    public void addBook(String bookName) {
        bookShielf.add(bookName);
    }

    @Override
    public List getBook() {
        return bookShielf;
    }
}

После этого я написал простой клиент для его подключения:

private static void invokeStatelessBean() throws NamingException {
    // Let's lookup the remote stateless calculator
    NewSessionBeanRemote remoteEjb = lookupRemoteSessionBean();
    System.out.println("Obtained a remote stateless calculator for invocation");
    String bookName = "TEST book";
    remoteEjb.addBook(bookName);
}

private static NewSessionBeanRemote lookupRemoteSessionBean() throws NamingException {

    final Hashtable jndiProperties = new Hashtable();
    jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
    jndiProperties.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:10090");
    jndiProperties.put(Context.SECURITY_PRINCIPAL, "ejb"); //this is the application user name, not management! it's correct?
    jndiProperties.put(Context.SECURITY_CREDENTIALS, "ejb");//this is the application password, not management! it's correct?
    jndiProperties.put("jboss.naming.client.ejb.context", true);
    final Context context = new InitialContext(jndiProperties);
    final String appName = "";
    final String moduleName = "EjbComponent";
    final String distinctName = "";
    final String beanName = NewSessionBean.class.getSimpleName();
    final String viewClassName = NewSessionBeanRemote.class.getName();
    System.out.println("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
    return (NewSessionBeanRemote) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
}

И имя пользователя, и пароль являются учетными данными пользователя приложения, а не управления! Это правильно?

Я получаю эту ошибку:

Исключение в потоке "main" java.lang.IllegalStateException: EJBCLIENT000025: нет приемника EJB, доступного для обработки комбинации [appName:, moduleName:EjbComponent, DifferentName:] для контекста вызова org.jboss.ejb.client.EJBClientInvocationContext@5034c75a в org.jboss .ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:798) в org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:128) в org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java) :186) в org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255) в org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200) в org.jboss.ejb.client. EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183) в org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146) в com.sun.proxy.$Proxy2.addBook(неизвестный источник) в com.studio.java.client.EjbTester.invokeStatelessBean(EjbTester.java:34) в com.studio.java.client.EjbTester.main(EjbTester.java:21)

Я не знаю почему! У кого-нибудь есть идея?


person reve    schedule 29.03.2016    source источник


Ответы (1)


Вы получаете указанную ошибку, потому что пытаетесь получить доступ к удаленному EJB, используя абсолютное имя JNDI.

Как указано в документации:

Клиент http-remoting предполагает, что имена JNDI в удаленном поиске относятся к пространству имен java:jboss/exported, поиск абсолютного имени JNDI завершится ошибкой.

Итак, после того как вы развернули свое приложение на WildFly, вы должны увидеть что-то вроде этого на консоли вашего сервера:

JNDI bindings for session bean named NewSessionBean in deployment unit deployment <your_deployment_unit> are as follows:

    java:global[/<application_name>]/<module_name>/<ejb_name>[!<interface_name>]
    java:app[/<module_name>]/<ejb_name>[!<interface_name>]
    java:module/<ejb_name>[!<interface_name>]
    java:jboss/exported[/<application_name>]/<module_name>/<ejb_name>[!<interface_name>]
    java:global/[/<application_name>]/<module_name>/<ejb_name>
    java:app[/<module_name>]/<ejb_name>
    java:module/<ejb_name>

Следовательно, принимая во внимание контекст java:jboss/exported, правильный способ получения вашего EJB должен быть следующим:

// Normally the appName is the EAR name
// Leave it empty if your application isn't packaged in a EAR
String appName = "your_application_name/";
// The EJB module name
String moduleName = "ejb_module_name/";
String beanName = NewSessionBean.class.getSimpleName();
String viewClassName = NewSessionBeanRemote.class.getName();

(NewSessionBeanRemote) context.lookup(appName + moduleName + beanName + "!" + viewClassName);

Для дальнейшего чтения я бы посоветовал вам также взглянуть на Java EE JNDI Syntax, а также Справочник по JNDI WildFly.

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

person aribeiro    schedule 30.03.2016
comment
Ok! большое спасибо Арибейро, но теперь я получаю java.lang.ClassCastException: org.jboss.ejb.client.naming.ejb.EjbNamingContext не может быть приведен к com.studio.java.NewSessionBeanRemote - person reve; 30.03.2016
comment
Как у вас дела с поиском? - person aribeiro; 30.03.2016
comment
всегда литой Исключение :( - person reve; 30.03.2016
comment
Я просил строку, которую вы используете в файле context.lookup. Что это такое? - person aribeiro; 30.03.2016
comment
я думаю, что поиск в порядке, но теперь у меня другая ошибка.. когда я пытаюсь найти эту строку: (NewSessionBeanRemote) context.lookup(ejb: + appName + + moduleName + + DifferentName + + beanName +! + viewClassName); - person reve; 30.03.2016
comment
Удалите ejb:, он вам не нужен. - person aribeiro; 30.03.2016
comment
Давайте продолжим обсуждение в чате. - person aribeiro; 30.03.2016
comment
большое спасибо @aribeiro, теперь я получаю: Не удалось подключиться к какому-либо серверу. Серверы пробовали: [http-remoting://127.0.0.1:10090 (java.io.IOException: Неизвестное имя службы)], но мое замечание: WFLYSRV0051: Консоль администратора прослушивает 127.0.0.1:10090 и HTTP-прослушиватель Undertow по умолчанию прослушивает 127.0.0.1:8180, если я изменю порт на 8180, я получу сообщение Нет приемника EJB, доступного для обработки - person reve; 30.03.2016
comment
@reve, если вы не изменили свой порт WildFly, по умолчанию это 8080. Следовательно, у вас должен быть jndiProperties.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080");. - person aribeiro; 30.03.2016
comment
Спасибо! решил это: EJBCLIENT000013: успешное рукопожатие версии завершено для контекста получателя EJBReceiverContext - person reve; 31.03.2016