Search code examples
javatomcatjbossejbjndi

Problems accessing EJB in JBoss AS 7.x from Tomcat 6


I am trying to make some remote calls to some EJB running inside a JBoss AS 7.1.1 final from my Servlet running under Tomcat 6. The EJBs are closed source and accessed from some given jars (closed code), which use a Delegate-Pattern to wrap the access to the stateless Beans.

After days of struggling with the right configuration for the jndi-lookup, I found different configurations, which all make different problems.

Solution A:

Since Tomcat 6 has it's own jndi, simply putting a jndi.properties (like it works fine if accessing the EJBs from a simple java application) in the classpath, did not work. Instead I pass the properties in an hashtable to the delegate's constructor like this:

Hashtable<String, String> jndiProperties = new Hashtable<String, String>();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.as.naming.interfaces:org.jboss.ejb.client.naming");
jndiProperties.put(Context.PROVIDER_URL, "remote://10.10.10.10:4447");
jndiProperties.put(Context.SECURITY_PRINCIPAL, "user");
jndiProperties.put(Context.SECURITY_CREDENTIALS, "password");

Delegate someDelegate = new DelegateImpl(jndiProperties);

This leads to the following exception (which does not occur when doing the same from a simple java application):

java.lang.IllegalStateException: No EJB receiver available for handling [appName:eex,modulename:eex-ejb,distinctname:] combination for invocation context 

Some research advised me to try....

Solution B:

I added the following line:

jndiProperties.put("jboss.naming.client.ejb.context", "true");

Now the lookup and remote call works fine, but after some calls I get the following exception (which also occurs when doing the same from a simple java application):

org.jboss.remoting3.ProtocolException: Too many channels open

As far as I understand, with jboss.naming.client.ejb.context set to true, a new EJBClientContext is created for every lookup on JBoss AS side and it seems, that the Delegate does not close it correctly. There's a detailed explanation on how to correctly close all contexts under https://docs.jboss.org/author/display/WFLY8/Scoped+EJB+client+contexts.

Since I don't own the Delegate-source-code, there is no way to close the contexts correctly.

So I tried...

Solution C:

There's a whole different way to do the lookup: by providing a jboss-ejb-client.xml instead of a jndi.properties. This works well together with tomcat and the lookup is fine with this configuration:

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.port=4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.host=10.10.10.10
remote.connection.default.username=user
remote.connection.default.password=password

However, with this configuration I run into the following exception from time to time (I can not reproduce it so far, the exception just occurs sometimes):

ERROR: JBREM000200: Remote connection failed: the timeout for the connection expired
...and some lines later...
Caused by: java.io.IOException: Channel Channel ID 841ded9c (outbound) of Remoting connection 00dcc89a to null has been closed

Any help is highly appreciated...


Solution

  • ok, I finally could solve my problem.

    I still don't know the answer to the problems of solution A.

    I described the possible problems of solution B.

    The exception of solution C was caused by our firewall, which dropped the session table entry after some minutes of inactivity. I solved it by adding

    remote.connection.default.connect.options.org.jboss.remoting3.RemotingOptions.HEARTBEAT_INTERVAL=60000
    

    to jboss-ejb-client.properties.

    This causes a "ping" from the client to the JBoss AS every minute, which prevents the firewall from dropping the session entry.