简体   繁体   English

在 Apache CXF 和 Java 11 中创建 SOAP 客户端时出错

[英]Error Creating SOAP Client In Apache CXF And Java 11

In short:简而言之:

I am trying to create a SOAP client, using auto generated code from WSDL files.我正在尝试使用从 WSDL 文件自动生成的代码创建一个 SOAP 客户端。 The generation of the files was using CXF 3.5.3 Wsdl2Java.文件的生成使用 CXF 3.5.3 Wsdl2Java。 The command for generating the data models from the WSDL was: ./wsdl2java -d ~/PROJECT/src/main/java -autoNameResolution PATH_TO_WSDL_FILE.wsdl从 WSDL 生成数据模型的命令是: ./wsdl2java -d ~/PROJECT/src/main/java -autoNameResolution PATH_TO_WSDL_FILE.wsdl

When trying to run the code I am seeing the following exception:尝试运行代码时,我看到以下异常:

Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
 - with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory]
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:421)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
    at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:345)
    at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:343)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at org.apache.cxf.common.jaxb.JAXBContextCache.createContext(JAXBContextCache.java:343)
    at org.apache.cxf.common.jaxb.JAXBContextCache.getCachedContextAndSchemas(JAXBContextCache.java:245)
    at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:499)
    at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:358)
    ... 8 more

In the call for: PortClass port = (PortClass) factoryBean.create();在调用中: PortClass port = (PortClass) factoryBean.create();
Full code sample:完整代码示例:

ClientProxyFactoryBean factoryBean = new ClientProxyFactoryBean();
factoryBean.setServiceClass(PortClass.class);
factoryBean.setAddress(ADDRESS);
PortClass port = (PortClass) factoryBean.create();

Any ideas how to properly set the dependencies?任何想法如何正确设置依赖关系?

Full Workflow:完整的工作流程:

At first I used the OOB generated files, with the following Gradle dependencies:起初我使用 OOB 生成的文件,具有以下 Gradle 依赖项:

dependencies {
    implementation 'org.apache.cxf:cxf-rt-transports-http:3.5.3'
    implementation 'org.apache.cxf:cxf-rt-frontend-jaxws:3.5.3'
    implementation 'org.apache.cxf:cxf-rt-ws-security:3.5.3'
    implementation 'javax.xml.soap:javax.xml.soap-api:1.4.0'
    implementation 'javax.annotation:javax.annotation-api:1.3.2'
    implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
    implementation 'com.sun.xml.ws:jaxws-rt:4.0.0'
    implementation 'com.sun.xml.ws:jaxws-ri:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-ri:4.0.0'
    implementation 'com.sun.xml.ws:rt:4.0.0'
    implementation 'javax.xml.ws:jaxws-api:2.3.1'
    implementation 'javax.jws:javax.jws-api:1.1'
    implementation 'javax.xml.bind:jaxb-api:2.3.1'
    implementation 'javax.xml.ws:jaxws-api:2.3.1'
    implementation 'com.sun.xml.bind:jaxb-impl:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-core:4.0.0'
}

and encountered the exception: Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.并遇到异常: Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.

Understanding that in Java 11 you have to migrate to Jakarta instead of Javax, I have replaced Gradle dependencies into:了解到在 Java 11 中您必须迁移到 Jakarta 而不是 Javax,我已将 Gradle 依赖项替换为:

dependencies {
    implementation 'org.apache.cxf:cxf-rt-transports-http:3.5.3'
    implementation 'jakarta.xml.soap:jakarta.xml.soap-api:3.0.0'
    implementation 'org.apache.cxf:cxf-rt-frontend-jaxws:3.5.3'
    implementation 'com.sun.xml.bind:jaxb-impl:4.0.0'
    implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0'
    implementation 'jakarta.jws:jakarta.jws-api:3.0.0'
    implementation 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.0'
    implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0'
    implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0'
    implementation 'com.sun.activation:javax.activation:1.2.0'
    implementation 'jakarta.annotation:jakarta.annotation-api:2.1.1'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
    implementation 'org.apache.cxf:cxf-rt-ws-security:3.5.3'
    implementation 'org.glassfish.metro:webservices-rt:4.0.1'
    implementation 'org.glassfish.metro:webservices-api:4.0.1'
    implementation 'com.sun.xml.messaging.saaj:saaj-impl:3.0.0'
    implementation 'com.sun.xml.ws:jaxws-rt:4.0.0'
    implementation 'com.sun.xml.ws:jaxws-ri:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-ri:4.0.0'
    implementation 'com.sun.xml.ws:rt:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-core:4.0.0'
}

