1

We developed a training application which contains a standalone java clients communicating with EJBs. The working setup included a JBoss AS 7.1 on Windows 7 and an application user created via /bin/add-user.bat.

The client was coded like that:

Properties jndiProps = new Properties();
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProps.put("jboss.naming.client.ejb.context", true);
jndiProps.put(Context.PROVIDER_URL, "remote://localhost:4447");
jndiProps.put(Context.SECURITY_PRINCIPAL, "user");
jndiProps.put(Context.SECURITY_CREDENTIALS, "xxx");
Context ctx = new InitialContext(jndiProps);
MyBeanRemote myBean = (MyBeanRemote) ctx.lookup("ejb:/training//MyBean!mypackage.MyBeanRemote");
String result = myBean.greet("John");

The client was started with jboss-client.jar in the classpath.

Now we tried to use a WildFly 8.1 instead which deployed successfully, but the client fails with

Exception in thread "main" java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:, moduleName:syjeews, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@6e7d3146

Changing the JNDI lookup name into something which is printed out during deployment (e.g. java:global/training/MyBean!mypackage.MyBeanRemote) resulted in

Exception in thread "main" javax.naming.CommunicationException: Failed to connect to any server. Servers tried: [remote://localhost:4447 (java.net.ConnectException: Connection refused: no further information)]

After searching googling for a while we stumpled upon several articles on SO (e.g. this or that) or samples or the Wildfly Developer Guide, but all alternatives, may it be the minimal JNDI properties or the extended configuration via ClientContext didn't make it work.

So my question is, what needs to be done to migrate the code/configuration above to run it under WildFly?

Note: This is not production code, so security is not an issue - if I can simplify the whole configuration, it's fine - it should only demonstrate how to use an EJB remote interface from a standalone Java program.

Community
  • 1
  • 1
Alexander Rühl
  • 6,769
  • 9
  • 53
  • 96

4 Answers4

4

You need to do two changes

instead of using "remote://localhost:4447" use "http-remoting://localhost:8080"

jndiProps.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");

When you configure jndi properties in code, lookup name should not contain ejb:

MyBeanRemote myBean = (MyBeanRemote) ctx.lookup("/training//MyBean!mypackage.MyBeanRemote");

this solution is tested and working

Isuru
  • 700
  • 9
  • 22
  • Hey, thanks a ton for the late but still very appreciated answer - I tried it immediately and it worked! I still wonder though, why the lookup can't be done with the exact Strings which are outputted by WildFly during deployment. – Alexander Rühl Nov 28 '16 at 12:31
2

The provider URL should be http-remoting://localhost:8080 instead of remote://localhost:4447

Aparna Chaudhary
  • 1,325
  • 8
  • 10
  • Ok, I tried that, but it's telling me that it can't find the JNDI name. Besides the original above with `ejb:/` I also tried the ones with `java:/` and others listed in console when deploying the EJB. Any idea what else is missing? – Alexander Rühl Mar 18 '15 at 19:45
  • @Geziefer try the `java:global/...` entry about your ejb that you find in log as lookup string. – Francesco Mar 19 '15 at 09:39
  • @Francesco: Just in case of interest: You were on the right track with your suggestion, but the namespace had to be ommited (though I don't know why). – Alexander Rühl Nov 28 '16 at 12:34
0

I'm using:

  • wildfly-10.0.0.Final(JBoss Application Server).

That works to me:

Properties jndiProperties = new Properties();
           jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
           jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
           jndiProperties.put("jboss.naming.client.ejb.context", true);
           jndiProperties.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");   //System.getProperty(Context.PROVIDER_URL, "http-remoting://localhost:8080"));

        /* jndiProperties.put(Context.SECURITY_PRINCIPAL, "user");
           jndiProperties.put(Context.SECURITY_CREDENTIALS, "xxx");*/

        InitialContext context = new InitialContext(jndiProperties);

        MyFirstEJBRemote ejb = (MyFirstEJBRemote) context.lookup("/EJBProjectName/MyFirstEJB!src.MyFirstEJBRemote");

Hope it helps!

Davijr
  • 1,093
  • 11
  • 10
  • Hallo Davijr, I also got the same configuration as you mentioned above, but I still got the error: Exception in thread "main" javax.naming.CommunicationException: Failed to connect to any server. Servers tried: [http-remoting://localhost:8080 (java.io.IOException: JBREM000202: Abrupt close on Remoting connection 329100e4 to localhost/127.0.0.1:8080 of endpoint "config-based-naming-client-endpoint" <1d9ed52c>)]. Do you have any idea? – Ock May 15 '17 at 14:53
  • I tried to run the project without to startup the server and I received a similar erro. So I think you forgot to startup the server. – Davijr May 16 '17 at 01:09
  • I had to "Add Another Answer" and it went to up. – Davijr May 16 '17 at 01:34
0

Here is my Project called "MyFirstEJBProject". Inside of the code are some notes to help.

package src.ejb;

import javax.ejb.Stateless;

/**
 * Session Bean implementation class MyFirstEJB
 */
@Stateless
public class MyFirstEJB implements MyFirstEJBRemote {

    public MyFirstEJB() {
    }

    @Override
    public String helloWorld() {
        return "Hello World EJB";
    }

}


package src.ejb;

import javax.ejb.Remote;

@Remote
public interface MyFirstEJBRemote {
    public String helloWorld();
}


package src.clientTest;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import src.ejb.MyFirstEJB;
import src.ejb.MyFirstEJBRemote;

public class EJBClient {

    public static void main(String[] args) throws NamingException {

        /**JNDI or Java Naming and Directory Interface.
         * When JNDI constructs an initial context, the context's environment
         * is initialized with properties defined in the environment parameter
         * passed to the constructor, the system properties, the applet parameters,
         * and the application resource files.
         * 
         * JNDI applications need a way to communicate various preferences
         * and properties that define the environment in which naming and
         * directory services are accessed.
         * */

        Properties jndiProperties = new Properties();
        jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        jndiProperties.put("jboss.naming.client.ejb.context", true);
        jndiProperties.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");

        /* jndiProperties.put(Context.SECURITY_PRINCIPAL, "user");
           jndiProperties.put(Context.SECURITY_CREDENTIALS, "xxx");*/

        /**Context For JNDI**/
        InitialContext context = new InitialContext(jndiProperties);

        /**The nameOfEJB appears on the console when the server is starting up.**/
        String nameOfEJB = "/MyFirstEJBProject/MyFirstEJB!src.ejb.MyFirstEJBRemote";

                                                  /**The Method .lookup("") search for EJB by name**/
        MyFirstEJBRemote ejb = (MyFirstEJBRemote) context.lookup(nameOfEJB);
        System.out.println(ejb.helloWorld());


        System.out.println("/** =============== 2º TEST ===============**/"); 

        /**getting a EJB name by a private Method.**/
        String nameOfEJB_2 = getEJBName("", "MyFirstEJBProject", "", 
                MyFirstEJB.class.getSimpleName(), MyFirstEJBRemote.class.getName());

        MyFirstEJBRemote ejb_2 = (MyFirstEJBRemote) context.lookup(nameOfEJB_2);
        System.out.println(ejb_2.helloWorld());
    }

    private static String getEJBName(String nameofAppEAR, String nameOfProjectModulo, 
            String distinctNameOfProject, String classBeanSimpleName, String classInterfaceName){
        /**Return a object name for search on JNDI */

        String finalNameOfEJB = nameofAppEAR + "/" + nameOfProjectModulo + "/" + distinctNameOfProject + 
                "/" + classBeanSimpleName + "!" + classInterfaceName;  

        return finalNameOfEJB; 

        /**Ex:                 
           String nameofAppEAR= "";                            // EAR  (if there is)
           String nameOfProjectModulo= "MyFirstEJBProject";
           String distinctNameOfProject= "";                   // Alias (if there is)
           String classBeanSimpleName= MyFirstEJB.class.getSimpleName(); 
           String classInterfaceName=  MyFirstEJBRemote.class.getName();

           String finalNameOfEJB = "" + "/" + "MyFirstEJBProject" + "/" + "" + 
                "/" + MyFirstEJB.class.getSimpleName() + "!" + MyFirstEJBRemote.class.getName();

           The nameOfEJB appears on the console when the server is starting up:
           String nameOfEJB = "/MyFirstEJBProject/MyFirstEJB!src.ejb.MyFirstEJBRemote";   
         */
    }
}

Notes: I am using Wildfly(JBoss), so it is needed to import the jboss-client.jar at wildfly-10.0.0.Final\bin\client\ folder.

Davijr
  • 1,093
  • 11
  • 10