如何从Java SE连接到部署在GlassFish上的远程EJB?

huangapple go评论65阅读模式
英文:

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

问题

经过两天的Google和大量测试,我在这里发布。我看到了类似的问题,但它们的解决方案不符合我的需求。我编写了一个带有远程接口的简单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接口的副本

在客户端,我正在使用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: 在SerialContext[myEnv={...}]中查找“java:global/EjbServer/GreeterBean”失败[根本异常是javax.naming.NamingException:远程业务接口test.Greeter的ejb引用解析错误[根本异常是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)
根本异常是javax.naming.NamingException:远程业务接口test.Greeter的ejb引用解析错误[根本异常是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
根本异常是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

任何帮助将不胜感激。提前致谢。
英文:

After two days googling and testing allot, I posting here.
I saw similar questions but their solutions don't feet my needs.
I wrote a simple Ejb with remote interface and want to call it from java Se program.
I deployed my ejb as Eclipse ejb module.
This is a part of my code.

@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(&quot;hello&quot;+name);
	}

}

And This is my Java se program

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

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

I also have a copy of Greeter Interface in client app

In client Side, I'm using glassfish 5 client

&lt;dependency&gt;
 &lt;groupId&gt;org.glassfish.main.appclient&lt;/groupId&gt;
 &lt;artifactId&gt;gf-client&lt;/artifactId&gt;
 &lt;version&gt;5.1.0&lt;/version&gt;
&lt;/dependency&gt;   

I'm using java EE 8 and glassfish 5.0.1 and Ejb 3.2 and Eclipse ide 2019
and This is my full stack trace.

javax.naming.NamingException: Lookup failed for &#39;java:global/EjbServer/GreeterBean&#39; 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

Any help would be appreciated.
Thanks in advance.

答案1

得分: 1

以下是您要翻译的内容:

首先,在Eclipse上创建一个企业应用程序项目,选择File > New > Enterprise Application Project,并输入一个名称,例如EarEjbProject。保持默认设置,然后点击Finish。

然后,创建一个EJB项目,例如EjbProjectModule。输入项目名称,勾选"Add project to an Ear"选项,并选择您之前构建的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;
    }
}

创建一个应用程序模块项目,选择File > New > Application Module Project。

创建一个与EjbServerModule项目上的远程接口相同的包,并从服务器项目中复制该接口。

将as-install/lib/gf-client.jar文件复制到客户端计算机,并将其包含在客户端端的类路径中。
gf-client.jar文件在其MANIFEST.MF文件中引用了GlassFish服务器JAR文件。如果客户端计算机上没有GlassFish服务器安装,您还必须将as-install/modules目录复制到客户端计算机,并保持其相对于as-install/lib/gf-client.jar文件的目录结构。或者,您可以使用package-appclient脚本。
"as-install"指的是您的GlassFish目录。

现在创建您的主类。

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"; // 如果您在同一台计算机上运行客户端和服务器示例
            String port = "3700"; // 默认端口
            // 要获取端口,请使用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();
        }
    }
}

您可以从此示例下载示例代码。

英文:

First, create an enterprise application project on eclipse File>new>Enterprise Application Project and enter a name.
for Example, EarEjbProject.
Leave default settings and hit finish.
Then, create an Ejb project for Example, EjbProjectModule.
Enter your project name and check add project to an Ear option and select your ear project that you built before.
create youre remote Ejb interface.

package com.hamid.test;

import javax.ejb.Remote;

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

And Then, create your remote Bean implementation.

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 =&quot;hello&quot;+name;
		System.out.println(greet);
		return greet;
	}

}

Create an Application Module project
File>new>Application Module Project.
create a package as same as your remote interface on EjbServerModule project andcoppy that interface from server project.
Copy the as-install/lib/gf-client.jar file to the client machine and include it in the classpath on the client side.
The gf-client.jar file references GlassFish Server JAR files in its MANIFEST.MF file. If there is no GlassFish Server installation on the client machine, you must also copy the as-install/modules directory to the client machine and maintain its directory structure relative to the as-install/lib/gf-client.jar file. Or you can use the package-appclient script.
"as-instal" means your glassfish directory.
now create your main 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(&quot;test&quot;);
		try {
			String host=&quot;localhost&quot;;// if you run your client and server sample on same machine
			String port =&quot;3700&quot;;//default
// to obtain port use asadmin get &quot;configs.config.server-config.iiop-service.iiop-listener.orb-listener-1.*&quot; 
			Properties prop = new Properties();
			prop.put(&quot;org.omg.CORBA.ORBInitialHost&quot;,host);
			prop.put(&quot;org.omg.CORBA.ORBInitialPort&quot;,port);
			InitialContext context =new InitialContext(prop);
			Greeting greeting =(Greeting) context.doLookup(&quot;java:global/EarEjbProject/EjbServerModule/GreetingBean&quot;);
			String text=greeting.greet(&quot;hamid&quot;);
			System.out.println(text);
			System.out.println(&quot;exit&quot;);
			context.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}

You can download this example

答案2

得分: 0

initialContext.lookup("java:global/EjbServer/GreeterBean")

For starters, the URL you're using doesn't look right to me: the names of the package and of the remote interface are supposed to be present, if memory serves.

英文:
initialContext.lookup(&quot;java:global/EjbServer/GreeterBean&quot;)

For starters, the URL you're using doesn't look right to me: the names of the package and of the remote interface are supposed to be present, if memory serves.

huangapple
  • 本文由 发表于 2020年4月8日 18:50:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/61098925.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定