2

I have a problem with my EJBTest.

I have installed WildFly and configured user management and application management.

I wrote an EJB 3.0 and deployed it:

@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;
    }
}

Afterwards, I wrote a simple client to connect it:

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);
}

Both username and password are the application user credential, not management! Is it correct?

I'm receiving this error:

Exception in thread "main" java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:, moduleName:EjbComponent, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@5034c75a at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:798) at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:128) at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186) at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255) at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200) at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183) at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146) at com.sun.proxy.$Proxy2.addBook(Unknown Source) at com.studio.java.client.EjbTester.invokeStatelessBean(EjbTester.java:34) at com.studio.java.client.EjbTester.main(EjbTester.java:21)

I don't know why! Anyone have an idea?

António Ribeiro
  • 4,129
  • 5
  • 32
  • 49
reve
  • 99
  • 1
  • 9

1 Answers1

5

You're receiving the mentioned error because you're trying to access a remote EJB using the absolute JNDI name.

As stated by the documentation:

The http-remoting client assumes JNDI names in remote lookups are relative to java:jboss/exported namespace, a lookup of an absolute JNDI name will fail.

So, after you've deployed your application on WildFly, you should see something like this on your server console:

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>

Therefore, taking into account the java:jboss/exported context, the correct way of attaining your EJB should be:

// 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);

For further reading, I'd suggest you also to take a look at the Java EE JNDI Syntax as well as to WildFly's JNDI Reference.

Regarding your credentials, they're not necessary since your EJB does not require any type of authentication in order for you to access it. Normally, that's only necessary when you have, for example, an application that uses a LDAP service provider.

António Ribeiro
  • 4,129
  • 5
  • 32
  • 49
  • ok! many thanks Aribeiro, but now i receive java.lang.ClassCastException: org.jboss.ejb.client.naming.ejb.EjbNamingContext cannot be cast to com.studio.java.NewSessionBeanRemote – reve Mar 30 '16 at 15:48
  • How are you doing the lookup? – António Ribeiro Mar 30 '16 at 15:55
  • always the cast Exception :( – reve Mar 30 '16 at 15:58
  • I was asking for the string that you are using in the `context.lookup`. What is it? – António Ribeiro Mar 30 '16 at 16:01
  • i think the lookup is ok, but now i have another error.. when i try the lookup this line: (NewSessionBeanRemote) context.lookup("ejb:" + appName + "" + moduleName + "" + distinctName + "" + beanName + "!" + viewClassName); – reve Mar 30 '16 at 16:02
  • Remove the `ejb:`, you don't need it. – António Ribeiro Mar 30 '16 at 16:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107769/discussion-between-aribeiro-and-reve). – António Ribeiro Mar 30 '16 at 18:00
  • many thanks @aribeiro , now i receive: Failed to connect to any server. Servers tried: [http-remoting://127.0.0.1:10090 (java.io.IOException: Unknown service name)] but my woldfly notice: WFLYSRV0051: Admin console listening on http://127.0.0.1:10090 and Undertow HTTP listener default listening on 127.0.0.1:8180 if i change the port with 8180 i receive No EJB receiver available for handling – reve Mar 30 '16 at 18:01
  • @reve, if you haven't changed your WildFly port, by default it's 8080. Therefore, you should have `jndiProperties.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080");`. – António Ribeiro Mar 30 '16 at 18:39
  • thanks! solved it: EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext – reve Mar 31 '16 at 19:45