Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bean-Validation 1.1 in Glassfish 4.0 - CDI Injection not working as intended

According to the Glassfish 4.0 wiki, Glassfish 4.0 should include JSR349 Bean Validation 1.1.: GF4 wiki link

According to the JSR349 spec, CDI Injection should work out of the box: Bean Validation 1.1. CDI Integration

So I changed my pom.xml accordingly:

<dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
        <scope>provided</scope>
 </dependency>

And tried injecting a CDI Bean into the ConstraintValidator:

public class UniqueEmaiValidator implements ConstraintValidator<UniqueEmail, String> {

    @Inject
    private UserAccountService accountService;

    @Override
    public void initialize(UniqueEmail constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
         return !accountService.userExistsByEmail(value);
    }
}

However, when testing the application (Running Arquillian 1.1.1. with arquillian-glassfish-remote-3.1 1.0.0.CR4), the validation will always fail because userAccountService is null and thus will throw a NullPointerException eventually.

What am I missing to make the Bean Validation 1.1 work?

edit:

A) Can confirm it is not caused by the Arquillian remote test - will also throw a NPEx. when run on the server

B) Running on a GlassFish Server Open Source Edition 4.0 (build 89)

C) I re-built the bean-validation.jar explicitly using the 5.0.1.FINAL of Hibernate Validator. The mvn package output:

[INFO] Building Validation API (JSR 349) version 1.1.0.Final, Hibernate Validator version 5.0.1.Final and its dependencies repackaged as OSGi bundle 2.1.92

Upon startup of the GlassFish server I get greeted with the following:

INFO:   GlassFish Server Open Source Edition  4.0  (89) startup time : Felix (5,736ms), startup services(2,078ms), total(7,814ms)
INFO:   HV000001: Hibernate Validator 5.0.1.Final

So I suppose the rebuilding did work. However, it did not resolve my issue of the NullPointerException :/

D) @Gunnar

This is the entity class, using a @Constraint annotation:

@Entity
public class UserAccount extends AbstractEntity implements VisibilitySettings {

  @UniqueEmail
  private String email;
  [...] 
}

The Annotation itself:

@Constraint(validatedBy = {UniqueEmailValidator.class})
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UniqueEmail {

    String message() default "{validator.security.useraccount.emailexists}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

And the corresponding ConstraintValidator:

public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {

    @Inject
    private UserAccountService accountService;

    @Override
    public void initialize(UniqueEmail constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return !accountService.userExistsByEmail(value);
    }
}

The UserAccountService is annotated with @ApplicationScoped @Transactional

like image 456
chzbrgla Avatar asked Nov 12 '13 09:11

chzbrgla


1 Answers

CDI integration won't work out of the box when manually bootstrapping a validator via Validation.buildDefaultValidatorFactory().

When performing validation as part of the entity lifecycle via JPA, CDI integration should work; If it doesn't, there still might be an issue how Bean Validation is integrated into GlassFish. If this actually is the case, you might work around the issue by configuring a custom constraint validator factory in META-INF/validation.xml which creates CDI managed validator instances.

For this, you may use the factory provided by Hibernate Validator's CDI integration as starting point. Note that the factory needs a default constructor though when configured via XML; to satisfy that requirement you could get a reference to the BeanManager via JNDI.

like image 98
Gunnar Avatar answered Feb 07 '23 05:02

Gunnar