6 Replies Latest reply on Jul 26, 2006 5:31 PM by cuoz

    ClassCastException accessing EJB3 from portlet

      Hi all,

      I posted this to the EJB3 forum originally, but just tested my app using a plain WAR file and it works fine, so I think it is something related to classloading and my portlet...

      I'm trying to use my EJB3 application from a JBoss Portal portlet and getting the infamous ClassCastException. I have read all the wiki & other resources on classloading, etc, but have not been able to solve this one.

      Specifics are: JBoss 4.0.4GA, Portal 2.4-CR2, EJB3 RC8.

      I have packaged the ejb3 application and the portlet application in separate ear files (originally tried using just a war for the portlet), and have also tried scoped loader repositories. The portlet includes a jar file of only the client parts of my ejb3 application. I have JBossAS configured for call by value, etc.

      Here are application specifics:
      ClientEJB is an entity that implements Client interface
      ClientSessionBean is a SLSB
      ClientSessionLocal is the local interface to the session bean
      The method I am calling on the session bean is:
      Client createClient(String username, String password)

      It creates an instance of ClientEJB, persists it, and returns it as a Client interface.

      The call to the session bean works fine. I get the CCE when I try to use the returned object as a Client and not a ClientEJB.

      What should I be doing to make this work? Hopefully somebody already ran into this scenario and can help. Let me know if you need more information.

      Thank you in advance,
      Gary.

        • 1. Re: ClassCastException accessing EJB3 from portlet
          soshah

          Gary-

          Can you post a representation of how both your ear files are packaged?

          Thanks
          Sohil

          • 2. Re: ClassCastException accessing EJB3 from portlet
            unibrew

            My guess would be that you are packaging Client.class in both ears and you should have it only in ejb3 package.

            • 3. Re: ClassCastException accessing EJB3 from portlet
              soshah

              Since the exception is happening in the Portal layer (in the Portlet) wouldn't the Client.class have to be in the ear file that holds the portlet.

              which from your post looks like you are packaging it in the portlet ear.

              Again, information on how the two files are packaged will throw more light on the issue

              • 4. Re: ClassCastException accessing EJB3 from portlet

                Thank you for the responses. Here is the packaging details:

                for the EJB3 deployment:
                panel-server.ejb3:
                class files for both client & server
                META-INF/persistence.xml
                META-INF/jboss.xml (security domain declaration)

                for the portlet deployment:
                panel-email.war:
                WEB-INF/classes (portlet related classes)
                WEB-INF/lib/panel-client.jar (client jar for session & interfaces)
                WEB-INF/email-object.xml
                WEB-INF/portlet-instances.xml
                WEB-INF/portlet.xml
                WEB-INF/web.xml

                unibrew: you indicated that I should not have client classes in both places, but my past experience (regular webapps, not portlets) is that to hot-deploy and not affect multiple applications I need to have them in both places and have call-by-value & such configured (which I believe I do). I am able to do this with my regular test war file.

                My goal is to have appropriate packaging to allow updates to the EJB3 application without needed to redeploy all the portlets & other applications (jbpm will be in the mix also).

                Thank you for the help,
                gary.

                • 5. Re: ClassCastException accessing EJB3 from portlet
                  unibrew

                  So, you can have Client.class just in war files. ejb3 archive could still be hot-deployed at any time as far as the class still implements Client interface. Call-by-value has nothing with it because if you deploy Client.class in different packages then it has got different classloaders which causes that they are not the same class for JVM and cannot be casted.

                  Sohil gave an idea to move classes from your lib jar to WEB-INF/classes and check whether it works.

                  Moreover, we don't see any application.xml in this ear definition. Maybe you could achieve loading lib jar only once by defining it there.

                  • 6. Re: ClassCastException accessing EJB3 from portlet

                    Ok, I made progress and got it to "work", but it's not 100% of what I was hoping for. Here's what I did, maybe there is a way to improve on it to obtain my ultimate goal.

                    1. I packaged all of the applications into their own ear files, with loader-repository entries in jboss-app.xml.
                    2. I switched from local interfaces to remote
                    3. I needed to include the server classes (ClientEJB) as well as the client classes with the web application.
                    4. I tested this setup with a portlet and also a full webapp. I was able to hot deploy any piece(s) that I wanted without affecting operation of the others.

                    The only drawback is that I needed to have all the server classes in the client applications. I'm guessing that I didn't have to do this with my EJB2.1 application because I was actually dealing with proxies for the home & local/remote interfaces.

                    At some point I'll test to see if I actually need the loader-repository entries or not.

                    Thanks again for the assistance. Let me know if you have better ideas for how to accomplish what I'm looking for.

                    Gary.