6
votes

I am trying to connect to a remote EJB on my local JBoss 7.2 from an executable Java application (local not on JBoss).

But I get the following error/Exception :

java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:xx-xx, moduleName:xx-xx-business-impl, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@14bc02d
    at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:693)
    at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)
    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183)
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:177)
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:161)
    at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:124)
    at com.sun.proxy.$Proxy0.getX(Unknown Source)
    at com...ris.client.PACSServiceTest.main(PACSServiceTest.java:71)

The test remote bean TestService and its implementation is in an EAR.

Server Classes:

@Remote
public interface TestService {

    public int getX();

}

@Stateless
@Remote(TestService.class)
public class TestServiceBean implements TestService{

    @Override
    public int getX() {
        // TODO Auto-generated method stub
        return 1111;
    }
}

Client code:

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,"remote://localhost:4447");

String jndiName = "ejb:orbis-dicom/orbis-dicom-business-impl//TestServiceBean!"
                  + TestService.class.getName();
logger.info(jndiName);

final Context context = new InitialContext(jndiProperties);
TestService service = (TestService) context.lookup(jndiName);

logger.info(service.getX());

jboss-ejb-client.properties:

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

client dependencies:

+- org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec:jar:1.
nal:runtime
 +- org.jboss.spec.javax.ejb:jboss-ejb-api_3.1_spec:jar:1.0.2.Final:runtim

 +- org.jboss:jboss-ejb-client:jar:1.0.16.Final:runtime
 |  +- org.jboss.marshalling:jboss-marshalling:jar:1.3.16.GA:runtime (vers
naged from 1.3.15.GA)
 |  \- org.jboss.logging:jboss-logging:jar:3.1.2.GA:runtime
 +- org.jboss.xnio:xnio-api:jar:3.0.7.GA:runtime
 +- org.jboss.xnio:xnio-nio:jar:3.0.7.GA:runtime
 +- org.jboss.remoting3:jboss-remoting:jar:3.2.14.GA:runtime
 +- org.jboss.sasl:jboss-sasl:jar:1.0.3.Final:runtime
 +- org.jboss.marshalling:jboss-marshalling-river:jar:1.3.16.GA:runtime
 +- org.jboss.as:jboss-as-naming:jar:7.2.0.Final:provided
 |  +- org.jboss:jboss-remote-naming:jar:1.0.5.Final:provided
 |  +- org.jboss.msc:jboss-msc:jar:1.0.4.GA:provided
 |  +- org.jboss.as:jboss-as-server:jar:7.2.0.Final:provided
 |  |  +- org.jboss.as:jboss-as-controller:jar:7.2.0.Final:provided
 |  |  |  +- org.jboss.as:jboss-as-controller-client:jar:7.2.0.Final:provi

 |  |  |  \- org.jboss:staxmapper:jar:1.1.0.Final:provided
 |  |  +- org.jboss.as:jboss-as-domain-http-interface:jar:7.2.0.Final:prov

 |  |  |  +- org.jboss.as:jboss-as-domain-management:jar:7.2.0.Final:provi

 |  |  |  |  \- org.jboss:jboss-common-core:jar:2.2.17.GA:provided
 |  |  |  \- org.jboss.com.sun.httpserver:httpserver:jar:1.0.1.Final:provi

 |  |  +- org.jboss.as:jboss-as-deployment-repository:jar:7.2.0.Final:prov

 |  |  |  \- org.jboss.as:jboss-as-protocol:jar:7.2.0.Final:provided
 |  |  +- org.jboss.as:jboss-as-platform-mbean:jar:7.2.0.Final:provided
 |  |  +- org.jboss.as:jboss-as-process-controller:jar:7.2.0.Final:provide

 |  |  |  \- system:jdk-tools:jar:jdk:system
 |  |  +- org.jboss.as:jboss-as-remoting:jar:7.2.0.Final:provided
 |  |  |  \- org.jboss.as:jboss-as-network:jar:7.2.0.Final:provided
 |  |  +- org.jboss.as:jboss-as-version:jar:7.2.0.Final:provided
 |  |  +- org.jboss:jandex:jar:1.0.3.Final:provided
 |  |  +- org.jboss:jboss-dmr:jar:1.1.6.Final:provided
 |  |  +- org.jboss.invocation:jboss-invocation:jar:1.1.1.Final:provided
 |  |  +- org.jboss.logmanager:jboss-logmanager:jar:1.4.0.Final:provided
 |  |  +- org.jboss.logmanager:log4j-jboss-logmanager:jar:1.0.1.Final:prov

 |  |  +- org.jboss.modules:jboss-modules:jar:1.2.0.CR1:provided
 |  |  +- org.jboss.stdio:jboss-stdio:jar:1.0.1.GA:provided
 |  |  +- org.jboss.threads:jboss-threads:jar:2.1.0.Final:provided
 |  |  \- org.jboss:jboss-vfs:jar:3.1.0.Final:provided
 |  \- org.jboss.as:jboss-as-build-config:jar:7.2.0.Final:provided
 \- log4j:log4j:jar:1.2.16:compile

