Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entry BOOT-INF/lib/jaxb-core-4.0.1.jar is a duplicate but no duplicate handling strategy has been set #33659

Closed
naihil opened this issue Dec 30, 2022 · 14 comments
Labels
for: external-project For an external project and not something we can fix status: invalid An issue that we don't feel is valid

Comments

@naihil
Copy link

naihil commented Dec 30, 2022

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.
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 30, 2022
@HououinKyouma2000
Copy link

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

@naihil
Copy link
Author

naihil commented Jan 2, 2023

Another workaround:

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

@bclozel
Copy link
Member

bclozel commented Jan 2, 2023

@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'
}

@bclozel bclozel added the for: team-meeting An issue we'd like to discuss as a team to make progress label Jan 2, 2023
@naihil
Copy link
Author

naihil commented Jan 2, 2023

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

@naihil naihil closed this as completed Jan 2, 2023
@naihil
Copy link
Author

naihil commented Jan 2, 2023

Oops, close accidentally, reopen.

@naihil naihil reopened this Jan 2, 2023
@anbusampath
Copy link
Contributor

anbusampath commented Jan 2, 2023

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.

@bclozel
Copy link
Member

bclozel commented Jan 4, 2023

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

@bclozel bclozel closed this as not planned Won't fix, can't repro, duplicate, stale Jan 4, 2023
@bclozel bclozel added status: invalid An issue that we don't feel is valid for: external-project For an external project and not something we can fix and removed status: waiting-for-triage An issue we've not yet triaged for: team-meeting An issue we'd like to discuss as a team to make progress labels Jan 4, 2023
@dev4sep
Copy link

dev4sep commented Apr 26, 2023

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
}

@wilkinsona
Copy link
Member

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

@dev4sep
Copy link

dev4sep commented Apr 26, 2023

@wilkinsona could you pls suggestion me clearly about this?

@wilkinsona
Copy link
Member

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.

@dev4sep
Copy link

dev4sep commented Apr 26, 2023

@wilkinsona Thanks for your suggestions!

@TheNullablePrototype
Copy link

TheNullablePrototype commented Oct 25, 2023

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'
}

@chkpnt
Copy link

chkpnt commented Feb 12, 2024

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")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project For an external project and not something we can fix status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

9 participants