Jakarta ee 无法在JBoss EAP 7:ClassCastException上注入远程bean

Jakarta ee 无法在JBoss EAP 7:ClassCastException上注入远程bean,jakarta-ee,jboss,ejb,javabeans,ejb-3.1,Jakarta Ee,Jboss,Ejb,Javabeans,Ejb 3.1,我有两个maven Java应用程序运行在两个不同的Jboss EAP 7实例上,让我们把它们命名为客户机应用程序、服务器应用程序 我想在客户端应用程序上进行远程注入,从服务器应用程序注入bean 我的结构如下: public void remoteInjectionTest() { try { final Hashtable jndiProperties = new Hashtable(); jndiProperties.put(Context.UR

我有两个maven Java应用程序运行在两个不同的Jboss EAP 7实例上,让我们把它们命名为客户机应用程序、服务器应用程序

我想在客户端应用程序上进行远程注入,从服务器应用程序注入bean

我的结构如下:

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();
    }

}
客户端应用程序

我添加了以下maven依赖项:

<dependency>
    <groupId>org.jboss.eap</groupId>
    <artifactId>wildfly-ejb-client-bom</artifactId>
    <type>pom</type>
</dependency>
以及界面:

public interface ServiceBeanInterface {

    public String getHelloString();

}
服务器应用程序 本节显示我的服务器应用程序的外观:

@Stateless
@Remote(ServiceBeanInterface.class)
public class ServiceBean implements ServiceBeanInterface {

    @Override
    public String getHelloString() {
        return "Hello";
    }

}
@WebServlet(urlPatterns = "/")
public class Client extends HttpServlet {

    // Inject remote stub
    @EJB(lookup="java:global/serverapp-1.0-SNAPSHOT/serverejb-1.0-SNAPSHOT/ServiceBean!com.stackoverflow.p42618757.api.ServiceBeanInterface")
    private ServiceBeanInterface serviceBeanInterface;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write(serviceBeanInterface.getHelloString());
    }

}
我还试图在服务器应用程序界面上添加一个@Remote,但同样没有成功

@Remote
 public interface ServiceBeanInterface {
    public String getHelloString();
 }
有什么建议吗

我得到的错误是:

原因:java.lang.ClassCastException:com.sun.proxy.$Proxy118 无法强制转换为test.package.ServiceBeanInterface


假设您的客户端应用程序也部署在JBoss EAP 7实例上,那么解决方案比您想象的要简单得多

我建立了一个测试项目,创建了四个工件:

  • serverapi-包含
    ServiceBeanInterface
  • serverejb-包含
    ServiceBean
  • serverapp-EAR包含
    serverejb
    serverapi
  • clientapp-WAR包含一个servlet(如下所示)和它的WEB-INF/lib目录中的
    serverapi
测试servlet如下所示:

@Stateless
@Remote(ServiceBeanInterface.class)
public class ServiceBean implements ServiceBeanInterface {

    @Override
    public String getHelloString() {
        return "Hello";
    }

}
@WebServlet(urlPatterns = "/")
public class Client extends HttpServlet {

    // Inject remote stub
    @EJB(lookup="java:global/serverapp-1.0-SNAPSHOT/serverejb-1.0-SNAPSHOT/ServiceBean!com.stackoverflow.p42618757.api.ServiceBeanInterface")
    private ServiceBeanInterface serviceBeanInterface;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write(serviceBeanInterface.getHelloString());
    }

}
serverapp
clientapp
部署到服务器

点击会产生预期的
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.stackoverflow.p42618757.api.ServiceBeanInterface");

可以在上找到演示示例。

假设您的客户端应用程序也部署在您的JBoss EAP 7实例上,那么解决方案比您想象的简单得多

我建立了一个测试项目,创建了四个工件:

  • serverapi-包含
    ServiceBeanInterface
  • serverejb-包含
    ServiceBean
  • serverapp-EAR包含
    serverejb
    serverapi
  • clientapp-WAR包含一个servlet(如下所示)和它的WEB-INF/lib目录中的
    serverapi
测试servlet如下所示:

@Stateless
@Remote(ServiceBeanInterface.class)
public class ServiceBean implements ServiceBeanInterface {

    @Override
    public String getHelloString() {
        return "Hello";
    }

}
@WebServlet(urlPatterns = "/")
public class Client extends HttpServlet {

    // Inject remote stub
    @EJB(lookup="java:global/serverapp-1.0-SNAPSHOT/serverejb-1.0-SNAPSHOT/ServiceBean!com.stackoverflow.p42618757.api.ServiceBeanInterface")
    private ServiceBeanInterface serviceBeanInterface;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write(serviceBeanInterface.getHelloString());
    }

}
serverapp
clientapp
部署到服务器

点击会产生预期的
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.stackoverflow.p42618757.api.ServiceBeanInterface");

可以在上找到一个演示示例。

在JBoss文档站点上有大量关于执行实例到实例远程EJB调用的文档

配置可能看起来有点复杂,但这主要是出于安全原因。代码方面仍然相对简单


我建议您参考这一点,然后如果仍然有问题,可以问一个新的问题。

在JBoss文档站点上有大量关于执行实例到实例远程EJB调用的文档

配置可能看起来有点复杂,但这主要是出于安全原因。代码方面仍然相对简单


我建议您参考这一点,如果仍然有问题,请提出新问题。

否,它们将在不同的实例上运行。所以我需要找到我的查找不起作用的原因。我在你的回答中遗漏了一步。在lib目录中包含serverapi。怎样?创建接口的jar并将其与maven一起添加到构建路径?我发现单独的API jar最适合远程EJB接口。现在,您的第一句话是“…两个maven Java应用程序运行在同一个Jboss EAP 7实例上…”,如果不是这样,请用正确的细节更新您的问题。例如,客户机是一个独立的java应用程序吗?我不知怎么被卡住了。我创建了一个只包含接口(ServiceBeanInterface)的新maven项目,并将其作为maven依赖项添加到客户端应用程序中。我仍然得到classcast异常。我读到其他人试图做类似的事情,他们可以通过删除@Remote注释或修复命名来修复它。看起来我的项目与此不同。我尝试在同一个实例下使用@EJB(“java:global/Server-Application/ServiceBean!test.package.servicebeanterface”)进行测试注释,但这给了我以下异常:原因:java.lang.IllegalStateException:WFLYEE0042:构造组件实例失败我尝试复制接口,但成功了。然后我在客户端更改了接口所在的包,得到了与您相同的WFLYEE0042错误。因此,如果复制接口,它必须是服务器端版本的二进制匹配。这就是为什么将它放在自己的jar中更安全。不,它们将在不同的实例上运行。所以我需要找到我的查找不起作用的原因。我在你的回答中遗漏了一步。在lib目录中包含serverapi。怎样?创建接口的jar并将其与maven一起添加到构建路径?我发现单独的API jar最适合远程EJB接口。现在,您的第一句话是“…两个maven Java应用程序运行在同一个Jboss EAP 7实例上…”,如果不是这样,请用正确的细节更新您的问题。例如,客户机是一个独立的java应用程序吗?我不知怎么被卡住了。我创建了一个只包含接口(ServiceBeanInterface)的新maven项目,并将其作为maven依赖项添加到客户端应用程序中。我仍然得到classcast异常。我读到其他人试图做类似的事情,他们可以通过删除@Remote注释或修复命名来修复它。看起来这与我的项目不同,我尝试在同一个实例下使用@EJB(“java:global/Server-Application/Servic”)进行测试