10 Replies Latest reply on Jul 3, 2008 2:44 AM by tomaszdyszy

    Classcast Exception $Proxy thing

    michaelralston

      I was using EJB3 early last year, and since then a bunch of things have changed.

      I'm now having a problem getting access to my Stateless Bean, when I look it up in the InitialContext, it is returning a $ProxyXX object. This is how I remember it working some time ago. But when I try and cast this object to its interface I get a class cast exception.

      I've seen this question asked many times before and I've read through the answers and tried to get it to work as best I could but I've gotten nowhere.

      I have made an interface (Manager) which is @Local, I've then made an @Stateless (ManagerBean) which implements the interface. The @Stateless is deployed in a JAR file. The interface is then copied into a WAR file where I am trying to get the Bean from the InitialContext.

      Last year I was successfully using this:
      Manager me=(Manager)ctx.lookup(Manager.class.getName();

      That now fails to find my bean and I have tried using this:
      Manager me=(Manager)ctx.lookup("ManagerBean/local");

      That is returning the proxy object which will then not cast properly. I've looked through the attributes of the proxy object in the eclipse debugged and it appears to be the ManagerBean which I am trying to access.

      I've ran the tutorial's against my JBoss installation and they are working. I've also tried using the remote interface with no luck. Is it something to do with the object not serializing properly so it no longer knows what class it is after I've looked it up?

      Should there be certain JARs included in my WAR that will allow the class to de-Serialize properly after getting it from jndi?

      Using JBoss-4.0.4.cr2... Will provide source code if that will help diagnose my problem.

        • 1. Re: Classcast Exception $Proxy thing
          elkner
          • 2. Re: Classcast Exception $Proxy thing
            michaelralston

            That page explains the jndi name change, from interface to name/local, as I have stated I am aware of this. But it does not explain why I am being return a $ProxyXX which I can't cast to my interface.

            • 3. Re: Classcast Exception $Proxy thing
              kvbisme

              I am having the same problem ... what really is confusing me is I went and added the collowing code to where I perform the lookup:

              InitialContext context = new InitialContext();
              Object objRef = context.lookup("ejb/notification");
              Class c = objRef.getClass();
              Class[] interfaces = c.getInterfaces();
              for (int i=0; i<interfaces.length; i++) {
              System.out.println(i + " : " + interfaces);
              }

              • 4. Re: Classcast Exception $Proxy thing
                kvbisme

                Sorry I ended up submitting a tad early ...

                Anyway my intefaces shows up as an interface for the proxy object ...

                and I still get the class cast exception.

                • 5. Re: Classcast Exception $Proxy thing
                  bdecoste

                  The code snippet you posted is fine. Can you please post the entire interface, bean, and client source?

                  • 6. Re: Classcast Exception $Proxy thing
                    anil.saldhana

                    Typically, this issue arises when the classpath on the client does not include all the jars from the jboss/client directory.

                    • 7. Re: Classcast Exception $Proxy thing
                      kvbisme

                      I can post the major parts ..

                      The Interface:

                      package com.ist.beans.interfaces.local;
                      
                      import java.io.Serializable;
                      import javax.ejb.Local;
                      
                      
                      @Local
                      public interface Notification {
                       ...
                       public Object getNotification(String topic, String user, int timeOut);
                       ...
                      }
                      


                      The bean:
                      package com.ist.beans.session;
                      
                      import java.io.Serializable;
                      import java.sql.Connection;
                      import java.sql.ResultSet;
                      import java.sql.SQLException;
                      import java.sql.Statement;
                      import java.util.ArrayList;
                      import java.util.List;
                      
                      import javax.ejb.Local;
                      import javax.ejb.Remote;
                      import javax.ejb.Stateless;
                      import javax.naming.InitialContext;
                      import javax.naming.NamingException;
                      import javax.sql.DataSource;
                      
                      import org.jboss.annotation.ejb.LocalBinding;
                      import org.jboss.annotation.ejb.RemoteBinding;
                      
                      @Stateless
                      
                      @Local ({com.ist.beans.interfaces.local.Notification.class})
                      @LocalBinding (jndiBinding="ejb/local-notification")
                      
                      @Remote ({com.ist.beans.interfaces.remote.Notification.class})
                      @RemoteBinding (jndiBinding="ejb/notification")
                      public class NotificationBean implements com.ist.beans.interfaces.remote.Notification,
                       com.ist.beans.interfaces.local.Notification {
                       private static final String NULL = "NULL";
                      
                       ...
                       public Object getNotification(String topic, int timeOut) {
                       return getObjectFromTopic(topic, timeOut);
                       }
                       ...
                       private Object getObjectFromTopic(String topic, int timeOut) {
                       Object value = null;
                      
                       //*Internal Processing ... database access ... blah ... blah
                      
                       return value;
                       }
                      
                      }
                      


                      Finally the client ... in this case the client is a web service ... if I use the same lookup code snippet in a client on my workstation ... works picture perfect ... However as a servlet it never makes it past construction.

                      package com.ist.webservice;
                      
                      import javax.naming.InitialContext;
                      import com.ist.beans.interfaces.local.Notification;
                      
                      public class NotificationWebService implements NotificationService {
                       private Notification notification;
                      
                       public NotificationWebService() {
                       super();
                       try {
                       InitialContext context = new InitialContext();
                      
                       Object objRef = context.lookup("ejb/local-notification");
                      
                       Class c = objRef.getClass();
                       Class[] interfaces = c.getInterfaces();
                       for (int i=0; i<interfaces.length; i++) {
                       System.out.println(i + " : " + interfaces);
                       }
                      
                       notification = (Notification)objRef;
                       }
                       catch (Throwable t) {
                       throw new RuntimeException(t);
                       }
                       }
                      
                       ...
                       }
                      
                      


                      Just incase ... web.xml
                      <?xml version="1.0" encoding="UTF-8"?>
                      <web-app version="2.5"
                       xmlns="http://java.sun.com/xml/ns/javaee"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
                       <display-name>Notification Service</display-name>
                       <description>Notification Web Service Interaface</description>
                       <servlet>
                       <servlet-name>NotificationServlet</servlet-name>
                       <servlet-class>com.ist.webservice.NotificationWebService</servlet-class>
                       </servlet>
                       <servlet-mapping>
                       <servlet-name>NotificationServiceServlet</servlet-name>
                       <url-pattern>/NotificationServlet</url-pattern>
                       </servlet-mapping>
                       <session-config>
                       <session-timeout>10</session-timeout>
                       </session-config>
                      </web-app>
                      


                      and the webservices.xml
                      <webservices xmlns="http://java.sun.com/xml/ns/j2ee"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd"
                       version="1.1">
                      
                       <webservice-description>
                       <webservice-description-name>NotificationWebService</webservice-description-name>
                       <wsdl-file>WEB-INF/wsdl/Notification.wsdl</wsdl-file>
                       <jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>
                       <port-component>
                       <port-component-name>NotificationServiceComponent</port-component-name>
                       <wsdl-port xmlns:ns="http://ist.com/services/ws/notification/">ns:NotificationSOAP</wsdl-port>
                       <service-endpoint-interface>com.ist.NotificationService</service-endpoint-interface>
                       <service-impl-bean>
                       <servlet-link>NotificationServlet</servlet-link>
                       </service-impl-bean>
                       </port-component>
                       </webservice-description>
                      </webservices>
                      


                      I am puzzled how someting can indicate it implements an interface when querying it through reflection, and then throw the ClassCastException when I try to do it.

                      To make some people happy here I have unfortunatly been forced to muck up these so pardon my fat-fingeredness if I missed something.

                      Thanks.

                      • 8. Re: Classcast Exception $Proxy thing
                        michaelralston

                        I ended up finding out what was wrong...

                        I had deployed the ejbjar and war seperately so they did not have the same classloader. One way to work around this is change tomcat to use the jboss classloader, but that mucks up other things.

                        I ended up deploying my ejbjar and war into an ear, this didn't help either!

                        I made a third jar which contained the interfaces which both ejb and war used, and then I made the manifest from the ejbjar and war include the common interfaces into its classpath.

                        I did have a problem with forgetting that my highest interface extended the apache abstractlogenabled interface, and I needed to include that in the manifest too.

                        Now it's all working sweet though.

                        • 9. Re: Classcast Exception $Proxy thing
                          jvramana

                          I was facing also some issues with classloaders. I posted a message at
                          http://www.jboss.com/index.html?module=bb&op=viewtopic&t=80895

                          But no luck yet. We have replaced all our injections with servicelocator pattern.
                          which ofcourse reduces our application ejb-ref scope from deployment to runtime.

                          • 10. Re: Classcast Exception $Proxy thing
                            tomaszdyszy

                            Hi,

                            I had already the same problem. MichaelRalston in his last post wrote good answer, thank.
                            The only one think which should be mantioned ist that the ejbjar, war and apijar musn't be in ear. It works also fine when they are deployed separatly, just don't put the apijar into war and add it to manifests in ejbjar and war.