EJB 远程客户端从 JBoss AS 7.1 迁移到 Wildfly 8.1
EJB remote client migration from JBoss AS 7.1 to Wildfly 8.1
我们开发了一个培训应用程序,其中包含与 EJB 通信的独立 java 客户端。工作设置包括 JBoss AS 7.1 on Windows 7 和通过 /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 的文章(例如 this or that) or samples or the Wildfly Developer Guide,但所有替代方案,可能是最小的 JNDI 属性或通过 ClientContext 进行的扩展配置并没有使其工作。
所以我的问题是,将上面的 code/configuration 迁移到 WildFly 下的 运行 需要做什么?
注意:这不是生产代码,因此安全性不是问题 - 如果我可以简化整个配置,那很好 - 它应该只演示如何从独立 Java 使用 EJB 远程接口程序。
提供商 URL 应该是 http-remoting://localhost:8080
而不是 remote://localhost:4447
您需要进行两项更改
而不是使用 "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");
此解决方案已经过测试并有效
我正在使用:
- wildfly-10.0.0.Final(JBoss 应用程序服务器)。
对我有用:
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");
希望对您有所帮助!
这是我的项目 "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),所以需要导入jboss-client.jar at wildfly-10.0.0.Final\bin\client\文件夹。
我们开发了一个培训应用程序,其中包含与 EJB 通信的独立 java 客户端。工作设置包括 JBoss AS 7.1 on Windows 7 和通过 /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 的文章(例如 this or that) or samples or the Wildfly Developer Guide,但所有替代方案,可能是最小的 JNDI 属性或通过 ClientContext 进行的扩展配置并没有使其工作。
所以我的问题是,将上面的 code/configuration 迁移到 WildFly 下的 运行 需要做什么?
注意:这不是生产代码,因此安全性不是问题 - 如果我可以简化整个配置,那很好 - 它应该只演示如何从独立 Java 使用 EJB 远程接口程序。
提供商 URL 应该是 http-remoting://localhost:8080
而不是 remote://localhost:4447
您需要进行两项更改
而不是使用 "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");
此解决方案已经过测试并有效
我正在使用:
- wildfly-10.0.0.Final(JBoss 应用程序服务器)。
对我有用:
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");
希望对您有所帮助!
这是我的项目 "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),所以需要导入jboss-client.jar at wildfly-10.0.0.Final\bin\client\文件夹。