IOException 编组 EJB 参数

IOException marshaling EJB parameters

我正在尝试从另一个 Web 应用程序(尤其是 Servlet)调用 ejb,并且两者都托管在同一个 JBoss AppServer 上。

如果我用 String/integer return-values/types 调用 ejb-methods,第一次看起来不错... 但是,如果我使用自定义 return 类型调用方法,那么我将得到 "IOException marshaling EJB parameters",尽管自定义 class 定义在 "WEB-INF/lib/" 上可用... 我认为这是一个大问题的小问题:-(

ejb项目结构: enter image description here 网络应用项目结构 enter image description here

远程 ejb classes 也链接到网络应用程序

远程:

package ma.remote;

import javax.ejb.Remote;


@Remote
public interface TestBeanRemote {
    public DataCenter getData();
    public String getStatus();

}

实施:

package ma.server;

import javax.ejb.Stateless;
import ma.remote.DataCenter;
import ma.remote.TestBeanRemote;


@Stateless
public class TestBeanImpl implements TestBeanRemote{

    @Override
    public DataCenter getData() {
        return new DataCenter("Lasname", "fistname", "examplestreet. 505", "berlin");
    }

    @Override
    public String getStatus() {
        String ret = "EJB funktioniert";
        System.out.println("public String getStatus():\n" + ret);

        return ret;
    }

}

自定义class:

package ma.remote;


public class DataCenter {
    public String Name;
    public String Vorname;
    public String Adresse;
    public String Stadt;

    public DataCenter(String Name, String Vorname, String Adresse, String Stadt)
    {
        this.Name = Name;
        this.Vorname = Vorname;
        this.Adresse = Adresse;
        this.Stadt = Stadt;
    }
}

webapp 和 ejb 在 JBoss 7.1

上成功部署
14:09:03,010 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) JBAS018565: Replaced deployment "ejb-ejb.jar" with deployment "ejb-ejb.jar"
    14:11:08,472 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-2) JBAS015877: Stopped deployment ejb-ejb.jar in 7ms
    14:11:08,472 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-3) JBAS015876: Starting deployment of "ejb-ejb.jar"
    14:11:08,487 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-3) JNDI bindings for session bean named TestBeanImpl in deployment unit deployment "ejb-ejb.jar" are as follows:

        java:global/ejb-ejb/TestBeanImpl!ma.remote.TestBeanRemote
        java:app/ejb-ejb/TestBeanImpl!ma.remote.TestBeanRemote
        java:module/TestBeanImpl!ma.remote.TestBeanRemote
        java:jboss/exported/ejb-ejb/TestBeanImpl!ma.remote.TestBeanRemote
        java:global/ejb-ejb/TestBeanImpl
        java:app/ejb-ejb/TestBeanImpl
        java:module/TestBeanImpl

    14:11:08,534 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) JBAS018565: Replaced deployment "ejb-ejb.jar" with deployment "ejb-ejb.jar"
    14:14:54,209 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-7) JBAS015877: Stopped deployment ejb-war.war in 20ms
    14:14:54,209 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-5) JBAS015876: Starting deployment of "ejb-war.war"
    14:14:54,334 INFO  [org.jboss.web] (MSC service thread 1-5) JBAS018210: Registering web context: /ejb-war
    14:14:54,381 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) JBAS018565: Replaced deployment "ejb-war.war" with deployment "ejb-war.war"

MyServlet 调用 ejb:

    package ma.remote;


import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class ejbTester extends HttpServlet {


    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet ejbTester</title>");
            out.println("</head>");
            out.println("<body>");


            try {
                Hashtable<String, String> jndiProperties = new Hashtable<String, String>();
                jndiProperties.put("java.naming.factory.url.pkgs", "org.jboss.ejb.client.naming");
                InitialContext context = new InitialContext(jndiProperties);
                String viewClassName = TestBeanRemote.class.getName();
                TestBeanRemote fbr = (TestBeanRemote) context.lookup("ejb:ejb-ejb/TestBeanImpl!" + viewClassName);
                //TestBeanRemote fbr = (TestBeanRemote) context.lookup("java:global/ejb-ejb/TestBeanImpl!" + viewClassName);

                //this will be invoked correctly
                String bn = fbr.getStatus();

                // but this one causes an exception!
                DataCenter dc = fbr.getData();
                out.println("DataCenter: " + dc.Name);
                out.println("message" + bn);
            } catch (NamingException e) 
            {
                System.out.println("\n EJB-Exception: \n" + e);
            }
            out.println("</body>");
            out.println("</html>");
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}

调用异常:localhost:8080/ejb-war/ejbTester :

14:24:50,650 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/ejb-war].[ejbTester]] (http--127.0.0.1-8080-1) Servlet.service() for servlet ejbTester threw exception: java.lang.RuntimeException: IOException marshaling EJB parameters
    at org.jboss.as.ejb3.remote.LocalEjbReceiver.clone(LocalEjbReceiver.java:227) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.remote.LocalEjbReceiver.clone(LocalEjbReceiver.java:216) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.remote.LocalEjbReceiver.processInvocation(LocalEjbReceiver.java:188) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:179) [jboss-ejb-client-1.0.5.Final.jar:1.0.5.Final]
    at org.jboss.ejb.client.TransactionInterceptor.handleInvocation(TransactionInterceptor.java:43) [jboss-ejb-client-1.0.5.Final.jar:1.0.5.Final]
    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181) [jboss-ejb-client-1.0.5.Final.jar:1.0.5.Final]
    at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:128) [jboss-ejb-client-1.0.5.Final.jar:1.0.5.Final]
    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181) [jboss-ejb-client-1.0.5.Final.jar:1.0.5.Final]
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136) [jboss-ejb-client-1.0.5.Final.jar:1.0.5.Final]
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121) [jboss-ejb-client-1.0.5.Final.jar:1.0.5.Final]
    at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104) [jboss-ejb-client-1.0.5.Final.jar:1.0.5.Final]
    at com.sun.proxy.$Proxy18.getData(Unknown Source)
    at ma.servlets.ejbTester.processRequest(ejbTester.java:42) [classes:]
    at ma.servlets.ejbTester.doGet(ejbTester.java:66) [classes:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_40]
Caused by: java.io.NotSerializableException: ma.remote.DataCenter
    at org.jboss.marshalling.cloner.SerializingCloner.clone(SerializingCloner.java:256)
    at org.jboss.marshalling.cloner.SerializingCloner.clone(SerializingCloner.java:135)
    at org.jboss.as.ejb3.remote.LocalEjbReceiver.clone(LocalEjbReceiver.java:225) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    ... 28 more

有人知道我的 code/structure 出了什么问题并可以帮助我吗?

谢谢!

您已经定义了一个 远程 EJB,这意味着您的目标是拥有一个分布式系统,您必须通过网络将对象传输到 不同的JVM。所以你的 POJO 必须是可序列化的,所以 ma.remote.DataCenter 必须实现 Serializable 接口。

public class DataCenter implements Serializable {
    /** The serial version UID. */
    private static final long serialVersionUID = 1L;

    // attributes, getters and setters...

}