Simple gradle Spring Boot 3 project with Spring Data and Spring Web Services:

build.gradle:

plugins {
      id 'java'
      id 'org.springframework.boot' version '3.0.1'
      id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.ws'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web-services'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

Error:

Execution failed for task ':bootJar'.
> Entry BOOT-INF/lib/jaxb-core-4.0.1.jar is a duplicate but no duplicate handling strategy has been set. Please refer to https://docs.gradle.org/7.6/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:duplicatesStrategy for details.

Comment From: HououinKyouma2000

org.hibernate:hibernate-envers:6 . i have the same problem. In the course of the conflict in the libraries inside. Below is one of the possible solutions, but it is not the best. Write it in gradle bootJar.enabled = false

Comment From: naihil

Another workaround:

tasks.named('bootJar') { duplicatesStrategy = DuplicatesStrategy.EXCLUDE }

Comment From: bclozel

@HououinKyouma2000 Disabling boot repackaging will prevent the application from runnning as an executable jar and won't solve the underlying problem.

@naihil I'm not sure excluding the dependency will solve the issue here, as excluding duplicates will exclude one of the jaxb-core jars: in this case, they're holding different content with classes located under different packages. This could lead to missing classes at runtime.

It looks like spring-ws-core has a hard dependency on com.sun.xml.bind:jaxb-core:

./gradlew dependencyInsight --dependency jaxb-core --configuration runtimeClasspath

> Task :dependencyInsight
com.sun.xml.bind:jaxb-core:4.0.1 (selected by rule)
  Variant runtime:
    | Attribute Name                 | Provided     | Requested    |
    |--------------------------------|--------------|--------------|
    | org.gradle.status              | release      |              |
    | org.gradle.category            | library      | library      |
    | org.gradle.libraryelements     | jar          | jar          |
    | org.gradle.usage               | java-runtime | java-runtime |
    | org.gradle.dependency.bundling |              | external     |
    | org.gradle.jvm.environment     |              | standard-jvm |
    | org.gradle.jvm.version         |              | 17           |

com.sun.xml.bind:jaxb-core:4.0.1
\--- com.sun.xml.bind:jaxb-impl:4.0.1
     \--- org.springframework.ws:spring-ws-core:4.0.0 (requested com.sun.xml.bind:jaxb-impl:4.0.0)
          \--- org.springframework.boot:spring-boot-starter-web-services:3.0.1
               \--- runtimeClasspath (requested org.springframework.boot:spring-boot-starter-web-services)

org.glassfish.jaxb:jaxb-core:4.0.1 (selected by rule)
  Variant runtime:
    | Attribute Name                 | Provided     | Requested    |
    |--------------------------------|--------------|--------------|
    | org.gradle.status              | release      |              |
    | org.gradle.category            | library      | library      |
    | org.gradle.libraryelements     | jar          | jar          |
    | org.gradle.usage               | java-runtime | java-runtime |
    | org.gradle.dependency.bundling |              | external     |
    | org.gradle.jvm.environment     |              | standard-jvm |
    | org.gradle.jvm.version         |              | 17           |

org.glassfish.jaxb:jaxb-core:4.0.1
\--- org.glassfish.jaxb:jaxb-runtime:4.0.1
     \--- org.hibernate.orm:hibernate-core:6.1.6.Final (requested org.glassfish.jaxb:jaxb-runtime:3.0.2)
          \--- org.springframework.boot:spring-boot-starter-data-jpa:3.0.1
               \--- runtimeClasspath (requested org.springframework.boot:spring-boot-starter-data-jpa)

Spring Boot has been using the Glassfish RI for a while now, so I'm wondering if this is an oversight or even needed in spring-ws?

Does the following work for your applications @naihil ?

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation ('org.springframework.boot:spring-boot-starter-web-services') {
        exclude group: "com.sun.xml.bind"
    }

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Comment From: naihil

implementation ('org.springframework.boot:spring-boot-starter-web-services') { exclude group: "com.sun.xml.bind" }

Checked this variant, application builds and tests fine, fat jar contains jaxb-core-4.0.1.jar and jaxb-runtime-4.0.1.jar

Variant with DuplicatesStrategy.EXCLUDE compiles and tests fine too, but fat jar contains jaxb-core-4.0.1.jar, jaxb-runtime-4.0.1.jar and jaxb-impl-4.0.1.jar

Comment From: naihil

Oops, close accidentally, reopen.

Comment From: anbusampath

Spring Boot has been using the Glassfish RI for a while now, so I'm wondering if this is an oversight or even needed in spring-ws?

spring-ws can migrate to org.glassfish.jaxb:jaxb-runtime from com.sun.xml.bind:jaxb-impl, as both contain same classes only differs with packing style. https://eclipse-ee4j.github.io/jaxb-ri/4.0.1/docs/release-documentation.html#deployment-maven-coordinates

but fat jar contains jaxb-core-4.0.1.jar, jaxb-runtime-4.0.1.jar and jaxb-impl-4.0.1.jar

In contrast to org.glassfish.jaxb artifacts, these(com.sun.xml.bind:jaxb-impl) jars have all dependency classes included inside.

Comment From: bclozel

We've discussed this as a team and we've created a Spring WS issue to address this problem. See spring-projects/spring-ws#1305

Comment From: dev4sep

Hi @everyone, Spring Boot 3.0.5 with Gradle 7.6.1 I still get this issuse

Execution failed for task ':war'.

Entry WEB-INF/lib/jaxb-core-4.0.2.jar is a duplicate but no duplicate handling strategy has been set. Please refer to https://docs.gradle.org/7.6.1/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:duplicatesStrategy for details.

I try to add this below in build.gradle, but still not work for me:

bootWar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE }

Comment From: wilkinsona

@yisivlay Your error occurred when running the war task but you've changed the configuration of the bootWar task.

Comment From: dev4sep

@wilkinsona could you pls suggestion me clearly about this?

Comment From: wilkinsona

The issue tracker isn't really the right place for this sort of support as it creates too much noise for those watching the repository. If you have further questions, please follow up on Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Comment From: dev4sep

@wilkinsona Thanks for your suggestions!

Comment From: TheNullablePrototype

I have a similar problem when generating a service from a wsdl tutorials: https://spring.io/guides/gs/consuming-web-service/#initial

and generate by xsd https://spring.io/guides/gs/producing-web-service/

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.1.5'
    id 'io.spring.dependency-management' version '1.1.3'
}

group = 'group'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '21'
}

ext.jaxwsSourceDir = "${buildDir}/generated/sources/jaxws"

configurations {
    jaxb
    jaxws
    compileOnly {
        extendsFrom annotationProcessor
    }
}

sourceSets {
    main {
        java {
            srcDir 'src/main/java'
            srcDir 'build/generated/sources/jaxb'
            srcDir jaxwsSourceDir
        }
    }
}

task genJaxb {
    ext.sourcesDir = "${buildDir}/generated/sources/jaxb"
    ext.schema = "src/main/resources/xsd/catalogs.xsd"
    ext.binding = "src/main/resources/jxb/bindings.xjb"

    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, binding: ext.binding) {
                arg(value: "-wsdl")
                produces(dir: sourcesDir, includes: "**/*.java")
            }
        }
    }
}

task wsimport {
    description = 'Generate classes from wsdl using wsimport'

    doLast {
        project.mkdir(jaxwsSourceDir)
        ant {
            taskdef(name: 'wsimport',
                    classname: 'com.sun.tools.ws.ant.WsImport',
                    classpath: configurations.jaxws.asPath
            )
            wsimport(
                    keep: true,
                    destdir: jaxwsSourceDir,
                    extension: "true",
                    verbose: true,
                    wsdl: "https://secret.com/SERVICEWS/soap?wsdl",
                    xnocompile: true,
                    package: "com.mos.ehd") {
                xjcarg(value: "-XautoNameResolution")
            }
        }
    }
}

compileJava.dependsOn genJaxb
compileJava.dependsOn wsimport

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-cache'
    implementation 'org.flywaydb:flyway-core'

    // support xml/xsd/wsdl
    implementation 'wsdl4j:wsdl4j'
    implementation 'com.sun.xml.ws:jaxws-rt:4.0.2'

    jaxb('org.glassfish.jaxb:jaxb-xjc:4.0.4')

    jaxws 'com.sun.xml.ws:jaxws-tools:4.0.2',
            'jakarta.xml.ws:jakarta.xml.ws-api:3.0.0',
            'jakarta.xml.bind:jakarta.xml.bind-api:4.0.1',
            'jakarta.activation:jakarta.activation-api:2.1.2'

    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'org.postgresql:postgresql'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

bootJar {
    setDuplicatesStrategy(DuplicatesStrategy.WARN)
}

tasks.named('test') {
    useJUnitPlatform()
}
Executing 'dependencyInsight --dependency jaxb-core --configuration runtimeClasspath'...


> Task :dependencyInsight
com.sun.xml.bind:jaxb-core:4.0.3 (selected by rule)
  Variant runtime:
    | Attribute Name                 | Provided     | Requested    |
    |--------------------------------|--------------|--------------|
    | org.gradle.status              | release      |              |
    | org.gradle.category            | library      | library      |
    | org.gradle.libraryelements     | jar          | jar          |
    | org.gradle.usage               | java-runtime | java-runtime |
    | org.gradle.dependency.bundling |              | external     |
    | org.gradle.jvm.environment     |              | standard-jvm |
    | org.gradle.jvm.version         |              | 21           |

com.sun.xml.bind:jaxb-core:4.0.3
\--- com.sun.xml.bind:jaxb-impl:4.0.3
     \--- com.sun.xml.ws:jaxws-rt:4.0.2 (requested com.sun.xml.bind:jaxb-impl:4.0.4)
          \--- runtimeClasspath

org.glassfish.jaxb:jaxb-core:4.0.3 (selected by rule)
  Variant runtime:
    | Attribute Name                 | Provided     | Requested    |
    |--------------------------------|--------------|--------------|
    | org.gradle.status              | release      |              |
    | org.gradle.category            | library      | library      |
    | org.gradle.libraryelements     | jar          | jar          |
    | org.gradle.usage               | java-runtime | java-runtime |
    | org.gradle.dependency.bundling |              | external     |
    | org.gradle.jvm.environment     |              | standard-jvm |
    | org.gradle.jvm.version         |              | 21           |

org.glassfish.jaxb:jaxb-core:4.0.3
\--- org.glassfish.jaxb:jaxb-runtime:4.0.3
     +--- org.springframework.ws:spring-ws-core:4.0.6 (requested org.glassfish.jaxb:jaxb-runtime:4.0.1)
     |    \--- org.springframework.boot:spring-boot-starter-web-services:3.1.5
     |         \--- runtimeClasspath (requested org.springframework.boot:spring-boot-starter-web-services)
     \--- org.hibernate.orm:hibernate-core:6.2.13.Final (requested org.glassfish.jaxb:jaxb-runtime:4.0.2)
          \--- org.springframework.boot:spring-boot-starter-data-jpa:3.1.5
               \--- runtimeClasspath (requested org.springframework.boot:spring-boot-starter-data-jpa)

So far, I have no idea how to deal with this problem without setting a duplication strategy, which is incorrect.

Execution failed for task ':bootJar'.
> Entry BOOT-INF/lib/jaxb-core-4.0.3.jar is a duplicate but no duplicate handling strategy has been set. Please refer to ...

UPD: Problem solved:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-cache'
    implementation 'org.flywaydb:flyway-core'

    // support xml/xsd/wsdl
    implementation 'wsdl4j:wsdl4j'
    implementation 'com.sun.xml.ws:rt:4.0.2'

    jaxb('org.glassfish.jaxb:jaxb-xjc:4.0.4')
    jaxb('org.glassfish.jaxb:jaxb-core:4.0.4')
    jaxb('org.glassfish.jaxb:jaxb-runtime:4.0.4')

    jaxws 'com.sun.xml.ws:jaxws-tools:4.0.2',
            'jakarta.xml.ws:jakarta.xml.ws-api:3.0.0',
            'jakarta.xml.bind:jakarta.xml.bind-api:4.0.1',
            'jakarta.activation:jakarta.activation-api:2.1.2',
            'com.sun.xml.ws:jaxws-rt:4.0.2'

    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'org.postgresql:postgresql'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Comment From: chkpnt

So it's just about replacing com.sun.xml.ws:jaxws-rt with com.sun.xml.ws:rt, which indirectly depends on org.glassfish.jaxb:jaxb-core instead of com.sun.xml.bind:jaxb-core? It seems to work here, too.

com.sun.xml.ws:rt has additional dependencies on com.sun.xml.ws:policyand org.glassfish.jaxb:jaxb-runtime, but is missing com.sun.xml.fastinfoset:FastInfoSet.

grafik

You might want to add com.sun.xml.fastinfoset:Fastinfoset as well as com.sun.xml.ws:rt-fi(which contains com.sun.xml.ws.encoding.fastinfoset.FastInfosetCodec that is included in jaxws-rt but no in rt), otherwise the following is logged:

2024-02-12 13:49:11.960  INFO com.sun.xml.ws.util.FastInfosetUtil      : Unable to locate compatible implementation of Fast Infoset in classpath

But other classes are also missing in rt, so additional dependencies like com.sun.xml.ws:httpspi-servlet, com.sun.xml.ws:servlet might be needed, too:

grafik

So in my opinion, an easier drop-in replacement is just to exclude com.sun.xml.bind:jaxb-core from com.sun.xml.ws:jaxws-rt, until something like org.glassfish.ws:jaxws-rt gets available:

    implementation("com.sun.xml.ws:jaxws-rt") {
        exclude(group = "com.sun.xml.bind", module = "jaxb-impl")
    }
    runtimeOnly("org.glassfish.jaxb:jaxb-runtime")