No EJB receiver available for handling ...
In Jboss EAP 6, this error occurs when calling a remote EJB, the reason may be that the JNDI format is wrong. The format of EJB JNDI is as follows:
ejb:<appName>/<moduleName>/<distinctName>/<beanName>!<viewClassName>?stateful
Note that there is no "/" before appName! If there is no distinctName, leave it blank, that is, two consecutive "//".
Sample code ejb-remote is provided in jboss-eap-quickstarts-6.4.0.GA:
public interface RemoteCalculator { int add(int a, int b); int subtract(int a, int b); } @Stateless @Remote(RemoteCalculator.class) public class CalculatorBean implements RemoteCalculator { @Override public int add(int a, int b) { return a + b; } @Override public int subtract(int a, int b) { return a - b; } } public class RemoteEJBClient { public static void main(String[] args) throws Exception { // Invoke a stateless bean invokeStatelessBean(); // Invoke a stateful bean invokeStatefulBean(); } private static void invokeStatelessBean() throws NamingException { // Let's lookup the remote stateless calculator final RemoteCalculator statelessRemoteCalculator = lookupRemoteStatelessCalculator(); System.out.println("Obtained a remote stateless calculator for invocation"); // invoke on the remote calculator int a = 204; int b = 340; System.out.println("Adding " + a + " and " + b + " via the remote stateless calculator deployed on the server"); int sum = statelessRemoteCalculator.add(a, b); System.out.println("Remote calculator returned sum = " + sum); if (sum != a + b) { throw new RuntimeException("Remote stateless calculator returned an incorrect sum " + sum + " ,expected sum was " + (a + b)); } // try one more invocation, this time for subtraction int num1 = 3434; int num2 = 2332; System.out.println("Subtracting " + num2 + " from " + num1 + " via the remote stateless calculator deployed on the server"); int difference = statelessRemoteCalculator.subtract(num1, num2); System.out.println("Remote calculator returned difference = " + difference); if (difference != num1 - num2) { throw new RuntimeException("Remote stateless calculator returned an incorrect difference " + difference + " ,expected difference was " + (num1 - num2)); } } ... private static RemoteCalculator lookupRemoteStatelessCalculator() throws NamingException { final Hashtable<String, String> jndiProperties = new Hashtable<String, String>(); jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); final Context context = new InitialContext(jndiProperties); return (RemoteCalculator) context.lookup("ejb:/jboss-ejb-remote-server-side/CalculatorBean!" + RemoteCalculator.class.getName()); } ... }
jboss-ejb-client.properties (in the resources root directory)
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
Client pom.xml
<dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.spec</groupId> <artifactId>jboss-javaee-6.0</artifactId> <version>${version.jboss.spec.javaee.6.0}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-ejb-client-bom</artifactId> <version>${version.jboss.as}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Import the transaction spec API, we use runtime scope because we aren't using any direct reference to the spec API in our client code --> <dependency> <groupId>org.jboss.spec.javax.transaction</groupId> <artifactId>jboss-transaction-api_1.1_spec</artifactId> <scope>runtime</scope> </dependency> <!-- Import the EJB 3.1 API, we use runtime scope because we aren't using any direct reference to EJB spec API in our client code --> <dependency> <groupId>org.jboss.spec.javax.ejb</groupId> <artifactId>jboss-ejb-api_3.1_spec</artifactId> <scope>runtime</scope> </dependency> <!-- We depend on the EJB remote business interfaces of this application --> <dependency> <groupId>org.jboss.quickstarts.eap</groupId> <artifactId>jboss-ejb-remote-server-side</artifactId> <type>ejb-client</type> <version>${project.version}</version> </dependency> <!-- JBoss EJB client API jar. We use runtime scope because the EJB client API isn't directly used in this example. We just need it in our runtime classpath --> <dependency> <groupId>org.jboss</groupId> <artifactId>jboss-ejb-client</artifactId> <scope>runtime</scope> </dependency> <!-- client communications with the server use XNIO --> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-api</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-nio</artifactId> <scope>runtime</scope> </dependency> <!-- The client needs JBoss remoting to access the server --> <dependency> <groupId>org.jboss.remoting3</groupId> <artifactId>jboss-remoting</artifactId> <scope>runtime</scope> </dependency> <!-- Remote EJB accesses can be secured --> <dependency> <groupId>org.jboss.sasl</groupId> <artifactId>jboss-sasl</artifactId> <scope>runtime</scope> </dependency> <!-- data serialization for invoking remote EJBs --> <dependency> <groupId>org.jboss.marshalling</groupId> <artifactId>jboss-marshalling-river</artifactId> <scope>runtime</scope> </dependency> </dependencies>
The example is deployed to jboss in the form of a jar package. Viewing the jboss log, you can find:
java:jboss/exported/jboss-ejb-remote-server-side/CalculatorBean!org.jboss.as.quickstarts.ejb.remote.stateless.RemoteCalculator
Deployed in the form of a jar package, written in the form of access:
context.lookup("ejb:/jboss-ejb-remote-server-side/CalculatorBean!" + RemoteCalculator.class.getName());
I moved it to ear and changed it to the following:
context.lookup("ejb:/myear/myejb/CalculatorBean!" + RemoteCalculator.class.getName());
There appears No EJB receiver available for handling ..., be careful to remove the "/"!
注意:By default WildFly uses 8080 as the remoting port. The EJB client API uses the http port, with the http-upgrade functionality, for communicating with the server for remote invocations(unless the server is configured for some other http port)
For more details see
Invoke a Session Bean Remotely using JNDI(EAP 6)
EJB invocations from a remote client using JNDI(Wildfly 8)
Remote EJB invocations via JNDI - EJB client API or remote-naming project