EJB 3.2 - 无法正确配置远程客户端
EJB 3.2 - Can't configure the remote client correctly
我是 EJB 的新手,我已经编写了一个非常小的 ejb 组件用于演示目的。它应该做的就是打印 "hello "。目前正在努力正确配置远程客户端的 InitialContext。我使用的容器是JBoss 7.0。我将 JaveEE7.0 与 ejb3.2 一起使用。
ejb 的接口:
package hello;
public interface Hello {
public String sayHello(String name);
}
bean 本身:
package hello;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Stateless(name="HelloEJB")
@Remote(Hello.class)
public class HelloBean implements Hello {
@Override
public String sayHello(String name) {
return "Hello, " + name;
}
}
还有我放在 EJB 项目中但 运行 作为 java 应用程序的远程客户端:
package client;
import hello.Hello;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class Test {
public static void main(String[] args) {
Hello statelessHello = null;
try {
statelessHello = lookupStatelessHello(); // the method that throws exception
} catch (NamingException e) {
System.out.println("Bean Loading Failed");
e.printStackTrace();
Thread.currentThread().stop();
}
Hello stub=(Hello)PortableRemoteObject.narrow(statelessHello, Hello.class);
System.out.println("obtained a remote stateless hello for invocation");
System.out.println(stub.sayHello(args[0]));
}
private static Hello lookupStatelessHello() throws NamingException {
// the problematic code:
Properties jndiProperties = new Properties();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL,"remote://localhost:4447"); // tried to change ports.
jndiProperties.put("jboss.naming.client.ejb.context", true);
Context context = new InitialContext(jndiProperties); // exception happens here
return (Hello) context.lookup("stateless1/HelloEJB!hello.Hello");
}
}
当我 运行 JBoss 时,我成功地部署了我的 ejb 项目:
13:37:20,141 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor]
(MSC service thread 1-6) JNDI bindings for session bean named HelloEJB
in deployment unit deployment "stateless1.jar" are as follows:
java:global/stateless1/HelloEJB!hello.Hello
java:app/stateless1/HelloEJB!hello.Hello
java:module/HelloEJB!hello.Hello
java:global/stateless1/HelloEJB
java:app/stateless1/HelloEJB
java:module/HelloEJB
13:37:20,255 INFO [org.jboss.as.server.controller]
(DeploymentScanner-threads - 2) Deployed "stateless1.jar"
但是当我尝试从远程客户端调用 ejb 时,我得到:
Bean Loading Failed javax.naming.NoInitialContextException: Cannot instantiate class:
org.jboss.naming.remote.client.InitialContextFactory [Root exception
is java.lang.ClassNotFoundException:
org.jboss.naming.remote.client.InitialContextFactory] at
javax.naming.spi.NamingManager.getInitialContext(Unknown Source) at
javax.naming.InitialContext.getDefaultInitCtx(Unknown Source) at
javax.naming.InitialContext.init(Unknown Source) at
javax.naming.InitialContext.(Unknown Source) at
client.Test.lookupStatelessHello(Test.java:34) at
client.Test.main(Test.java:18) Caused by:
java.lang.ClassNotFoundException:
org.jboss.naming.remote.client.InitialContextFactory at
java.net.URLClassLoader.findClass(Unknown Source) at
java.lang.ClassLoader.loadClass(Unknown Source) at
sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at
java.lang.ClassLoader.loadClass(Unknown Source) at
java.lang.Class.forName0(Native Method)
我尝试更改端口,尝试添加安全凭证,但我不明白如何添加用户,尝试阅读指南,但坦率地说,因为我是新手,这对我来说很难。另外,我很确定我查找 bean 的方式是错误的,但现在这不是问题所在。
我希望你能帮我找到我在这里做错的地方。如果您需要有关设置的更多信息,请询问。
您的客户端 class 路径中缺少 class 个元素。
查看 $JBOSS_HOME/bin/client/README-EJB-JMS.txt 文件,了解有关您的客户端需要包含哪些 jar 的信息。
如上所述,您需要 jboss-client.jar 以及您的代码才能正常工作。具体的 jar 可以在
找到
JBOSS_HOME/bin/client/jboss-client-7.1.0.Final.jar.
另请查看带有完整示例的官方文档和 wiki。参见 here。
- 确保
client*.jar
在我的 class 路径中 gf-client.jar
,因为使用 glassfish 而不是 JBoss。
- 客户端代码更改阅读评论 2 种查找方式...
- ejb Stateless(name = "HelloWorldEJB", mappedName="HelloEJB") 应该只与 name 一起使用,因为它是可移植的,并且 mappedName 是供应商锁定的应该被劝阻,我只将它用于说明目的。
- 此外,我还没有在同一个容器中设置 jndi 道具。
Context context = new InitialContext();
- post 代码更改重新部署或重新启动 JBoss。
工作代码在粘贴下方 运行 ;)
import javax.ejb.Remote;
@Remote
public interface HelloI {
public String sayHello(String name);
}
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Stateless(name = "HelloWorldEJB", mappedName="HelloEJB")
@Remote(HelloI.class)
public class Hello implements HelloI {
@Override
public String sayHello(String name) {
return "Hello, " + name;
}
}
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class HelloT {
public static void main(String[] args) {
HelloI statelessHelloI = null;
try {
statelessHelloI = lookupStatelessHello(); // the method that throws exception
} catch (NamingException e) {
System.out.println("Bean Loading Failed");
e.printStackTrace();
Thread.currentThread().stop();
}
HelloI stub=(HelloI) PortableRemoteObject.narrow(statelessHelloI, HelloI.class);
System.out.println("obtained a remote stateless hello for invocation");
System.out.println(stub.sayHello(args[0]));
}
private static HelloI lookupStatelessHello() throws NamingException {
// the problematic code:
/*Properties jndiProperties = new Properties();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL,"remote://localhost:4447"); // tried to change ports.
jndiProperties.put("jboss.naming.client.ejb.context", true);
Context context = new InitialContext(jndiProperties); // exception happens here*/
Context context = new InitialContext();
return (HelloI) context.lookup("HelloEJB");
}
}
output Jul 18, 2020 5:58:07 PM
obtained a remote stateless
hello for invocation Hello, ani
Process finished with exit code 0
我在上面post中保留了你的大部分代码。上面的客户端代码可以简化为
import com.au.ejbs.HelloI;
import javax.naming.Context;
import javax.naming.InitialContext;
public class HelloT2 {
public static void main(String[] args)throws Exception {
Context context = new InitialContext();
HelloI remote = (HelloI) context.lookup("HelloEJB");//resolves to mappedName @Stateless(name = "HelloWorldEJB", mappedName="HelloEJB"), from what I read could be glassfish and weblogic centric.
System.out.println(remote.sayHello(args[0]));
remote = (HelloI) context.lookup("java:global/ejb3_2_ear_exploded/ejb/HelloWorldEJB");//Portable should work on jboss and any container resolves to Stateless(name = "HelloWorldEJB"
System.out.println(remote.sayHello(args[0]));
}
}
我是 EJB 的新手,我已经编写了一个非常小的 ejb 组件用于演示目的。它应该做的就是打印 "hello "。目前正在努力正确配置远程客户端的 InitialContext。我使用的容器是JBoss 7.0。我将 JaveEE7.0 与 ejb3.2 一起使用。
ejb 的接口:
package hello;
public interface Hello {
public String sayHello(String name);
}
bean 本身:
package hello;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Stateless(name="HelloEJB")
@Remote(Hello.class)
public class HelloBean implements Hello {
@Override
public String sayHello(String name) {
return "Hello, " + name;
}
}
还有我放在 EJB 项目中但 运行 作为 java 应用程序的远程客户端:
package client;
import hello.Hello;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class Test {
public static void main(String[] args) {
Hello statelessHello = null;
try {
statelessHello = lookupStatelessHello(); // the method that throws exception
} catch (NamingException e) {
System.out.println("Bean Loading Failed");
e.printStackTrace();
Thread.currentThread().stop();
}
Hello stub=(Hello)PortableRemoteObject.narrow(statelessHello, Hello.class);
System.out.println("obtained a remote stateless hello for invocation");
System.out.println(stub.sayHello(args[0]));
}
private static Hello lookupStatelessHello() throws NamingException {
// the problematic code:
Properties jndiProperties = new Properties();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL,"remote://localhost:4447"); // tried to change ports.
jndiProperties.put("jboss.naming.client.ejb.context", true);
Context context = new InitialContext(jndiProperties); // exception happens here
return (Hello) context.lookup("stateless1/HelloEJB!hello.Hello");
}
}
当我 运行 JBoss 时,我成功地部署了我的 ejb 项目:
13:37:20,141 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named HelloEJB in deployment unit deployment "stateless1.jar" are as follows:
java:global/stateless1/HelloEJB!hello.Hello java:app/stateless1/HelloEJB!hello.Hello java:module/HelloEJB!hello.Hello
java:global/stateless1/HelloEJB java:app/stateless1/HelloEJB
java:module/HelloEJB13:37:20,255 INFO [org.jboss.as.server.controller] (DeploymentScanner-threads - 2) Deployed "stateless1.jar"
但是当我尝试从远程客户端调用 ejb 时,我得到:
Bean Loading Failed javax.naming.NoInitialContextException: Cannot instantiate class: org.jboss.naming.remote.client.InitialContextFactory [Root exception is java.lang.ClassNotFoundException: org.jboss.naming.remote.client.InitialContextFactory] at javax.naming.spi.NamingManager.getInitialContext(Unknown Source) at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source) at javax.naming.InitialContext.init(Unknown Source) at javax.naming.InitialContext.(Unknown Source) at client.Test.lookupStatelessHello(Test.java:34) at client.Test.main(Test.java:18) Caused by: java.lang.ClassNotFoundException: org.jboss.naming.remote.client.InitialContextFactory at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method)
我尝试更改端口,尝试添加安全凭证,但我不明白如何添加用户,尝试阅读指南,但坦率地说,因为我是新手,这对我来说很难。另外,我很确定我查找 bean 的方式是错误的,但现在这不是问题所在。
我希望你能帮我找到我在这里做错的地方。如果您需要有关设置的更多信息,请询问。
您的客户端 class 路径中缺少 class 个元素。
查看 $JBOSS_HOME/bin/client/README-EJB-JMS.txt 文件,了解有关您的客户端需要包含哪些 jar 的信息。
如上所述,您需要 jboss-client.jar 以及您的代码才能正常工作。具体的 jar 可以在
找到JBOSS_HOME/bin/client/jboss-client-7.1.0.Final.jar.
另请查看带有完整示例的官方文档和 wiki。参见 here。
- 确保
client*.jar
在我的 class 路径中gf-client.jar
,因为使用 glassfish 而不是 JBoss。 - 客户端代码更改阅读评论 2 种查找方式...
- ejb Stateless(name = "HelloWorldEJB", mappedName="HelloEJB") 应该只与 name 一起使用,因为它是可移植的,并且 mappedName 是供应商锁定的应该被劝阻,我只将它用于说明目的。
- 此外,我还没有在同一个容器中设置 jndi 道具。
Context context = new InitialContext();
- post 代码更改重新部署或重新启动 JBoss。
工作代码在粘贴下方 运行 ;)
import javax.ejb.Remote;
@Remote
public interface HelloI {
public String sayHello(String name);
}
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Stateless(name = "HelloWorldEJB", mappedName="HelloEJB")
@Remote(HelloI.class)
public class Hello implements HelloI {
@Override
public String sayHello(String name) {
return "Hello, " + name;
}
}
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class HelloT {
public static void main(String[] args) {
HelloI statelessHelloI = null;
try {
statelessHelloI = lookupStatelessHello(); // the method that throws exception
} catch (NamingException e) {
System.out.println("Bean Loading Failed");
e.printStackTrace();
Thread.currentThread().stop();
}
HelloI stub=(HelloI) PortableRemoteObject.narrow(statelessHelloI, HelloI.class);
System.out.println("obtained a remote stateless hello for invocation");
System.out.println(stub.sayHello(args[0]));
}
private static HelloI lookupStatelessHello() throws NamingException {
// the problematic code:
/*Properties jndiProperties = new Properties();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL,"remote://localhost:4447"); // tried to change ports.
jndiProperties.put("jboss.naming.client.ejb.context", true);
Context context = new InitialContext(jndiProperties); // exception happens here*/
Context context = new InitialContext();
return (HelloI) context.lookup("HelloEJB");
}
}
output Jul 18, 2020 5:58:07 PM obtained a remote stateless hello for invocation Hello, ani
Process finished with exit code 0
我在上面post中保留了你的大部分代码。上面的客户端代码可以简化为
import com.au.ejbs.HelloI;
import javax.naming.Context;
import javax.naming.InitialContext;
public class HelloT2 {
public static void main(String[] args)throws Exception {
Context context = new InitialContext();
HelloI remote = (HelloI) context.lookup("HelloEJB");//resolves to mappedName @Stateless(name = "HelloWorldEJB", mappedName="HelloEJB"), from what I read could be glassfish and weblogic centric.
System.out.println(remote.sayHello(args[0]));
remote = (HelloI) context.lookup("java:global/ejb3_2_ear_exploded/ejb/HelloWorldEJB");//Portable should work on jboss and any container resolves to Stateless(name = "HelloWorldEJB"
System.out.println(remote.sayHello(args[0]));
}
}