2015-05-29 95 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。