You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为EAR中的所有WAR应用配置单一类加载器(WebSphere Liberty)

WebSphere Liberty 中替代WAS 9.0.5“应用单类加载器”的配置方案

我正尝试将遗留应用从WAS 9.0.5迁移至WebSphere Liberty,应用结构如下:

EarApplication.ear
          |--> META-INF
                   |-->application.xml
          |--> WebApplication1.war
                 |---> META-INF 
                          |--> MANIFEST
                 |----->WEB-INF 
                          |--> classes
                          |--> lib 
                                 |--> WebApplication1Client.jar
                                 |--> WebApplication2Client.jar
                                 |--> Other libs
          |--> WebApplication2.war
                 |---> META-INF 
                          |--> MANIFEST
                 |----->WEB-INF 
                          |--> classes
                          |--> lib 
                                 |--> WebApplication2Client.jar
                                 |--> Other libs

WebApplication1Client.jar包含的JAX-RS定义类:

@Path("a")
public interface A {
    @GET
    @Path("a-method")
    AB getA();

    class AB implements Serializable {
    ...    
    }
}

WebApplication1.war包含的EJB实现类(注:原文@Steteless为笔误,修正为@Stateless):

@Stateless
@Local(A.class)
public class AImpl implements A {
    
    @EJB
    private B b;

    @Override
    public AB getA(){
        BB bb = b.getB();
        return getABFromBB(bb);
    }

    private AB getABFromBB(BB bb){
    ...
    }
}

WebApplication2Client.jar包含的JAX-RS定义类:

@Path("b")
public interface B {
    @GET
    @Path("b-method")
    BB getB();

    class BB implements Serializable {
    ...    
    } 

}

WebApplication2.war包含的EJB实现类(注:原文@Steteless为笔误,修正为@Stateless):

@Stateless
@Local(B.class)
public class BImpl implements B {
    
    @Override
    public BB getB(){
        return new BB();
    }

}

由于WebApplication1.war和WebApplication2.war由不同类加载器加载,出现如下异常:

CWOWB1000E: 发生CDI错误:CWNEN0074E: 为java:comp/env/AImpl/b引用获取的EJSLocal_B_64388ed6类型的对象实例与AImpl成员B的类型不兼容。

在WAS 9.0.5中,可通过在应用级别勾选“Single class loader for application”(应用单类加载器)选项解决该问题,但WebSphere Liberty文档未提及相关配置选项,当前server.xml配置如下:

<server>

   <features>
       <feature>javaee-7.0</feature>
   </features>

   <applicationManager autoExpand="true"/>

   <enterpriseApplication location="EarApplication.ear"/>

</server>

请问WebSphere Liberty中是否有类似WAS的配置选项来解决该问题?


解决方案

WebSphere Liberty中提供了对应的配置属性来实现和WAS 9.0.5“应用单类加载器”相同的效果:

在<enterpriseApplication>元素中添加classLoadingMode="SINGLE"属性,修改后的server.xml如下:

<server>

   <features>
       <feature>javaee-7.0</feature>
   </features>

   <applicationManager autoExpand="true"/>

   <enterpriseApplication location="EarApplication.ear" classLoadingMode="SINGLE"/>

</server>

该配置会让整个EAR应用使用单一类加载器,所有模块(war、jar)共享同一个类加载上下文,这样WebApplication1和WebApplication2加载的B接口类会是同一个实例,从而避免类型不兼容的异常。

另外,更推荐的优化方案是:将共享的WebApplication1Client.jar和WebApplication2Client.jar移动到EAR根目录的lib文件夹下(若不存在则创建),这样这些共享类会被EAR的类加载器加载,所有子模块(war)都可以共享这些类。这种方式既解决了类加载器冲突问题,又比全局单类加载器更符合Java EE的模块化规范,减少不必要的类共享。


内容的提问来源于stack exchange,提问作者Kapik001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:50:00