2

I'm setting up a GWT application based on GWT/RequestFactory on client side, and JPA/EclipseLink over WebLogic on server side.

However, during development, everytime I change something on the server-side code (it can be an entity, the DAO, or even a comment in a Java file!), I get a ClassCastException between 2 apparently similar classes when I try to use my application, and the only way to get rid of it is to restart my WebLogic server. Even redeploying the application doesn't help.

Feb 10, 2012 4:08:10 PM com.google.web.bindery.requestfactory.server.RequestFactoryServlet doPost SEVERE: Unexpected error java.lang.ClassCastException: com.mycompany.MyClass cannot be cast to com.mycompany.MyClass at com.mycompany.server.locator.CodeLevelLocator.getId(MyClassLocator.java:1) at com.google.web.bindery.requestfactory.server.LocatorServiceLayer.doGetId(LocatorServiceLayer.java:168) at com.google.web.bindery.requestfactory.server.LocatorServiceLayer.getId(LocatorServiceLayer.java:66) at com.google.web.bindery.requestfactory.server.ServiceLayerDecorator.getId(ServiceLayerDecorator.java:81)

Any idea how to avoid this server restart?

Thanks.

EDIT: I'm setting up a bounty on this, because restarting WebLogic after each server change is really painful!!!

EDIT2 solved thanks to James by adding the following ServletContextListener:

public class DeploymentListener implements ServletContextListener {

    private static Logger log = LoggerFactory
            .getLogger(DeploymentListener.class.getName());

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {

        try {
            // close the Entity Manager Factory.
            EMF.close();
        } catch (Exception e) {
            log.error("Error closing the Entity Manager Factory", e);
        }
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        // nothing to do
    }

}
foch
  • 1,039
  • 10
  • 21
  • 2
    I'm not really qualified to answer, but I can suggest this: The error looks like a classloader issue, where the jvm apparently has two different declarations for the same class from two classloaders, and so considers them to be different classes. Most servlet containers use a specialized classloader to keep apps isolated from eachother, and to allow apps to be redeployed - my guess is that this isn't working correctly in your case. – Colin Alworth Feb 10 '12 at 19:05
  • Thanks for the hint, but here I believe there's something here specific to [GWT/RequestFactory](http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.html). Maybe any user of GWT around here have came across this issue? – foch Feb 13 '12 at 13:12
  • I'm actually a GWT developer first and foremost, and use RF in most of my projects, but I know just enough of the classloader issues to offer that suggestion. I've never seen that issue in redeploying RF classes to Jetty or Tomcat. – Colin Alworth Feb 13 '12 at 14:14
  • 1
    OK thanks! I guess the easiest solution then will be to do my developments under Jetty and keep WebLogic for Production only, where restarting the server after a code load is not a big issue! – foch Feb 13 '12 at 14:37

2 Answers2

2

This is a class loader issue, somehow after redeploying you have the old classes/instances remaining somewhere in your application.

It could be related to JPA, are you using a container managed persistence unit, or application managed? Container managed should not have this issue, but application managed could, as if you don't close the old EntityManagerFactory it can remain with the old classes. Ensure you close all factories before redeploying, or try container managed to see if it resolves the issue.

James
  • 17,965
  • 11
  • 91
  • 146
  • Fantastic, it works! I'm using Application managed persistence, so I added a listener to close my factory. That was 50 reps well spent, thanks :) – foch Feb 28 '12 at 16:48
0

Not familiar with running GWT on Weblogic but perhaps this will help.

Run your server in debug mode - it should be able to pick up the class/jar changes at runtime.

Perhaps you only need to re-publish your server instead of restarting it.

Lastly, do you have that class in a jar file elsewhere in your class path?

Stevko
  • 4,345
  • 6
  • 39
  • 66