Apache CXF - ClassCastException on Creating a Dynamic Client



我正试图利用Apache CXF库来创建一个动态客户端,该客户端将读取WSDL并将其解析为Java对象进行处理。

实现该逻辑的应用程序是使用Spring Boot 2.7和JDK11构建的。JAR工件在Spring Boot提供的嵌入式Tomcat容器上运行。

JDK11已经删除了创建对象所需的JAXB库,但它们是从Gradle文件中指定的其他依赖项(jakarta.xml.bind-api-2.3.3.jar、JAXB-impl-2.3.0.1.jar和JAXB-core-2.3.0.1.jar(间接添加的。

我正在创建动态客户端,如下所示。

this.wsdlClient = dcf.createClient(this.serviceURL + "?wsdl");

当我运行客户端时,应用程序无法编译从WSDL创建的源文件,并引发异常。

javax.xml.bind.JAXBException: "report.balance" doesnt contain ObjectFactory.class or jaxb.index

当CXF尝试编译源文件时,我假设应用程序JAR文件中的JAXB库不在类路径上。因此,我尝试创建动态客户端,并指定一个新的类加载器,其中包含位于应用程序运行目录中的文件夹中所需的JAR文件。

this.wsdlClient = dcf.createClient(this.serviceURL + "?wsdl", new URLClassLoader(new URL[] {
new File("applibs\jakarta.xml.bind-api-2.3.3.jar").toURI().toURL(),
new File("applibs\jaxb-impl-2.3.0.1.jar").toURI().toURL(),
new File("applibs\jaxb-core-2.3.0.1.jar").toURI().toURL(),
new File("applibs\javax.activation-api-1.2.0.jar").toURI().toURL()
}));

好消息是,从WSDL创建的源文件能够成功编译!

不幸的是,当动态客户端检查对象实例是否为JAXBContext类型时,会抛出ClassCastException。

javax.xml.bind.JAXBException: Provider class com.sun.xml.bind.v2.ContextFactory could not be instantiated: javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/C:/app/applibs/jakarta.xml.bind-api-2.3.3.jar!/javax/xml/bind/JAXBContext.class to jar:file:/C:/app/build/libs/app.jar!/BOOT-INF/lib/jakarta.xml.bind-api-2.3.3.jar!/javax/xml/bind/JAXBContext.class.  Please make sure that you are specifying the proper ClassLoader.

尽管JAXBContext类是同一个类,但我认为存在两个jakarta.xml.bind-api JAR文件(一个在应用程序JAR中,一个在appliebs文件夹中(会导致冲突,但我不确定原因,因为我正在指定一个全新的类加载器,由CXF用来编译从WSDL生成的Java源代码。

我不能从应用程序jar文件中排除jakarta.xml.bind-api-2.3.3.jar,因为其他依赖项需要它。

在我的方法中有没有遗漏什么?

对于将来遇到这个问题的人,以下是解决方案。

对于动态客户端的创建,将JakartaXMLBindneneneba API JAR包含在传递给构造函数的单独类加载器中。

this.wsdlClient = dcf.createClient(this.serviceURL + "?wsdl", new URLClassLoader(new URL[] {
new File("applibs\jakarta.xml.bind-api-2.3.3.jar").toURI().toURL()
}));

在JAR文件中,确保应用程序JAR文件中包含JAXB Runtime JAR的2.3.3版本。用于添加此依赖项的Gradle代码如下所示。

implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.3'

jaxb运行时JAR的2.3.6版本最初包含在应用程序JAR文件中,这导致了上述问题。

相关内容

最新更新