Skip to content

Compilation error with multiple @Pattern annoations. #266

@cdevoss

Description

@cdevoss

Hi, My first time using Avaje so I'm not sure if I'm doing something wrong. Getting a compiler error in the generated code. Tested on all 2.x versions.

Compiler Error

[12,1] a type with the same simple name is already defined by the single-type-import of jakarta.validation.constraints.Pattern.List

The reason is a namespace collision (List) between these 2 imports. This error goes away if I don't have multiple @pattern annoations on the same member variable.

import jakarta.validation.constraints.Pattern.List;
import java.util.List;

Avaje Generated Class

import io.avaje.validation.adapter.ValidationAdapter;
import io.avaje.validation.adapter.ValidationContext;
import io.avaje.validation.adapter.ValidationRequest;
import io.avaje.validation.spi.Generated;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Pattern.List;
import jakarta.validation.constraints.Size;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static io.avaje.validation.adapter.RegexFlag.*;

@Generated("avaje-validator-generator")
public final class SignupRequestValidationAdapter implements ValidationAdapter<SignupRequest> {

  private final ValidationAdapter<String> usernameValidationAdapter;
  private final ValidationAdapter<String> passwordValidationAdapter;
  private final ValidationAdapter<String> emailValidationAdapter;

  public SignupRequestValidationAdapter(ValidationContext ctx) {
    this.usernameValidationAdapter = 
        ctx.<String>adapter(Pattern.class, Map.of("regexp","^[a-zA-Z0-9]*$", "message","{signup.username.pattern}"))
            .andThen(ctx.adapter(Size.class,Map.of("message","{signup.username.size}", "min",6, "max",32, "_type","String")))
            .andThen(ctx.adapter(NotBlank.class,Map.of("message","{signup.username.notblank}", "_type","String")));

    this.passwordValidationAdapter = 
        ctx.<String>adapter(Size.class, Map.of("message","{signup.password.size}", "min",16, "max",32, "_type","String"))
            .andThen(ctx.adapter(NotBlank.class,Map.of("message","{signup.password.notblank}", "_type","String")));

    this.emailValidationAdapter = 
        ctx.<String>adapter(Size.class, Map.of("message","{signup.email.size}", "min",1, "max",64, "_type","String"))
            .andThen(ctx.adapter(Email.class,Map.of("message","{signup.email.email}", "regexp",".*", "flags",List.of(), "_type","String")))
            .andThen(ctx.adapter(NotBlank.class,Map.of("message","{signup.email.notblank}", "_type","String")));

  }

  @Override
  public boolean validate(SignupRequest value, ValidationRequest request, String field) {
    if (field != null) {
      request.pushPath(field);
    }
    var _$username = value.getUsername();
    usernameValidationAdapter.validate(_$username, request, "username");

    var _$password = value.getPassword();
    passwordValidationAdapter.validate(_$password, request, "password");

    var _$email = value.getEmail();
    emailValidationAdapter.validate(_$email, request, "email");

    if (field != null) {
      request.popPath();
    }
    return true;
  }
}

Java Bean

import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;

@Valid
public class SignupRequest {

    @NotBlank(message = "{signup.username.notblank}")
    @Size(min = 6, max = 32, message = "{signup.username.size}")
    @Pattern(regexp = "^[a-zA-Z0-9]*$", message = "{signup.username.pattern}")
    private String username;

    @NotBlank(message = "{signup.password.notblank}")
    @Size(min = 16, max = 32, message = "{signup.password.size}")
    @Pattern.List({
        @Pattern(regexp = "^[a-zA-Z0-9!@#$^&*]*$", message = "{signup.password.invalid}"),
        @Pattern(regexp = ".*[a-z].*", message = "{signup.password.lowercase}"),
        @Pattern(regexp = ".*[A-Z].*", message = "{signup.password.uppercase}"),
        @Pattern(regexp = ".*[0-9].*", message = "{signup.password.digit}"),
        @Pattern(regexp = ".*[!@#$^&*].*", message = "{signup.password.special}"),
    })
    private String password;

    @Email(message = "{signup.email.email}")
    @NotBlank(message = "{signup.email.notblank}")
    @Size(min = 1, max = 64, message = "{signup.email.size}")
    private String email;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Maven Plugin Setup

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.13.0</version>
    <configuration>
        <annotationProcessorPaths>
            <!-- if using lombok, it must be placed before the jooby-apt -->
            <!-- if using avaje-inject, it must be placed after lombok, but before the jooby-apt -->
            <path>
                <groupId>io.avaje</groupId>
                <artifactId>avaje-validator-generator</artifactId>
                <version>2.4</version>
            </path>
            <path>
                <groupId>io.avaje</groupId>
                <artifactId>avaje-inject-generator</artifactId>
                <version>11.1</version>
            </path>
            <path>
                <groupId>io.jooby</groupId>
                <artifactId>jooby-apt</artifactId>
                <version>${jooby.version}</version>
            </path>
        </annotationProcessorPaths>
        <compilerArgs>
            <compilerArg>
                -Ajooby.debug=true
            </compilerArg>
            <compilerArg>
                -Ajooby.services=true
            </compilerArg>
        </compilerArgs>
    </configuration>
</plugin>

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions