【问题标题】:inconsistent behaviour in WebLogic when loading classes from a WAR exposing WebServices (Servlet 3.0) within an EAR从 WAR 加载类时 WebLogic 中的行为不一致,在 EAR 中公开 WebServices (Servlet 3.0)
【发布时间】:2018-02-15 13:26:42
【问题描述】:

我在 Weblogic 12c (12.2.1.0.0) 中部署 EAR 包时遇到了一个非常奇怪的问题。 首先,我们需要使用一个非常古老且特定的库,但是这个库在一个类上存在问题,所以我们在不同的 jar 中重写了同一个类,并将它放在类路径中,就在 buggy 强制类加载顺序,以便在运行时更早加载我们的版本,并且一切都按预期工作。 不幸的是,根据the Oracle's documentation,在部署简单的WAR 时,Weblogic 无法使用MANIFEST.MF 文件中的Class-Path 条目按预期工作。 为了使它工作,我需要通过以下方式重新打包我的应用程序:

耳朵 + 库 + 元信息 + ws-webapp.war

我的“libz”文件夹包含所有依赖项,包括遗留 jar 和修补程序。 ws-webapp 中的 MANIFEST.MF 定义了我的 Class-Path,包括前缀“libz”,它似乎工作正常。

当我尝试使用注释定义 Web 服务时,就会发生奇怪的事情。 假设我有一个名为 Foo 的类,它在旧库中,并且是我需要修补的类之一。

以下代码运行良好,代码编译,EAR 部署,web 服务运行,结果符合预期,即我收到了修补类中实现的 toString():

@WebService(serviceName = "MyWebService")
public class MyWebService {

    @WebMethod(operationName = "Foo")
    public void foo() {
        System.out.println(new Foo());
    }
}

另一方面,如果我只是创建一个返回 Foo 对象的方法,如下例所示:

@WebService(serviceName = "MyWebService")
public class MyWebService {

    @WebMethod(operationName = "Foo")
    public void foo() {
        System.out.println(getFoo());
    }

    private Foo getFoo() {
        return new Foo();
    }
}

我什至无法部署 EAR,因为 Weblogic 返回异常:

Caused by: java.lang.ClassNotFoundException: com.legacy.Foo 

我尝试在 weblogic 部署描述符中使用“prefer-web-inf-classes”,但这种方法不起作用,因为由于上述原因我需要保持类加载顺序,但我不能强制 weblogic 使用战争清单中的那个。 任何帮助将不胜感激。

非常感谢。

【问题讨论】:

    标签: java web-services classloader weblogic12c


    【解决方案1】:

    最后,我找到了解决问题的方法。 jaxws 给出了奇怪的行为。由于它是一个原生的 java 库,Weblogic 使用系统类加载器来加载它。当我的对象在方法中声明时,它们自然会在广告运行时加载。相反,方法签名是在部署时加载的,因此,由于我的库是在战争清单中定义的,它们还没有“看到”,所以 ClassNotFoundException。

    另一个错误,是在 ear 文件中定义自定义库文件夹:

    EAR
    + libz
    + META-INF
    + ws-webapp.war
    

    长话短说:我将 libz 重命名为 lib 并且 Weblogic 以“标准方式”加载耳朵,即在众所周知的文件夹中寻找应用程序库. 然后我完成如下:

    1. 我按照 Oracle 文档中的说明设置了 war 项目,以便 在战争附近的 lib 文件夹中查找库
    2. 我将 maven(*) 配置为将所有依赖项添加到 MANIFEST.MF 但不是在战争的 WEB-INF/lib 中
    3. 最后,我在 Weblogic.xml 部署描述符中添加了指令,以首先通过元素“prefer-web-inf-classes”从战争中加载库。

    部署描述符中的 prefer-web-inf-classes 对于指示 Weblogic 我们要使用 MANIFEST.MF 中描述的 Class-Path 条目很重要 要告诉 maven 将库包含在 MANIFEST 但不在 WEB-INF/lib 中,只需添加

    <optional>true</optional> 
    

    到每个依赖项。

    【讨论】:

    • 那么您的战争文件是否包含 MANIFEST.MF 或者您是否在 META-INF 中引用了与战争处于同一级别的该文件?我对你的第 1 点和第 2 点感到困惑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    相关资源
    最近更新 更多