Any ideas? Thanks in advance!

8

8 Answers

7
votes

You need to keep the InitialContext referenced (it must not be garbage collected) as long as you want to access methods on the "lookup'ed" Remote EJB.

5
votes

The same issue has been bugging me for days. I'm using Wildfly 9.0.2, but the essence should be the same. Set the property jboss.naming.client.ejb.context to false.

JBoss provides two different means for remote lookup, "remote-naming" and "ejb-client". Both are explained best at https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project

You are using a pure "ejb-client" approach, in which the InitialContext that the EJB proxy was looked up from is no longer valid (i.e., it was closed or gc'ed). This is what the "no EJB receiver" exception means. When the property jboss.naming.client.ejb.context is true, it indicates that InitialContext should be used for all EJB calls. Keeping a reference to the InitialContext as mentioned earlier isn't a good idea, however.

The solution is to set jboss.naming.client.ejb.context to false, which enforces EJB calls to be managed by the "remote-naming" framework. In order for this to work, you need both jboss-ejb-client.properties and jndi.properties files on your classpath (or configure programmatically). The latter should contain the following properties:

java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.provider.url=remote://localhost:4447
jboss.naming.client.ejb.context=false

Given this setup, you may even call InitialContext.close() immediately after looking up the EJB proxy (in case you cannot wait for it to be automatically gc'ed).

2
votes

add the setting below in your client code: jndiProperties.put("jboss.naming.client.ejb.context",true);

0
votes

I faced the same problem.

This exception is raised because an attempt to open a connection (JNDI) after opening all the allowed number of accepted connections from a client to the application server (JBoss).

The common mistake is that the opened connection is not closed as soon as possible. Worse than that, it is not closed at all.

To solve the problem, simply add this statement, after you are done with your EJB:

context.close();

Refer to this link too.

0
votes

We faced this problem also when passing the ejb reference from one method to another to be used in the second one.

So you better create the context, get the ejb, use it and close the context in one method.

0
votes

If someone is interested in, in my opinion the message tells: I can't get a connection to the server bean. Whyever! There can be many reasons (wrong ejb lookup syntax, wriong port, wrong whatever).

In my case it was a "wrong" host, which beside all other definitions was defined in the properties file - unfortunetly having trailing blanks.

Hope this may help others.

0
votes

The same issue I have met. I can see you are trying to run a unit test to invoke remote EJB, is that right? Please make sure add your jboss-ejb-client.properties file into classpath. Though you may create jboss-ejb-client.properties file, but make sure it's included into classpath, it is required. I solved this issue by this way.

-1
votes

context.close() does not solve the problem for me.

I initialized a blank context and did the jnki lookup in the below manner for session beans.

private static String JNDINAME = "java:global/XXXEAR/XXXXejb/!.XXXHome"; home = (XXXHome) context.lookup(JNDINAME);

For Entity beans...it is complex and involves more changes in JBoss configuration.

Entity beans 2.X are not supported in the lightweight configuration of JBoss AS 7 onwards. We have to use the use the standalone-full configuration or standalone-full-ha configuration for entity beans deployment in AS7. Start the server using the standalone full.xml and and you'll see the entity beans being bound to JNDI: 17:27:31,762 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-7) JNDI bindings for session bean named XXXBean in deployment unit subdeployment "XXXEJB.jar" of deployment "XXXEAR.ear" are as follows:

java:global/XXXEAR/XXXXEJB/<ejb bean name>!<package name><ejb local home>
java:app/XXXXEJB/<ejb bean name>!<package name><ejb local home>
java:module/<ejb bean name>!<package name><ejb local home>
java:global/XXXEAR/XXXXEJB/<ejb beanname>!<package name><ejb local>
java:app/XXXXEJB/<ejb bena name>!<package name><ejb local>
java:module/<ejb bean name>!<package name><ejb local>

The JNDI should be looked up by the java:global binding : java:global/XXXEAR/XXXXEJB/!. It works good..!!