Search code examples
jax-rscdibean-validationapache-tomee

Bean Validation on Jax-RS Resource stops working while using CDI on Apache TomEE 8.0.10


I'm having troubles getting bean validation to work with the following minimalised project consisting only of this three java files plus pom.xml. I'm using Apache TomEE 8.0.10.

LoginMessage.java

package org.example;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.validation.constraints.NotBlank;

@Getter
@Setter
@ToString
public class LoginMessage {

    @NotBlank
    private String username;

    @NotBlank
    private String password;
}

SessionService.java

package org.example;

import lombok.extern.java.Log;

import javax.enterprise.context.RequestScoped;

@Log
@RequestScoped
public class SessionService {

    public void login(final LoginMessage loginMessage) {
        log.info(loginMessage.toString());
    }
}

SessionController.java

package org.example;

import lombok.extern.java.Log;

import javax.inject.Inject;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;

@Log
@Path("/session")
public class SessionController {

    @Inject
    private SessionService sessionService;

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public void postLoginMessage(@Valid final LoginMessage loginMessage) {
        sessionService.login(loginMessage);
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <packaging>war</packaging>

    <groupId>org.example</groupId>
    <artifactId>beanval</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>8.0.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
    </dependencies>
</project>

If you post an empty JSON object it ignores the @Valid annotation in SessionController#postLoginMessage() and directly outputs the log message containing the toString() content of the LoginMessage object through SessionService#login() method.

POST http://localhost:8080/beanval-1.0-SNAPSHOT/session
Content-Type: application/json

{
}
13-Mar-2022 01:30:39.700 INFORMATION [http-nio-8080-exec-6] SessionService.login LoginMessage(username=null, password=null)

If you remove or comment out the @RequestScoped annotation from SessionService and post the empty JSON-Object after restart of TomEE then bean validation works and logs:

13-Mar-2022 01:52:51.594 WARNUNG [http-nio-8080-exec-6] org.apache.cxf.jaxrs.validation.ValidationExceptionMapper.toResponse Value (null) of SessionController.postLoginMessage.arg0.password: must not be blank
13-Mar-2022 01:52:51.595 WARNUNG [http-nio-8080-exec-6] org.apache.cxf.jaxrs.validation.ValidationExceptionMapper.toResponse Value (null) of SessionController.postLoginMessage.arg0.username: must not be blank

I would like to use CDI in combination with Bean-Validation in JAX-RS Resource. What am I doing wrong?

Thanks in advance.


Solution

  • After all to come up to some kind of a solution I will stop using bean validation at controller layer. It works at service layer and so I can continue to work on my web app.

    The solution is using the @Valid annotation in SessionService#login() method and remove it from SessionController#postLoginMessage() method.

    If it is really a bug in TomEE the alternative could also be to use another application server until it is fixed.