无法在 JBoss EAP 7 上注入远程 bean:ClassCastException
Unable to inject remote bean on JBoss EAP 7: ClassCastException
我有两个 Maven Java 应用程序 运行 在两个不同的 Jboss EAP 7 实例上,我们将它们命名为 Client-Application , Server-Application。
我想对客户端应用程序进行远程注入,从服务器应用程序注入一个 bean。
我的结构如下:
客户端应用程序
我添加了以下 Maven 依赖项:
<dependency>
<groupId>org.jboss.eap</groupId>
<artifactId>wildfly-ejb-client-bom</artifactId>
<type>pom</type>
</dependency>
我的主要 class 和此应用程序的界面如下所示:
public void remoteInjectionTest() {
try {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProperties.put("java.naming.factory.initial", "org.jboss.as.naming.InitialContextFactory");
jndiProperties.put("java.naming.provider.url", "localhost");
jndiProperties.put("jboss.naming.client.ejb.context", "true");
Context context = new InitialContext(jndiProperties);
String jndi = "java:global/Server-Application/ServiceBean!test.package.ServiceBeanInterface";
serviceInterface = (ServiceBeanInterface) context.lookup(jndi);
return serviceInterface.getHelloString();
} catch (NamingException e) {
e.printStackTrace();
}
}
和界面:
public interface ServiceBeanInterface {
public String getHelloString();
}
服务器应用程序
本节显示我的服务器应用程序的外观:
@Stateless
@Remote(ServiceBeanInterface.class)
public class ServiceBean implements ServiceBeanInterface {
@Override
public String getHelloString() {
return "Hello";
}
}
我也尝试在服务器应用程序界面上添加一个@Remote,但还是没有成功。
@Remote
public interface ServiceBeanInterface {
public String getHelloString();
}
有什么建议吗?
我得到的错误是:
Caused by: java.lang.ClassCastException: com.sun.proxy.$Proxy118
cannot be cast to test.package.ServiceBeanInterface
假设您的 Client-Application 也在您的 JBoss EAP 7 实例上 deployed,那么解决方案很远比你想象的要简单。
我设置了一个创建四个工件的测试项目:
- serverapi - 包含
ServiceBeanInterface
- serverejb - 包含
ServiceBean
- serverapp - 包含
serverejb
和 serverapi
的 EAR
- clientapp - WAR 包含一个 servlet(如下所示)和
serverapi
在它的 WEB-INF/lib 目录中
测试 servlet 如下所示:
@WebServlet(urlPatterns = "/")
public class Client extends HttpServlet {
// Inject remote stub
@EJB(lookup="java:global/serverapp-1.0-SNAPSHOT/serverejb-1.0-SNAPSHOT/ServiceBean!com.Whosebug.p42618757.api.ServiceBeanInterface")
private ServiceBeanInterface serviceBeanInterface;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write(serviceBeanInterface.getHelloString());
}
}
serverapp
和clientapp
部署到服务器。
点击 http://localhost:8080/clientapp-1.0-SNAPSHOT/ 会产生预期的 Hello
。
不需要老式的 JNDI 查找。
然而,如果你真的想做一个 JNDI 查找,那么你只需要:
Context initialContext = new InitialContext(); // no props needed in the same server instance
ServiceBeanInterface serviceBeanInterface
= (ServiceBeanInterface)initialContext.lookup("java:global/serverapp-1.0-SNAPSHOT/serverejb-1.0-SNAPSHOT/ServiceBean!com.Whosebug.p42618757.api.ServiceBeanInterface");
可在 GitHub 上找到演示示例。
在 EJB invocations from a remote server instance 的 JBoss 文档站点上有大量关于执行实例到实例远程 EJB 调用的文档。
配置可能看起来有点复杂,但这主要是出于安全原因。代码端还是比较简单的
我建议你参考这个,如果还有问题再问一个新问题。
我有两个 Maven Java 应用程序 运行 在两个不同的 Jboss EAP 7 实例上,我们将它们命名为 Client-Application , Server-Application。
我想对客户端应用程序进行远程注入,从服务器应用程序注入一个 bean。
我的结构如下:
客户端应用程序
我添加了以下 Maven 依赖项:
<dependency>
<groupId>org.jboss.eap</groupId>
<artifactId>wildfly-ejb-client-bom</artifactId>
<type>pom</type>
</dependency>
我的主要 class 和此应用程序的界面如下所示:
public void remoteInjectionTest() {
try {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProperties.put("java.naming.factory.initial", "org.jboss.as.naming.InitialContextFactory");
jndiProperties.put("java.naming.provider.url", "localhost");
jndiProperties.put("jboss.naming.client.ejb.context", "true");
Context context = new InitialContext(jndiProperties);
String jndi = "java:global/Server-Application/ServiceBean!test.package.ServiceBeanInterface";
serviceInterface = (ServiceBeanInterface) context.lookup(jndi);
return serviceInterface.getHelloString();
} catch (NamingException e) {
e.printStackTrace();
}
}
和界面:
public interface ServiceBeanInterface {
public String getHelloString();
}
服务器应用程序 本节显示我的服务器应用程序的外观:
@Stateless
@Remote(ServiceBeanInterface.class)
public class ServiceBean implements ServiceBeanInterface {
@Override
public String getHelloString() {
return "Hello";
}
}
我也尝试在服务器应用程序界面上添加一个@Remote,但还是没有成功。
@Remote
public interface ServiceBeanInterface {
public String getHelloString();
}
有什么建议吗?
我得到的错误是:
Caused by: java.lang.ClassCastException: com.sun.proxy.$Proxy118 cannot be cast to test.package.ServiceBeanInterface
假设您的 Client-Application 也在您的 JBoss EAP 7 实例上 deployed,那么解决方案很远比你想象的要简单。
我设置了一个创建四个工件的测试项目:
- serverapi - 包含
ServiceBeanInterface
- serverejb - 包含
ServiceBean
- serverapp - 包含
serverejb
和serverapi
的 EAR
- clientapp - WAR 包含一个 servlet(如下所示)和
serverapi
在它的 WEB-INF/lib 目录中
测试 servlet 如下所示:
@WebServlet(urlPatterns = "/")
public class Client extends HttpServlet {
// Inject remote stub
@EJB(lookup="java:global/serverapp-1.0-SNAPSHOT/serverejb-1.0-SNAPSHOT/ServiceBean!com.Whosebug.p42618757.api.ServiceBeanInterface")
private ServiceBeanInterface serviceBeanInterface;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write(serviceBeanInterface.getHelloString());
}
}
serverapp
和clientapp
部署到服务器。
点击 http://localhost:8080/clientapp-1.0-SNAPSHOT/ 会产生预期的 Hello
。
不需要老式的 JNDI 查找。
然而,如果你真的想做一个 JNDI 查找,那么你只需要:
Context initialContext = new InitialContext(); // no props needed in the same server instance
ServiceBeanInterface serviceBeanInterface
= (ServiceBeanInterface)initialContext.lookup("java:global/serverapp-1.0-SNAPSHOT/serverejb-1.0-SNAPSHOT/ServiceBean!com.Whosebug.p42618757.api.ServiceBeanInterface");
可在 GitHub 上找到演示示例。
在 EJB invocations from a remote server instance 的 JBoss 文档站点上有大量关于执行实例到实例远程 EJB 调用的文档。
配置可能看起来有点复杂,但这主要是出于安全原因。代码端还是比较简单的
我建议你参考这个,如果还有问题再问一个新问题。