Tag Archives: maven

Fixing error “The package org.xml.sax is accessible from more than one module: , java.xml”

After upgrading a dependency on Apache POI from version 4.2.0 to 5.0, my Java 11 Spring Boot application failed to start with error “The package org.xml.sax is accessible from more than one module: , java.xml”.

This issue is not specific to Apache POI, it was introduced with JAVA 9 modules. Here, the problem comes from the java.xml module, which is included by default with JAVA 11, and conflicts with the one included with Apache POI for compatibility with JAVA <= 8.

Thie first thing you need to do in such a cas, is to identify where the conflict comes from, which is done using Maven Dependency tree command:

mvn dependency:tree
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Bartleby 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ bartleby ---
[INFO] com.riousset.bartleby:bartleby:war:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:2.4.4:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-aop:jar:2.4.4:compile
[INFO] |  |  \- org.aspectj:aspectjweaver:jar:1.9.6:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-jdbc:jar:2.4.4:compile
[INFO] |  |  +- com.zaxxer:HikariCP:jar:3.4.5:compile
[INFO] |  |  \- org.springframework:spring-jdbc:jar:5.3.5:compile
[INFO] |  +- jakarta.transaction:jakarta.transaction-api:jar:1.3.3:compile
[INFO] |  +- jakarta.persistence:jakarta.persistence-api:jar:2.2.3:compile
[INFO] |  +- org.hibernate:hibernate-core:jar:5.4.29.Final:compile
....

Once identified the problematic dependency, you have 3 options to fix the conflict :
A. upgrade the libraries to a Java 11 compatible version without transitive dependencies,
B. exclude the conflict explicitly in POM dependencyManagement, or
C. avoid the conflict by only importing the classes needed and do not use wildcards (*) in import statements.

I chose the 3 option, and excluded the xml-apis dependency for poi-ooxml :

		<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>5.0.0</version>
			<exclusions>
				<exclusion>
					<artifactId>xml-apis</artifactId>
					<groupId>xml-apis</groupId>
				</exclusion>
			</exclusions>
		</dependency>

mvn dependency:tree

Solving Eclipse/maven error : dependency/ a.b.c (managed from x.y.z)

If Eclipse/M2E reports a maven dependency version conflict, with message “managed from x.y.z” (ex : “jooq/ 3.7.1 (managed from 3.6.0)“), the conflicting dependency is defined by an ancestor of the current maven project (could be its parent, great-parent, great-great-parent, etc.).

For example, let’s say maven signals a dependency conflict for a spring-boot 1.3 application. Version 3.7.1 of the JOOQ library is used while you specified version 3.6.0 (which is a pain because JAVA 7 is targeted, while JOOQ 3.7.1 only supports JAVA 8).

The error returned by the SpringBoot application is :
[code]
java.lang.UnsupportedClassVersionError: org/jooq/SQLDialect :
Unsupported major.minor version 52.0
[/code]

JOOQ is used by a dependency of the spring-boot application. The main application itself has no reference to JOOQ.

Indeed :

  1. project A declares a maven dependency on JOOQ 3.6.0 :
    [code lang=xml]

    org.jooq
    jooq
    3.6.0

    [/code]
    datawarehouse-jooq-dependency
  2. project B declares a maven dependency on project A, and defines spring-boot-starter-parent as a parent
    In project B dependencies, Eclipse/M2E flags JOOQ as “version 3.7.1 (managed from 3.6.0)” while version 3.6.0 is expected.
    feedbackrestservices-jooq-dependecy
  3. spring-boot-starter-parent has spring-boot-dependencies as a parent, which itself manages dependencies for JOOQ
    spring-boot-dependencies-managed-dependencies-jooq
    [code lang=xml]

    org.jooq
    jooq
    ${jooq.version}

    [/code]

To fix it, you could add a jooq 3.6.0 dependency to project B, so that the maven dependency conflict solving strategy uses this version since it is the nearest dependency. But that would be ugly. A cleaner solution consists in overriding the jooq.version property defined in spring-boot-starter-parent, as documented here :
[code lang=xml] 3.6.0 [/code]