2015-05-29 104 views
0

我正在將遺留應用程序從weblogic遷移到Tomcat 6. 應用程序需要訪問ejbs;爲了實現這一點,我將wlclient.jar添加到了classpath中。查找ejb jndi名稱時的類加載器問題tomcat 6

當負責與EJB的通信的傳統罐的方法是所謂的,我得到以下異常:

javax.naming.NamingException: Unhandled exception in lookup 
[Root exception is org.omg.CORBA.MARSHAL: vmcid: SUN minor code: 211 completed: Maybe] 

其原因是:

Caused by: java.lang.IllegalArgumentException: interface com.xxx.xxx.InterfaceName is not visible from class loader 
    at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353) 
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581) 
    at weblogic.iiop.ProxyDesc.readResolve(ProxyDesc.java:45) 

該接口似乎是用來定義從客戶端調用的方法,以從部署ejbs的服務器返回一些信息。

當使用verbose:class運行時,我發現Interface實際上是從本地jar加載的。在服務器上的相應接口裝入了:

[Loaded com.xx.xx.InterfaceName_t3s99q_InterfaceNameIntf from http://192.168.x.xx:port/path/classes/] 

即使我沒有任何想法如何工作的內部,我以爲查找進展順利,因爲它發現在服務器上正確的類。

在Proxy.getProxyClass中放置斷點時,發現異常時使用的類加載器是Launcher$AppClassLoader;它用來查找的URL就是我本地classpath(a.k.a. src/main/java等)中的那些,而不是webapp的路徑(a.k.a. WEB-INF/lib等)。

所以我的問題是:是否有可能錯誤的ClassLoader被用於特定的查找(本地而不是Tomcat的web應用程序級別)? 我可以指定一個特定的ClassLoader嗎?

我在尋找完全錯誤的方向來解決這個問題?

回答

0

那麼我在這上面損失了1.5天,所以我會發佈一個答案,希望最終對某人有用。

的問題是,我包括在日食的classpath wlclient.jar,而且由於Oracle實施使用super.getClass().getClassLoader(),它將返回用於加載在呼叫又名本地製造的ClassLoader類的類加載器,而不是從一個Web應用程序,所以它沒有web應用程序依賴關係的可見性。

我更新了我的項目,將jar包含在WEB-INF/lib中,這樣它將被webapp加載,因此super.getClass().getClassLoader()將返回正確的ClassLoader。

另一種可能性是將該行修改爲使用Thread.currentThread.getContextClassLoader。