4 Replies Latest reply on Oct 4, 2006 5:11 AM by manish.java

    EJB Strange ClassCastException

      Hi.
      I have a very strange ClassCastException that I'm going to try to explain in detail.
      I have an EAR application, with a WAR, an EJB JAR and some other JARs.
      The structure is like that:

      App.EAR:

      WebApp.war (struts files and jsps)
      App.jar (business objects and business rules)
      EJBApp.jar (bridge to access App.jar remotely)
      otherjar1.jar
      otherjar2.jar
      ..............

      The project evolved in this way. I had a web application, and possibly, they told me that another application could call this application remotely through an EJB. So, I made an EAR application with a WAR (with struts and jsps) and a JAR with all my business code. In this way, the action classes of the WAR call the business Java classes of the App.JAR.
      By the way, the MANIFEST.MF of the WAR file has a list of all the jars used in the application,i.e., App.jar and the rest of the other tools jars. In this way, these classes would be visibles from any part of the application.
      The next step, was that I had to create and EJB for the other application. The functionality would be the same between both applications (my original web application and the remote application). In this way, my web application gives the same functionality that the remote Swing application that access through the EJB.

      Web Application ->(access) Business Rules (App.jar through WAR)
      Swing Application -> (access) Business Rules (App.jar through EJB)

      For the EJB I use the Command Pattern. This is (basically) the code of the EJB:

      public Command executeCommand(Command comando) throws EJBException {
       try {
       comando.execute();
       } catch (AppException ex) {
       throw new EJBException(ex);
       }
       return comando;
       }
      

      So, to make a functionality, I use the next Command class (I only show the execute method code) that I pass to the EJB as the Command argument:
      public void execute() throws AppException {
       Session session = null;
       JbpmSession jbpmSession = null;
       try {
       session = PersistenceUtil.getSession();
       jbpmSession = PersistenceUtil.getJbpmSession();
      
       if(getTercero().getDni() != null && !"".equals(getTercero().getDni())){
       UsuarioDAOHibernateImpl usuarioDAO = new UsuarioDAOHibernateImpl();
       if(usuarioDAO.getTerceroByDNI(new Long(getTercero().getDni()).longValue()) != null){
       this.setTercero(usuarioDAO.getTerceroByDNI(new Long(getTercero().getDni()).longValue(), session));
       ProcessInstanceDAOHibernateImpl processInstanceDAO = new ProcessInstanceDAOHibernateImpl();
       setTramitesTercero(processInstanceDAO.getTramitesTercero(usuarioDAO.getTerceroByDNI(new Long(getTercero().getDni()).longValue()).getDni(), session, jbpmSession));
       }
       }
       } catch (Exception e) {
       throw new AppException(e);
       }finally{
       try {
       PersistenceUtil.closeJbpmSession(jbpmSession);
       PersistenceUtil.closeSession(session);
       } catch (InfrastructureException e) {
       throw new AppException("Error al intentar cerrar las sesiones de Hibernate (Session y JbpmSession)", e);
       }
       }
       }
      

      Note: As you can see, my application uses Hibernate and Jbpm.
      Well. When I try to execute the functionality through the web tier all goes well.But when I try to test the EJB through a JUnit Test (a standalone application from my Eclipse IDE), I get a ClassCastExcpetion in the next point. When the execute code shown earlier is in

      usuarioDAO.getTerceroByDNI(new Long(getTercero().getDni()).longValue(), session)
      


      I get the ClassCastException.
      The UsuarioDAOHibernateImpl is a business plain java class that resides in the App.jar.
      The UsuarioDAOHibernateImpl.getTerceroByDNI method code is as follows:

      public Tercero getTerceroByDNI(long dni, Session session){
       // Se crea la query con los parametros
       Tercero tercero = null;
       Query q = session.createQuery("from Tercero t where t.dni=:dni");
       q.setLong("dni",dni);
       tercero = (Tercero)q.uniqueResult();
       return tercero;
       }
      

      The ClassCastException is thrown in this line
      tercero = (Tercero)q.uniqueResult();
      

      Note: The Tercero class is a POJO class that resides in the App.jar.
      I don't understand this ClassCastException.
      I thought that as I have specified in the MANIFEST.MF, the classes in the App.jar would be shared by all the application (in classloading terms).
      My unique suspicion was that the Session (org.hibernate.Session) parameter object in the above code was obtained in different way from the web application (all works well in the web application) that through the EJB. But I've debugged the application, I've used the jmx-console to observe the UCL used to load all the objects involved in the execution and in both cases (through the web and through the EJB) I get the same UCLs for all the classes, but only through the EJB I obtain the ClassCastException.
      Any help or suggestion will be very very welcome!!
      I'm getting crazy!!!
      Thanks to all.

        • 1. Re: EJB Strange ClassCastException
          darranl

          You missed one important piece of information in this post, not all ClassCastExceptions are equal!! Can you post the exception with message and stack trace.

          • 2. Re: EJB Strange ClassCastException

            OK.
            I think this is the typical case when the class bytecode is equal, but the classes are loaded by different classloaders (if this was not the case, the web application would fail and the application only fails when I access it through the EJB).
            In any case, here is the trace of the exception:

            14:34:37,859 ERROR [LogInterceptor] EJBException in method: public abstract org.ildefe.webfciobusiness.command.interfaces.Command org.ildefe.ejb.interfaces.WorkFlow.executeCommand(org.ildefe.webfciobusiness.command.interfaces.Command) throws java.rmi.RemoteException,javax.ejb.EJBException, causedBy:
            org.ildefe.webfciobusiness.exceptions.AppException
             at org.ildefe.webfciobusiness.command.impl.TerceroCommand.execute(TerceroCommand.java:61)
             at org.ildefe.ejb.impl.WorkFlow.executeCommand(WorkFlow.java:69)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:324)
             at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
             at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:214)
             at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:185)
             at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:130)
             at org.jboss.webservice.server.ServiceEndpointInterceptor.invoke(ServiceEndpointInterceptor.java:51)
             at org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:48)
             at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:105)
             at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:335)
             at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:166)
             at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:139)
             at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
             at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
             at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:624)
             at org.jboss.ejb.Container.invoke(Container.java:873)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:324)
             at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:141)
             at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
             at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
             at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:249)
             at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
             at org.jboss.invocation.jrmp.server.JRMPInvoker$MBeanServerAction.invoke(JRMPInvoker.java:805)
             at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:406)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:324)
             at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
             at sun.rmi.transport.Transport$1.run(Transport.java:148)
             at java.security.AccessController.doPrivileged(Native Method)
             at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
             at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
             at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
             at java.lang.Thread.run(Thread.java:534)
            Caused by: java.lang.ClassCastException
             at org.ildefe.webfciobusiness.dao.impl.UsuarioDAOHibernateImpl.getTerceroByDNI(UsuarioDAOHibernateImpl.java:83)
             at org.ildefe.webfciobusiness.command.impl.TerceroCommand.execute(TerceroCommand.java:53)
             ... 41 more
            Causada por:
            java.lang.ClassCastException
             at org.ildefe.webfciobusiness.dao.impl.UsuarioDAOHibernateImpl.getTerceroByDNI(UsuarioDAOHibernateImpl.java:83)
             at org.ildefe.webfciobusiness.command.impl.TerceroCommand.execute(TerceroCommand.java:53)
             at org.ildefe.ejb.impl.WorkFlow.executeCommand(WorkFlow.java:69)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:324)
             at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
             at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:214)
             at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:185)
             at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:130)
             at org.jboss.webservice.server.ServiceEndpointInterceptor.invoke(ServiceEndpointInterceptor.java:51)
             at org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:48)
             at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:105)
             at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:335)
             at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:166)
             at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:139)
             at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
             at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
             at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:624)
             at org.jboss.ejb.Container.invoke(Container.java:873)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:324)
             at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:141)
             at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
             at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
             at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:249)
             at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
             at org.jboss.invocation.jrmp.server.JRMPInvoker$MBeanServerAction.invoke(JRMPInvoker.java:805)
             at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:406)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:324)
             at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
             at sun.rmi.transport.Transport$1.run(Transport.java:148)
             at java.security.AccessController.doPrivileged(Native Method)
             at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
             at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
             at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
             at java.lang.Thread.run(Thread.java:534)
            

            The UsuarioDAOHibernateImpl.java:83 line is the line I showed in the past topic:
            tercero = (Tercero)q.uniqueResult();
            


            IMPORTANT: The actual code of the execute method of the Command class is:
            public void execute() throws AppException {
             Session session = null;
             JbpmSession jbpmSession = null;
             try {
             session = PersistenceUtil.getSession();
             jbpmSession = PersistenceUtil.getJbpmSession();
            
             if(getTercero().getDni() != null && !"".equals(getTercero().getDni())){
             UsuarioDAOHibernateImpl usuarioDAO = new UsuarioDAOHibernateImpl();
             Tercero terceroBBDD = usuarioDAO.getTerceroByDNI(new Long(getTercero().getDni()).longValue(), session);
             if(terceroBBDD != null){
             setTercero(terceroBBDD);
             ProcessInstanceDAOHibernateImpl processInstanceDAO = new ProcessInstanceDAOHibernateImpl();
             setTramitesTercero(processInstanceDAO.getTramitesTercero(terceroBBDD.getDni(), session, jbpmSession));
             }
             }
             } catch (Exception e) {
             throw new AppException(e);
             }finally{
             try {
             PersistenceUtil.closeJbpmSession(jbpmSession);
             PersistenceUtil.closeSession(session);
             } catch (InfrastructureException e) {
             throw new AppException("Error al intentar cerrar las sesiones de Hibernate (Session y JbpmSession)", e);
             }
             }
             }
            

            It's similar that the first topic, although with less redundant code.
            The TerceroCommand execute method, line 53 is
            Tercero terceroBBDD = usuarioDAO.getTerceroByDNI(new Long(getTercero().getDni()).longValue(), session);
            


            • 3. Re: EJB Strange ClassCastException

              Hi, all.
              It works well!!
              I was using MyEclipse to create the EAR of my application.
              By default, the MyEclipse adds the dependant Java projects (in this case, the App.jar, where resides my business rules) to the WEB-INF/lib of the WAR file.
              I've changed this default behaviour and now it works (one of the class where I was getting the ClassCastException was loaded by the WebClassloader).

              • 4. Re: EJB Strange ClassCastException
                manish.java

                Hi,

                I am facing the exactly same exception.
                I am using ANT BUILD instead of MyEclipse.
                I dont found any dependent java project in it.

                what could be the cause than?

                Please help me to come out from this....