有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java GWT devmode外部服务器类加载器地狱(艰难)

我有两个eclipse项目(在同一个工作区中),一个是运行jetty实例的标准java项目。另一个是GWT项目。GWT项目(在文件系统上)作为Web应用程序存在于java项目中,并由jetty(xml)配置加载

调试时,我通过eclipse运行这两个程序,首先作为常规java应用程序启动jetty服务器(localhost:8080),然后作为“Web应用程序(在外部服务器上)”启动GWT项目

一切都很好,除了试着投班级。在某些情况下,我会使用java。经过数小时的调试,我确定这是由于使用了两个独立的类加载器,每个类加载器一个

我认为这源于在servlet上下文中创建的对象和不在servlet上下文中创建的对象

我创建了一个测试来显示这一点。假设从传入请求调用以下方法到servlet,参数InstanceOffClassa在servlet请求处理程序中的某个位置创建并传递给此方法:

public void calledFromServlet(ClassA instanceOfClassA){

    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    // systemClassLoader is sun.misc.Launcher$AppClassLoader@45a877

    Object classA1 = new ClassA();
    ClassLoader loader1 = classA1.getClass().getClassLoader();
    // loader1 is is WebAppClassLoader=GWTProject@b98fe1


    ClassLoader loader2 = instanceOfClassA.getClass().getClassLoader();
    // loader2 is sun.misc.Launcher$AppClassLoader@45a877

    ClientA request = (ClassA)instanceofClassA; // java.lang.ClassCastException!
}

如您所见(希望如此),在当前上下文中创建的对象由WebAppClassLoader加载=GWTProject@b98fe1在servlet上下文中创建的对象(在其他地方)由系统加载器sun加载。杂项。发射装置$AppClassLoader@45a877.

因此,当我尝试将在servlet上下文中创建的对象强制转换为当前上下文中的同一个类时,我得到一个ClassCastException

不用说,这真的毁了我的一周,我无法解决这个问题,因为我需要能够投射对象

以前有没有人经历过这种情况,并有解决方案

更新(1月5日凌晨2:24):我已尝试使用线程强制当前线程的类加载器。currentThread()。setContextClassLoader(ClassLoader.getSystemClassLoader())。还是不行

更新(1月6日下午1:09——托马斯·博耶)

似乎有两个感兴趣的线程正在运行,其中一个是我的断点所在的线程:

Thread [38] (Suspended (breakpoint at line 53 in CollaborationSocketListener))  
CollaborationSocketListener.onMessage(String) line: 53  
WebSocketConnectionRFC6455$WSFrameHandler.onFrame(byte, byte, Buffer) line: 845 
WebSocketParserRFC6455.parseNext() line: 359    
WebSocketServletConnectionRFC6455(WebSocketConnectionRFC6455).handle() line: 235    
SelectChannelEndPoint.handle() line: 606    
SelectChannelEndPoint$1.run() line: 46  
QueuedThreadPool.runJob(Runnable) line: 603 
QueuedThreadPool$3.run() line: 538  
Thread.run() line: 662  

另一个属于gwt开发启动器:

 com.google.gwt.dev.DevMode at localhost:37240  
    Thread [main] (Running) 
Thread [Thread-0] (Running) 
Daemon Thread [Thread-1] (Running)  
Daemon Thread [UnitWriteThread] (Running)   
Daemon Thread [Timer-0] (Running)   
Daemon Thread [Code server listener] (Running)  
Daemon Thread [com.google.gwt.thirdparty.guava.common.base.internal.Finalizer] (Running)    
Daemon Thread [com.google.inject.internal.util.$Finalizer] (Running)    
Daemon Thread [Code server for freshgwtp from Mozilla/5.0 (X11; Linux i686)     AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11 on http://localhost:8080/FreshGWTP.html?gwt.codesvr=127.0.0.1:9997 @ h`"*x.nukanE_ke_] (Running)   

正在调用的方法是对servlet(WebSocket servelet)的传入消息的响应。相关代码如下:

public void onMessage(String serRequest) {

        // Create a request here to show that we can cast anything created in this context
    Object uFakeRequest = new ClientConnectRequest("someSite", new Client("SomeClient"));

    // This cast works fine
    ClientConnectRequest fakeRequest = (ClientConnectRequest)uFakeRequest;

            // Now I build the same object from a serialized object using a "deserializer" instantiated elsewhere (Note what it is instantiated does not seem to make a difference
    Object uRequest = streamer.fromString(serRequest);

            // ClassCastException
    ClientConnectRequest request = (ClientConnectRequest)uRequest;

    CollaborationSite site = siteManager.getOrCreateSite(request.getSiteID());

    site.onRequestRecieved(con, request);
}

“streamer”是一个gwt streamer(有关详细信息,请参阅google代码),我已经尝试在servelet init()中实例化它,并在这个方法中内联,以及通过Guice注入。我总是得到相同的类强制转换异常

原因是拖缆的类加载器是系统类加载器,而当前方法中的类加载器是GWT Dev类加载器

**更新(1月5日下午2:36)更多混乱**

为了分离类加载器之间的冲突,我分别启动了两个eclipse实例,一个启动了jetty应用程序,另一个启动了gwt dev模式(在外部服务器上)。仍然会得到相同的错误

我不明白为什么GWT认为is应该在外部服务器的服务器端代码上处理类加载


共 (0) 个答案