Next, the generated code didn't compile because Jaxb was not recognized in the auto generated files (because it is not part of the dependencies):接下来,生成的代码没有编译,因为 Jaxb 在自动生成的文件中没有被识别(因为它不是依赖项的一部分):

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

So I have manually replaced these imports into:所以我手动将这些导入替换为:

import jakarta.jws.WebMethod;
import jakarta.jws.WebParam;
import jakarta.jws.WebService;
import jakarta.xml.bind.annotation.XmlSeeAlso;
import jakarta.xml.ws.RequestWrapper;
import jakarta.xml.ws.ResponseWrapper;

And indeed everything compiles, but there were still errors because Apache CXF itself is built on javax .事实上一切都可以编译,但仍然有错误,因为 Apache CXF 本身是建立在javax之上的。 I had to return javax dependencies into Gradle:我必须将javax依赖项返回到 Gradle 中:

dependencies {
    implementation 'jakarta.xml.soap:jakarta.xml.soap-api:3.0.0'
    implementation 'org.apache.cxf:cxf-rt-frontend-jaxws:3.5.3'
    implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0'
    implementation 'jakarta.jws:jakarta.jws-api:3.0.0'
    implementation 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.0'
    implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0'
    implementation 'org.apache.cxf:cxf-rt-ws-security:3.5.3'
    implementation 'org.glassfish.metro:webservices-rt:4.0.1'
    implementation 'org.glassfish.metro:webservices-api:4.0.1'
    implementation 'com.sun.xml.messaging.saaj:saaj-impl:3.0.0'
    implementation 'jakarta.xml.soap:jakarta.xml.soap-api:3.0.0'
    
    implementation 'javax.jws:javax.jws-api:1.1'
    implementation 'javax.activation:activation:1.1.1'
    implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-core:4.0.0'
    implementation 'javax.annotation:javax.annotation-api:1.3.2'
    implementation 'javax.xml.ws:jaxws-api:2.3.1'
    implementation 'javax.xml.soap:javax.xml.soap-api:1.4.0'
    implementation 'javax.annotation:javax.annotation-api:1.3.2'
    implementation 'javax.xml.bind:jaxb-api:2.3.1'
    implementation 'com.sun.activation:javax.activation:1.2.0'
    implementation 'org.apache.cxf:cxf-rt-transports-http:3.5.3'
    implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-impl:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-ri:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-core:4.0.0'
    implementation 'com.sun.xml.ws:jaxws-rt:4.0.0'
    implementation 'com.sun.xml.ws:jaxws-ri:4.0.0'
    implementation 'com.sun.xml.bind:jaxb-ri:4.0.0'
    implementation 'com.sun.xml.ws:rt:4.0.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}

And now I am getting the above exception:现在我得到了上述异常:

Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
 - with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory]
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:421)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
    at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:345)
    at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:343)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at org.apache.cxf.common.jaxb.JAXBContextCache.createContext(JAXBContextCache.java:343)
    at org.apache.cxf.common.jaxb.JAXBContextCache.getCachedContextAndSchemas(JAXBContextCache.java:245)
    at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:499)
    at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:358)
    ... 8 more

Are you using Java 9 (or later)?您使用的是 Java 9(或更高版本)吗? The JAXB API is no longer included from this version.此版本不再包含 JAXB API。 You can take a look at How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException你可以看看如何解决 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM