1 2 Previous Next 26 Replies Latest reply on Mar 23, 2009 4:09 PM by Andrew Rubinger

    java.lan.ClassCastException when casting to remote bean inte

    Magnus Johansson Newbie

      I get a ClassCastException when trying to cast to a remote interface of stateful session bean (for some reason it works for the stateless ones..). To really pinpoint the problem I made the easiest project possible.

      At the server application I have the following bean

      @Stateful
      public class SimpleStatefulBean implements SimpleStatefulBeanRemote, SimpleStatefulBeanLocal {
      
       public SimpleStatefulBean() {
       }
      
       @Override
       public boolean isSimple() {
       return true;
       }
      }


      The remote interface looks like this:

      @Remote
      public interface SimpleStatefulBeanRemote {
       public boolean isSimple();
      }
      


      On the client side I have a web application. It is running on the same JBoss AS but is not deployed in the EAR as the bean above. I created a servlet to access the bean.
      In the doGet methods of the servlet..
       try {
       Properties p = new Properties();
       p.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
       p.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
       p.put("java.naming.provider.url", "localhost");
       Context ctx = new InitialContext(p);
       SimpleStatefulBeanRemote o = (SimpleStatefulBeanRemote) ctx.lookup("simpleserver/" + SimpleStatefulBean.class.getSimpleName() + "/remote");
       } catch (Exception e) {
       e.printStackTrace();
       }


      Now it does not work to cast it to the remote interface! I get the following error:

      19:53:27,164 ERROR [STDERR] java.lang.ClassCastException: $Proxy90 cannot be cast to com.test.SimpleStatefulBeanRemote
      19:53:27,165 ERROR [STDERR] at com.test.SimpleTestServlet.doGet(SimpleTestServlet.java:38)
      19:53:27,165 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
      19:53:27,165 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      19:53:27,165 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      19:53:27,165 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      19:53:27,165 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      19:53:27,165 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      19:53:27,165 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      .
      .
      .
      


      Can someone please help me??


        • 1. Re: java.lan.ClassCastException when casting to remote bean
          Andrew Rubinger Master

          Sounds like all the ingredients of a ClassLoading issue, ie. you've got SimpleStatefulBeanRemote defined in both the EAR and the WAR, hence loaded by different CLs, so CCE when trying to cast from one to the other?

          Classes are unique by both FQN and their CL.

          S,
          ALR

          • 2. Re: java.lan.ClassCastException when casting to remote bean
            Wolfgang Knauf Master

            I learned to use this code snippet to convert the JNDI lookup result to a remote interface:

            Object objRemote = ctx.lookup("simpleserver/" + SimpleStatefulBean.class.getSimpleName() + "/remote");
            
            SimpleStatefulBeanRemote o = (SimpleStatefulBeanRemote ) PortableRemoteObject.narrow(objRemote, SimpleStatefulBeanRemote .class);


            Andrew, is a direct cast supported in JBoss 5?

            Hope this helps

            Wolfgang

            • 3. Re: java.lan.ClassCastException when casting to remote bean
              Andrew Rubinger Master

               

              "Wolfgang Knauf" wrote:
              Andrew, is a direct cast supported in JBoss 5?


              More accurately, direct cast is supported by EJB3. EJB2.x Remote views is what dictated the PortableRemoteObject usage due to an underlying transport of IIOP.

              S,
              ALR

              • 4. Re: java.lan.ClassCastException when casting to remote bean
                Andrew Rubinger Master

                And it's always better to cite references. ;)

                "EJB3 Core Specification "3.2.3 Bullet 5" wrote:
                When the EJB 2.1 and earlier remote home and remote component interfaces are used, the narrowing of remote types requires the use of javax.rmi.PortableRemoteObject.narrow rather than Java language casts.


                S,
                ALR

                • 6. Re: java.lan.ClassCastException when casting to remote bean
                  Magnus Johansson Newbie

                  Thanks for the replies!

                  Yes, I figured that it was the class loading issue after reading a bunch of other posts (before posting the original topic). Sadly, I do not know how to remedy the problem.

                  When I look in the unpacked war I can see the interfaces the simple-ejb.jar file and there is another one unpacked in the .ear directory, The interface is identical although defined in two places and as far as I understand loaded by different class loaders - which is the root problem.

                  I tried your suggestion Wolfgang but can't see how it would help (I got the same exception). The problem is still the same.

                  Object o = ctx.lookup("simpleserver/" + SimpleStatefulBean.class.getSimpleName() + "/remote");
                  SimpleStatefulBeanRemote x = (SimpleStatefulBeanRemote) PortableRemoteObject.narrow(o, SimpleStatefulBeanRemote.class);
                  


                  08:48:36,061 ERROR [STDERR] java.lang.ClassCastException
                  08:48:36,062 ERROR [STDERR] at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229)
                  08:48:36,062 ERROR [STDERR] at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137)
                  


                  Could you give me some pointers on how to proceed?

                  br
                  Magnus

                  • 7. Re: java.lan.ClassCastException when casting to remote bean
                    jaikiran pai Master

                    Please post the output of

                    dir /b /s myunpackedapp.war


                    Also please post the JNDI tree output http://www.jboss.org/community/docs/DOC-9583


                    • 8. Re: java.lan.ClassCastException when casting to remote bean
                      Magnus Johansson Newbie

                      Output from "ls":

                      magnus@manexps:~/jboss-4.2.2.GA/server/default/tmp/deploy$ ls -laR tmp41571simple-webclient-exp.war/
                      tmp41571simple-webclient-exp.war/:
                      total 16
                      drwxr-xr-x 4 magnus magnus 4096 2008-11-20 10:11 .
                      drwxr-xr-x 12 magnus magnus 4096 2008-11-20 10:11 ..
                      drwxr-xr-x 2 magnus magnus 4096 2008-11-20 10:11 META-INF
                      drwxr-xr-x 4 magnus magnus 4096 2008-11-20 10:11 WEB-INF
                      
                      tmp41571simple-webclient-exp.war/META-INF:
                      total 12
                      drwxr-xr-x 2 magnus magnus 4096 2008-11-20 10:11 .
                      drwxr-xr-x 4 magnus magnus 4096 2008-11-20 10:11 ..
                      -rw-r--r-- 1 magnus magnus 102 2008-11-20 10:11 MANIFEST.MF
                      
                      tmp41571simple-webclient-exp.war/WEB-INF:
                      total 20
                      drwxr-xr-x 4 magnus magnus 4096 2008-11-20 10:11 .
                      drwxr-xr-x 4 magnus magnus 4096 2008-11-20 10:11 ..
                      drwxr-xr-x 3 magnus magnus 4096 2008-11-20 10:11 classes
                      drwxr-xr-x 2 magnus magnus 4096 2008-11-20 10:11 lib
                      -rw-r--r-- 1 magnus magnus 1073 2008-11-19 19:44 web.xml
                      
                      tmp41571simple-webclient-exp.war/WEB-INF/classes:
                      total 12
                      drwxr-xr-x 3 magnus magnus 4096 2008-11-20 10:11 .
                      drwxr-xr-x 4 magnus magnus 4096 2008-11-20 10:11 ..
                      drwxr-xr-x 3 magnus magnus 4096 2008-11-20 10:11 com
                      
                      tmp41571simple-webclient-exp.war/WEB-INF/classes/com:
                      total 12
                      drwxr-xr-x 3 magnus magnus 4096 2008-11-20 10:11 .
                      drwxr-xr-x 3 magnus magnus 4096 2008-11-20 10:11 ..
                      drwxr-xr-x 2 magnus magnus 4096 2008-11-20 10:11 test
                      
                      tmp41571simple-webclient-exp.war/WEB-INF/classes/com/test:
                      total 12
                      drwxr-xr-x 2 magnus magnus 4096 2008-11-20 10:11 .
                      drwxr-xr-x 3 magnus magnus 4096 2008-11-20 10:11 ..
                      -rw-r--r-- 1 magnus magnus 2005 2008-11-20 10:10 SimpleTestServlet.class
                      
                      tmp41571simple-webclient-exp.war/WEB-INF/lib:
                      total 12
                      drwxr-xr-x 2 magnus magnus 4096 2008-11-20 10:11 .
                      drwxr-xr-x 4 magnus magnus 4096 2008-11-20 10:11 ..
                      -rw-r--r-- 1 magnus magnus 1899 2008-11-20 10:11 simple-ejb.jar
                      


                      I understand that the problem lies in the simple-ejb.jar and the CL of the web client loads from this instead of from the simple-ejb.jar located in the unpacked ear directory.

                      I figure there are two solutions to this:
                      1. Remove the "simple-ejb.jar" file from the war archive. I tried this and this works! Now I just need to find the build/deploy scripts so I can remove the jar file automatically (any hints here?).

                      2. Force the CL to load the bean from the class definition from ear instead. I don't know how to do this...

                      Oh and BTW for some reason JNDIView is not present in my JMX console ?!


                      • 9. Re: java.lan.ClassCastException when casting to remote bean
                        jaikiran pai Master

                        I should have read your original post before responding :-) I missed the point that you have an EAR and a WAR file which are deployed separately. In such cases, you have to use classloader scoping for your applications. So the EAR (containing your simple-ejb.jar) should have a jboss-app.xml which configures the classloader for the application. Then your WAR (containing a simple-ejb-client.jar - note that you just need the remote/local interfaces in the jar. no need of the implementation) should have a jboss-web.xml which configures the classloader for the WAR. See this wiki for details http://www.jboss.org/community/docs/DOC-9288 (section "Specifying Isolation").

                        Oh and BTW for some reason JNDIView is not present in my JMX console ?!


                        Did you use the JEMS installer to install JBoss? If yes, see this https://jira.jboss.org/jira/browse/JBINSTALL-374

                        • 10. Re: java.lan.ClassCastException when casting to remote bean
                          Magnus Johansson Newbie

                          I followed what was said in

                          See this wiki for details http://www.jboss.org/community/docs/DOC-9288 (section "Specifying Isolation").


                          and added the following in my projects:

                          War: WEB-INF/jboss-web.xml

                          <?xml version="1.0" encoding="utf-8"?>
                          <jboss-web>
                           <loader-repository>
                           com.test:archive=simpleserver.ear
                           </loader-repository>
                          </jboss-web>


                          EAR: META-INF/jboss-app.xml

                          <?xml version="1.0" encoding="UTF-8"?>
                          <jboss-app>
                           <loader-repository>
                           com.test:archive=simpleserver.ear
                           </loader-repository>
                          </jboss-app>


                          ...but sadly it still doesn't work.

                          I also installed the zip-variant of JBoss to access JNDIView. Here is excerpt of it..


                          Global JNDI Namespace

                          +- TopicConnectionFactory (class: org.jboss.naming.LinkRefPair)
                           +- jmx (class: org.jnp.interfaces.NamingContext)
                           | +- invoker (class: org.jnp.interfaces.NamingContext)
                           | | +- RMIAdaptor (proxy: $Proxy47 implements interface org.jboss.jmx.adaptor.rmi.RMIAdaptor,interface org.jboss.jmx.adaptor.rmi.RMIAdaptorExt)
                           | +- rmi (class: org.jnp.interfaces.NamingContext)
                           | | +- RMIAdaptor[link -> jmx/invoker/RMIAdaptor] (class: javax.naming.LinkRef)
                           +- HTTPXAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
                           +- ConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
                           +- UserTransactionSessionFactory (proxy: $Proxy15 implements interface org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory)
                           +- HTTPConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
                           +- simpleserver (class: org.jnp.interfaces.NamingContext)
                           | +- SimpleStatefulBean (class: org.jnp.interfaces.NamingContext)
                           | | +- localStatefulProxyFactory (class: org.jboss.ejb3.stateful.StatefulLocalProxyFactory)
                           | | +- local (class: java.lang.Object)
                           | | +- remote (class: java.lang.Object)
                           | | +- remoteStatefulProxyFactory (proxy: $Proxy66 implements interface org.jboss.ejb3.ProxyFactory)
                           +- XAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
                           +- TransactionSynchronizationRegistry (class: com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionSynchronizationRegistryImple)
                           +- UserTransaction (class: org.jboss.tm.usertx.client.ClientUserTransaction)
                          



                          • 11. Re: java.lan.ClassCastException when casting to remote bean
                            jaikiran pai Master

                            You have a problem in your configuration files. The classloader repository name should be unique. In your jboss-web.xml and jboss-app.xml you are configuring classloaders with the same name. I would recommend you change the jboss-web.xml to:

                            <?xml version="1.0" encoding="utf-8"?>
                            <jboss-web>
                             <loader-repository>
                             com.test:archive=simplewebapp.war
                             </loader-repository>
                            </jboss-web>


                            and restart the server.

                            • 12. Re: java.lan.ClassCastException when casting to remote bean
                              jaikiran pai Master

                              And this is strange:

                              +- simpleserver (class: org.jnp.interfaces.NamingContext)
                               | +- SimpleStatefulBean (class: org.jnp.interfaces.NamingContext)
                               | | +- localStatefulProxyFactory (class: org.jboss.ejb3.stateful.StatefulLocalProxyFactory)
                               | | +- local (class: java.lang.Object)
                               | | +- remote (class: java.lang.Object)
                              


                              Which version of Java do you use? I would recommend using Java 1.5. And if you are using any IDE to deploy the application, i would recommend you switch to manual deployment till the issue is fixed.


                              • 13. Re: java.lan.ClassCastException when casting to remote bean
                                Magnus Johansson Newbie

                                Ok, changed that (and tried possible variations of the settings) but sadly I still get the CCE.

                                • 14. Re: java.lan.ClassCastException when casting to remote bean
                                  jaikiran pai Master

                                   

                                  "manemannen" wrote:
                                  Ok, changed that (and tried possible variations of the settings) but sadly I still get the CCE.



                                  Please provide few more details requested in my previous reply :-)

                                  1 2 Previous Next