无法在 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 - 包含 serverejbserverapi
  • 的 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());
    }

}

serverappclientapp部署到服务器。

点击 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 调用的文档。

配置可能看起来有点复杂,但这主要是出于安全原因。代码端还是比较简单的

我建议你参考这个,如果还有问题再问一个新问题。