EJB远程客户端从JBoss AS 7.1迁移到Wildfly 8.1

问题描述 投票:1回答:4

我们开发了一个培训应用程序,其中包含与EJB通信的独立Java客户端。工作设置包括Windows 7上的JBoss AS 7.1和通过/bin/add-user.bat创建的应用程序用户。

客户端编码如下:

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

客户端是在类路径中使用jboss-client.jar启动的。

现在我们尝试使用WildFly 8.1而不是成功部署,但客户端失败了

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

将JNDI查找名称更改为在部署期间打印出来的内容(例如java:global/training/MyBean!mypackage.MyBeanRemote)导致

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)]

在谷歌搜索了一段时间之后,我们对SO上的几篇文章(例如thisthat)或samplesWildfly Developer Guide进行了论述,但所有替代方案,可能是最小的JNDI属性或通过ClientContext的扩展配置都没有使它工作。

所以我的问题是,需要做些什么来迁移上面的代码/配置才能在WildFly下运行它?

注意:这不是生产代码,因此安全性不是问题 - 如果我可以简化整个配置,那很好 - 它应该只演示如何使用独立Java程序中的EJB远程接口。

java java-ee ejb jboss7.x wildfly
4个回答
3
投票

你需要做两个改变

而不是使用“remote:// localhost:4447”使用“http-remoting:// localhost:8080”

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

在代码中配置jndi属性时,查找名称不应包含ejb:

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

这个解决方案经过测试和运行


2
投票

提供者URL应该是http-remoting://localhost:8080而不是remote://localhost:4447


0
投票

我正在使用:

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

这对我有用:

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

希望能帮助到你!


0
投票

这是我的项目名为“MyFirstEJBProject”。代码里面有一些注意事项可以提供帮助。

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";   
         */
    }
}

注意:我使用的是Wildfly(JBoss),因此需要在wildfly-10.0.0.Final \ bin \ client \文件夹中导入jboss-client.jar。