Я пытаюсь обновить Springboot 2.7.18
до 3.3.1
, который включает Spring WS 4.0.11
.
Я использую WebServiceTemplate
и моя конфигурация такая:
private WebServiceTemplate buildWebServiceTemplate(WebServiceTemplateBuilder builder, ConfigurationProperties properties) {
return builder.messageSenders(new HttpWebServiceMessageSenderBuilder()
.setConnectTimeout(Duration.ofMillis(properties.getWebServiceConnectionTimeout()))
.setReadTimeout(Duration.ofMillis(properties.getWebServiceReadTimeout())).build())
.build();
}
И я получаю эту ошибку:
Caused by: org.springframework.ws.soap.SoapMessageCreationException: Could not create SAAJ MessageFactory: Unable to create SAAJ meta-factory: class com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl cannot be cast to class jakarta.xml.soap.SAAJMetaFactory (com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl and jakarta.xml.soap.SAAJMetaFactory are in unnamed module of loader 'app')
at app//org.springframework.ws.soap.saaj.SaajSoapMessageFactory.afterPropertiesSet(SaajSoapMessageFactory.java:156)
at app//org.springframework.ws.support.DefaultStrategiesHelper.instantiateBean(DefaultStrategiesHelper.java:180)
... 120 more
Caused by: jakarta.xml.soap.SOAPException: Unable to create SAAJ meta-factory: class com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl cannot be cast to class jakarta.xml.soap.SAAJMetaFactory (com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl and jakarta.xml.soap.SAAJMetaFactory are in unnamed module of loader 'app')
at app//jakarta.xml.soap.SAAJMetaFactory.getInstance(SAAJMetaFactory.java:73)
at app//jakarta.xml.soap.MessageFactory.newInstance(MessageFactory.java:126)
at app//org.springframework.ws.soap.saaj.SaajSoapMessageFactory.afterPropertiesSet(SaajSoapMessageFactory.java:139)
... 121 more
Я потратил много времени, чтобы разобраться в этом, попробовал много способов, установив свойство для замены jakarta.xml.soap
на com.sun.xml.messaging
, я попытался понизить версию Spring-WS
до 2.7.0
, но все равно получил ту же ошибку.
Приложение представляет собой модульный монолит, поэтому у меня их 2 build.gradle
repositories {
mavenCentral()
}
dependencies {
classpath 'org.apache.maven.resolver:maven-resolver-api:1.9.20'
}
}
plugins {
id 'java'
id 'project-report'
id 'io.spring.dependency-management' version '1.1.5'
id 'io.freefair.lombok' version '8.6'
id 'com.adarshr.test-logger' version '4.0.0'
id 'com.google.cloud.tools.jib' version '3.4.3'
}
allprojects {
group = 'com.example'
version = gitVersion
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
}
subprojects { project ->
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'project-report'
apply plugin: 'io.freefair.lombok'
apply plugin: 'com.adarshr.test-logger'
apply plugin: 'com.google.cloud.tools.jib'
ext {
springBootVersion = '3.3.1'
springCloudVersion = '2023.0.2'
spotbugsVersion = '4.8.6'
springdocVersion = '2.5.0'
projectMainPackage = "${project.group}"
byteBuddyVersion = '1.14.17'
}
dependencyManagement {
imports {
mavenBom "io.zonky.test.postgres:embedded-postgres-binaries-bom:${postgresqlVersion}"
mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
dependencies {
dependency "org.apache.logging.log4j:log4j-api:${redacted}"
dependency "org.apache.logging.log4j:log4j-simple:${redacted}"
dependency "org.apache.logging.log4j:log4j-to-slf4j:${redacted}"
dependency 'io.micrometer:micrometer-registry-prometheus:1.11.5'
dependency 'io.zonky.test:embedded-database-spring-test:2.5.1'
dependency "org.springdoc:springdoc-openapi-starter-webmvc-ui:${springdocVersion}"
dependency 'org.springframework.retry:spring-retry:2.0.6'
dependency 'com.sun.xml.bind:jaxb-osgi:4.0.5'
dependency 'com.tngtech.archunit:archunit-junit5:1.3.0'
dependency 'org.apache.poi:poi-ooxml:5.3.0'
dependency 'org.apache.commons:commons-csv:1.11.0'
dependency 'commons-io:commons-io:2.16.1'
dependency 'org.apache.commons:commons-lang3:3.14.0'
dependency 'org.apache.commons:commons-collections4:4.4'
dependency 'commons-codec:commons-codec:1.17.0'
dependency 'com.google.guava:guava:33.2.1-jre'
dependency 'net.javacrumbs:smock-springws:0.9.0'
dependency 'com.google.zxing:core:3.5.3'
'org.apache.httpcomponents.client5:httpclient5:5.2.1'
dependency "net.bytebuddy:byte-buddy:${byteBuddyVersion}"
dependency "net.bytebuddy:byte-buddy-agent:${byteBuddyVersion}"
}
}
tasks.withType(AbstractCompile) {
options.encoding = 'UTF-8'
}
tasks.withType(Test) {
jvmArgs '-XX:TieredStopAtLevel=1', '-XX:+UseParallelGC', '-XX:ReservedCodeCacheSize=1024m', '-Xshare:auto', '-noverify'
maxHeapSize '16g'
useJUnitPlatform()
systemProperties = [
'file.encoding' : 'UTF-8',
'junit.jupiter.execution.parallel.enabled': true,
'spring.config.location' : 'optional:classpath:/application.yml,optional:classpath:/application-test.yml'
]
maxParallelForks = 4
testlogger {
theme 'standard-parallel'
showPassed false
showPassedStandardStreams false
}
outputs.upToDateWhen { true }
}
}
wrapper {
gradleVersion = '8.5'
distributionType = Wrapper.DistributionType.ALL
}
tasks.withType(JavaCompile) {
options.compilerArgs << '-parameters'
}
и внутренний градиент сборки для моего модуля:
buildscript {
dependencies {
classpath 'org.glassfish.jaxb:jaxb-runtime:4.0.5'
}
}
plugins {
id 'org.springframework.cloud.contract' version '4.0.1'
id 'com.github.eerohele.saxon-gradle' version '0.9.0-beta4'
id 'com.yupzip.wsdl2java' version "3.0.0"
id 'org.unbroken-dome.xjc' version '2.0.0'
}
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
compileOnly {
extendsFrom annotationProcessor
}
jaxb
}
wsdl2java {
wsdlDir = file("${project.buildDir}/wsdl")
wsdlsToGenerate = [
["-p", "com.example.modulename.infrastructure.soap", "${wsdlDir}/CREATE_USER.wsdl"],
]
cxfVersion = "4.0.4"
cxfPluginVersion = "3.5.5"
}
sourceSets {
main {
java {
srcDir 'src/main/java'
srcDir 'build/generated/jaxb'
}
}
}
task genJaxb {
ext.sourcesDir = "${buildDir}/generated/jaxb"
ext.schema = "src/main/resources/webservices/notification.xsd"
outputs.dir sourcesDir
doLast() {
project.ant {
taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
classpath: configurations.jaxb.asPath
mkdir(dir: sourcesDir)
xjc(destdir: sourcesDir, schema: schema) {
arg(value: "-wsdl")
produces(dir: sourcesDir, includes: "**/*.java")
}
}
}
}
dependencies {
implementation project(':core')
testImplementation project(':test')
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
implementation 'io.micrometer:micrometer-registry-prometheus'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui'
implementation 'org.springframework.boot:spring-boot-starter-web-services'
implementation 'wsdl4j:wsdl4j'
jaxb("org.glassfish.jaxb:jaxb-xjc")
testImplementation('org.springframework.boot:spring-boot-starter-test')
implementation 'org.springframework.ws:spring-ws-core'
implementation 'org.glassfish.jaxb:jaxb-runtime'
implementation 'com.google.guava:guava'
implementation 'org.springframework.retry:spring-retry'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
implementation 'org.apache.commons:commons-lang3'
implementation 'org.apache.commons:commons-collections4'
testImplementation 'io.zonky.test:embedded-database-spring-test'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation('org.springframework.cloud:spring-cloud-starter-contract-verifier') {
testImplementation 'com.sun.xml.bind:jaxb-osgi'
}
testImplementation('org.springframework.cloud:spring-cloud-starter-contract-stub-runner')
testImplementation 'net.javacrumbs:smock-springws'
}
processResources {
filesMatching(['**/application*.yml']) {
expand(project.properties)
}
exclude '**/*.wsdl'
exclude '**/*.xslt'
}
tasks.compileJava.dependsOn genJaxb
tasks.wsdl2javaTask.dependsOn xslt
tasks.withType(JavaCompile) {
options.compilerArgs << '-parameters'
}
модуль зависит от основного модуля, это основной модуль build.gradle
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
testImplementation project(':test')
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui'
implementation 'org.apache.commons:commons-lang3'
implementation 'commons-codec:commons-codec'
implementation 'org.springframework.retry:spring-retry'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
implementation 'io.micrometer:micrometer-registry-prometheus'
implementation 'com.google.guava:guava'
implementation 'org.apache.commons:commons-collections4'
implementation 'org.apache.httpcomponents.client5:httpclient5'
implementation 'org.hibernate.orm:hibernate-micrometer'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation('org.springframework.cloud:spring-cloud-starter-contract-stub-runner')
}
tasks.withType(JavaCompile) {
options.compilerArgs << '-parameters'
}
также зависит от модуля test
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
implementation project('core')
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui'
implementation 'org.apache.commons:commons-lang3'
implementation 'commons-codec:commons-codec'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
implementation 'com.google.guava:guava'
implementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
implementation('org.springframework.cloud:spring-cloud-starter-contract-stub-runner')
}
processResources {
filesMatching(['**/application*.yml']) {
expand(project.properties)
}
}
tasks.withType(JavaCompile) {
options.compilerArgs << '-parameters'
}
Добавлен build.gradle
Я бы предложил заменить зависимость spring-ws-core
на spring-boot-starter-web-services
, что приведет к появлению некоторых дополнительных зависимостей. Единственное, о чем я могу думать, это то, что используемая вами версия CXF не совместима с JakartaEE.
spring-boot-starter-web-services
У меня тоже есть такое, и я думаю, что CXF 4.0.0
поддерживает Jakarta ee 9
Итак, потратив несколько дней, проблема заключалась в том, что произошел конфликт с com.yupzip.wsdl2java
. После прочтения документации и руководства по миграции мне пришлось добавить includeJava8XmlDependencies = false
к моей wsdl2java
задаче, README
Добавьте в вопрос свой файл pom или сборки.