recently I have started working on a full stack project on my own using Jersey 3.0.2 . I have configured the service to use HK2 DI annotation and Maven to shade the project in a Jar.
I wanted to add some bean validation and to do so I have included this dependency to the pom.xml
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId>
<version>3.0.2</version>
</dependency>
this is in the Maven build
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<inherited>true</inherited>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2-metadata-generator</artifactId>
<version>3.0.2</version>
</annotationProcessorPath>
<annotationProcessorPath>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId>
<version>3.0.2</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>package-name-with-shade</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.package.name.Main</Main-Class>
<Build-Number>1</Build-Number>
<X-Compile-Source-JDK>1.8</X-Compile-Source-JDK>
<X-Compile-Target-JDK>1.8</X-Compile-Target-JDK>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
and this is how one of my endpoints looks like
@POST
@Operation(summary = "Create a user in the Database",
responses = {
@ApiResponse(description = "The created user",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = User.class))),
@ApiResponse(responseCode = "400", description = "User not found")})
public Response postIt(@Valid @NotNull @ValidUser User user) {
try {
crud.createUser(user);
return Response.ok(user).build();
} catch (Exception e) {
logger.info(e);
return Response.status(Response.Status.BAD_REQUEST).entity(e.getCause()).build();
}
}
If I try to run the project via IntelliJ it all works fine, validation too and I can see in the logs that the validator is loaded correctly:
INFO [2021-06-21 11:12:16.645] org.hibernate.validator.internal.util.Version: HV000001: Hibernate Validator 7.0.0.Final
including several debug messages like this one
DEBUG [2021-06-21 11:12:16.735] org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper
But, when I build up the Fat Jar using Maven and run it with
mvn clean -DskipTests package && java -jar ./target/package-name-with-shade.jar
Everything seems working fine except for the validation: the hibernate validator logs are not shown, no errors are thrown and the validation won't work. It seems like the validation was not even present in the codebase despite finding it the compiled Jar.
Any idea on what can I try?
Thanks
In your shade plugin configuration, you're missing the ServicesResourceTransformer.
JAR files providing implementations of some interfaces often ship with a
META-INF/services/
directory that maps interfaces to their implementation classes for lookup by the service locator. To relocate the class names of these implementation classes, and to merge multiple implementations of the same interface into one service entry, theServicesResourceTransformer
can be used:
This is important for auto-discovery. Without this, you will need to manually register features/providers that would otherwise be registered via auto-discovery.
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<!-- other transformers -->
</transformers>
</configuration>