Category Archives: JAVA

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

Measuring JUnit CodeCoverage with Jacoco

Once you start working with unit tests, and that you understand how to use and write them, it’s impossible to go back. They help you decouple code, gain confidence in the behaviour you’re implementing, makes you faster by avoiding to start, and restart, a whole application.

Yet, one thing I never used up to now was code coverage. I just never took the time to dig the topic, even though that’s clearly useful. It helps maintain a team effort to ensure all new code is tested, and it gives you an idea of the risk you’re taking when chaging a line of code. Because the number of tests doesn’t give you any idea about the coverage, they may be focused on one part of the application only, or at the opposite cover a little bit every part, but not completely.

It appeared that adding code coverage measurement to a maven Java project using JUnit was as simple as adding the JaCoCo plugin to the POM file. As usual, Baeldung is your reference, but in brief :

            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

The JaCoCo plugin will output a jacoco.exec binary file, which can be consumed by some third party tools, like SonarQube. However, you can generate a more human friendly report using the repot goal :

mvn clean jacoco:prepare-agent install jacoco:report

You’ll then have a target\site\jacoco\index.html report detailing your code coverage :

Fixing Mockito UnnecessaryStubbingException with JUnit5

After upgrading to JUnit 5, you may bump into some unit tests now failing with the following error :

org.mockito.exceptions.misusing.UnnecessaryStubbingException: 
Unnecessary stubbings detected.
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):...

JUnit 5 is tricter regarding stubbing. As explained in the error message, unnecessary stubbing is not a good practice. It usually results from copy and paste, and creates confusion about the tested behaviour. In such a situation, you just want to remove the unnecessary stubbing.

However, there are some cases when you’d like a less strict approach. For example, when you use a helper method that does some mocking that is required by most of the cases, but not all. Than you have to choices :

  • instead of mocking directly with “when(…).then(…)”, prefix the call with lenient(). Ex
    lenient().when(oauth.getAuthorities()).thenReturn(authorities);
  • else, annotate your test class with :
    @MockitoSettings(strictness = Strictness.LENIENT)
    It will relax the mockito stubbing rules.

Increasing uploaded files maximum size in a Spring Boot 2 application

When uploading a file to a SpringBoot Application, you will get the following exception for files over 1 Mb size :

Maximum upload size exceeded; nestedexception is java.lang.IllegalStateException:org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field fileexceeds its maximum permitted size of1048576 bytes.

These are the default Spring Boot limits. To increase these limits to 10 Mb, with Spring Boot 2, add the following lines to your application.properties file:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB