如何从 java Se 连接到部署在 glassfish 上的远程 Ejb?

How to connect to remote Ejb that deployed on glassfish from java Se?

经过两天的谷歌搜索和测试分配,我在这里发帖。 我看到了类似的问题,但他们的解决方案不符合我的需求。
我写了一个带有远程接口的简单 Ejb,想从 java Se 程序中调用它。
我将我的 ejb 部署为 Eclipse ejb 模块。 这是我的代码的一部分。

@Remote
public interface Greeter extends Serializable {
public void greet(String name) throws NamingException;
}

@Stateless
public class GreeterBean implements Greeter {
    @Override
    public void greet(String name) throws NamingException {
        System.out.println("hello"+name);
    }

}

这是我的Java se程序

Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
    "com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.factory.url.pkgs",
    "com.sun.enterprise.naming");
props.setProperty("java.naming.factory.state",
    "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

try {
    InitialContext  initialContext = new InitialContext(props);
    Greeter greeter = (Greeter) initialContext.lookup("java:global/EjbServer/GreeterBean");
    greeter.greet("hamid");
...

我在客户端应用程序中也有一个 Greeter Interface 的副本

在客户端 Side 中,我使用的是 glassfish 5 客户端

<dependency>
 <groupId>org.glassfish.main.appclient</groupId>
 <artifactId>gf-client</artifactId>
 <version>5.1.0</version>
</dependency>   

我正在使用 java EE 8 和 glassfish 5.0.1 以及 Ejb 3.2 和 Eclipse ide 2019 这是我的完整堆栈跟踪。

javax.naming.NamingException: Lookup failed for 'java:global/EjbServer/GreeterBean' in SerialContext[myEnv={org.omg.CORBA.ORBInitialPort=3700, java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory, org.omg.CORBA.ORBInitialHost=localhost, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NamingException: ejb ref resolution error for remote business interfacetest.Greeter [Root exception is java.lang.ClassNotFoundException: test.Greeter]]
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:467)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:414)
    at javax.naming.InitialContext.lookup(InitialContext.java:417)
    at com.client.ejb.App.main(App.java:45)
Caused by: javax.naming.NamingException: ejb ref resolution error for remote business interfacetest.Greeter [Root exception is java.lang.ClassNotFoundException: test.Greeter]
    at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:409)
    at com.sun.ejb.containers.RemoteBusinessObjectFactory.getObjectInstance(RemoteBusinessObjectFactory.java:51)
    at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
    at com.sun.enterprise.naming.impl.SerialContext.getObjectInstance(SerialContext.java:503)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:463)
    ... 3 more
Caused by: java.lang.ClassNotFoundException: test.Greeter
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at com.sun.ejb.EJBUtils.getBusinessIntfClassLoader(EJBUtils.java:663)
    at com.sun.ejb.EJBUtils.loadGeneratedRemoteBusinessClasses(EJBUtils.java:439)
    at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:389)

... 7 more

如有任何帮助,我们将不胜感激。 提前致谢。

首先,在eclipse File>new>Enterprise Application Project上创建一个企业应用项目,并输入名称。 例如,EarEjbProject。 保留默认设置并点击完成。 然后,为示例 EjbProjectModule 创建一个 Ejb 项目。 输入您的项目名称并选中将项目添加到 Ear 选项和 select 您之前构建的 ear 项目。 创建你的远程 Ejb 接口。

package com.hamid.test;

import javax.ejb.Remote;

@Remote
public interface Greeting {
public String greet(String name);
}

然后,创建您的远程 Bean 实现。

package com.hamid.test;

import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Remote
@Stateless
public class GreetingBean implements Greeting  {
    @Override
    public String greet(String name) {
        String greet ="hello"+name;
        System.out.println(greet);
        return greet;
    }

}

创建应用程序模块项目 文件>新建>应用程序模块项目。 在 EjbServerModule 项目上创建一个与您的远程接口相同的包,并从服务器项目复制该接口。 将 as-install/lib/gf-client.jar 文件复制到客户端计算机并将其包含在客户端的 class 路径中。 gf-client.jar 文件在其 MANIFEST.MF 文件中引用 GlassFish Server JAR 文件。如果客户端计算机上没有安装 GlassFish Server,您还必须将 as-install/modules 目录复制到客户端计算机并维护其相对于 as-install/lib/gf-client.jar 文件的目录结构。或者您可以使用 package-appclient 脚本。 "as-instal" 表示您的 glassfish 目录。 现在创建您的主要 class.

package com.ejb.client.example;
import java.util.List;
import java.util.Properties;

import javax.ejb.EJB;
import javax.naming.InitialContext;

import com.hamid.test.Greeting;

public class Main {
    public static void main(String[] args) {
        System.out.println("test");
        try {
            String host="localhost";// if you run your client and server sample on same machine
            String port ="3700";//default
// to obtain port use asadmin get "configs.config.server-config.iiop-service.iiop-listener.orb-listener-1.*" 
            Properties prop = new Properties();
            prop.put("org.omg.CORBA.ORBInitialHost",host);
            prop.put("org.omg.CORBA.ORBInitialPort",port);
            InitialContext context =new InitialContext(prop);
            Greeting greeting =(Greeting) context.doLookup("java:global/EarEjbProject/EjbServerModule/GreetingBean");
            String text=greeting.greet("hamid");
            System.out.println(text);
            System.out.println("exit");
            context.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

您可以下载this example