Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

July 13, 2017

Java Bean Validation Basics

Abstract

This post summarizes some quick and easy examples for the most common things you would want to do with the Java Beans Validation API (JSR 349, JSR 303). Remember, Beans Validation is independent of Java EE. Although it is built in as part of a Java EE compliant server, the API can also be used just as easily in a Java SE application. All these examples use Java SE.

Table of Contents

  1. Basics
  2. Custom Message Template
  3. Custom Message Template with Variable Replacement
  4. Custom Property Validator
  5. Custom Class Validator
  6. GroupSequence (Short Circuit)

Requirements

I did all of the work for this post using the following major technologies. You may be able to do the same thing with different technologies or versions, but no guarantees.

  • Java 1.8.0_65_x64
  • NetBeans 8.2
  • Maven 3.0.5 (Bundled with NetBeans)
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.2.Final</version>
</dependency>
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>2.2.4</version>
</dependency>
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.el</artifactId>
    <version>2.2.4</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

Download

Visit my GitHub page https://github.com/mjremijan to see all of my open source projects. The code for this post is located at: https://github.com/mjremijan/thoth-beanvalidation

Basics

This example shows the basics of bean validation using the built-in, standard constraints and the built-in, standard validators.

Listing 1.1 - Bean to validate

package org.thoth.beanvalidation.basics;

import javax.validation.constraints.NotNull;

public class Widget {

    @NotNull
    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Listing 1.2 - How to validate

package org.thoth.beanvalidation.basics;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class WidgetTest {

    protected Validator validator;

    @Before
    public void before() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    public void violations_size() {
        // setup
        Widget w = new Widget();

        // action
        Set<ConstraintViolation<Widget>> violations
            = validator.validate(w);

        // assert
        Assert.assertEquals(1, violations.size());
    }

    @Test
    public void violation_message() {
        // setup
        Widget w = new Widget();

        // action
        Set<ConstraintViolation<Widget>> violations
            = validator.validate(w);

        // assert
        ConstraintViolation<Widget> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("may not be null", v.getMessage());
    }

    @Test
    public void violation_messageTemplate() {
        // setup
        Widget w = new Widget();

        // action
        Set<ConstraintViolation<Widget>> violations
            = validator.validate(w);

        // assert
        ConstraintViolation<Widget> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("{javax.validation.constraints.NotNull.message}", v.getMessageTemplate());
    }

    @Test
    public void violation_propertyPath() {
        // setup
        Widget w = new Widget();

        // action
        Set<ConstraintViolation<Widget>> violations
            = validator.validate(w);

        // assert
        ConstraintViolation<Widget> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("name", v.getPropertyPath().toString());
    }
}

Custom Message Template

This example shows how the built-in, standard constraints can be customized with a custom error message instead of using the built-in, standard error messages.

Listing 2.1 - ValidationMessages.properties

Candy.name.NotNull=A candy name is required.

Listing 2.2 - Bean to validate

package org.thoth.beanvalidation.custommessage;

import javax.validation.constraints.NotNull;

public class Candy {

    @NotNull(message = "{Candy.name.NotNull}")
    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Listing 2.3 - How to validate

package org.thoth.beanvalidation.custommessage;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

public class CandyTest {

    protected static Validator validator;

    @BeforeClass
    public static void before() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    public void notnull_violation_message() {
        // setup
        Candy candy = new Candy();

        // action
        Set<ConstraintViolation<Candy>> violations
            = validator.validate(candy);

        // assert
        ConstraintViolation<Candy> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("A candy name is required.", v.getMessage());
    }

    @Test
    public void notnull_violation_messageTemplate() {
        // setup
        Candy candy = new Candy();

        // action
        Set<ConstraintViolation<Candy>> violations
            = validator.validate(candy);

        // assert
        ConstraintViolation<Candy> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("{Candy.name.NotNull}", v.getMessageTemplate());
    }
}

Custom Message Template with Variable Replacement

This example shows how the built-in, standard constraints can be configured with a custom error message which has variable values in the message which are replaced by bean validation at runtime. Examples of variables which can be replaced are the actual value which was validate and the min and max properties of a @Size constraint.

Listing 3.1 - ValidationMessages.properties

Candy.name.Size.message=The candy name "${validatedValue}" is invalid. It must be between {min} and {max} characters long

Listing 3.2 - Bean to validate

package org.thoth.beanvalidation.variablereplacement;

import javax.validation.constraints.Size;

public class Candy {
    private String name;

    @Size(message = "{Candy.name.Size.message}", min=5, max=10)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Listing 3.3 - How to validate

package org.thoth.beanvalidation.variablereplacement;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.thoth.beanvalidation.variablereplacement.Candy;

public class CandyTest {

    protected static Validator validator;

    @BeforeClass
    public static void before() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }


    @Test
    public void does_the_constraint_have_the_correct_messageTemplate() {
        // setup
        Candy candy = new Candy();
        candy.setName("");

        // action
        Set<ConstraintViolation<Candy>> violations
            = validator.validate(candy);

        // assert
        ConstraintViolation<Candy> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("{Candy.name.Size.message}", v.getMessageTemplate());
    }

    @Test
    public void is_the_message_correct_if_size_is_too_small() {
        // setup
        Candy candy = new Candy();
        candy.setName("foo");

        // action
        Set<ConstraintViolation<Candy>> violations
            = validator.validate(candy);

        // assert
        ConstraintViolation<Candy> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("The candy name \"foo\" is invalid. It must be between 5 and 10 characters long", v.getMessage());
    }

    @Test
    public void is_the_message_correct_if_size_is_too_big() {
        // setup
        Candy candy = new Candy();
        candy.setName("123456789|1");

        // action
        Set<ConstraintViolation<Candy>> violations
            = validator.validate(candy);

        // assert
        ConstraintViolation<Candy> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("The candy name \"123456789|1\" is invalid. It must be between 5 and 10 characters long", v.getMessage());
    }
}

Custom Property Validator

This example shows how to create your own constraint and your own validator for a property of a class.

Listing 4.1 - ValidationMessages.properties

org.thoth.beanvalidation.propertyvalidator.Excludes.message=The value "${validatedValue}" is one of {value} which is forbidden.

Listing 4.2 - Constraint annotation

package org.thoth.beanvalidation.propertyvalidator;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;

@Target({
    ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ExcludesValidator.class})
@Documented
public @interface Excludes {

    String message() default "{org.thoth.beanvalidation.propertyvalidator.Excludes.message}";

    Class[] groups() default {};

    Class[] payload() default {};

    String[] value() default {};
}

Listing 4.3 - Constraint validator

package org.thoth.beanvalidation.propertyvalidator;

import java.util.Arrays;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class ExcludesValidator
    implements ConstraintValidator< Excludes, String> {

    private List<String> excludeTheseValues;

    @Override
    public void initialize(Excludes arg) {
        String[] strarr = arg.value();
        if (strarr == null) {
            strarr = new String[]{};
        }
        excludeTheseValues = Arrays.asList(strarr);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext cvc) {
        if (excludeTheseValues.contains(value)) {
            return false;
        } else {
            return true;
        }
    }
}

Listing 4.4 - Bean to validate

package org.thoth.beanvalidation.propertyvalidator;

public class Candy {
    private String name;

    public Candy(String name) {
        this.name = name;
    }

    @Excludes({"foo", "bar", "shrubbery"})
    public String getName() {
        return name;
    }
}

Listing 4.5 - How to validate

package org.thoth.beanvalidation.propertyvalidator;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;

public class CandyTest {

    protected static Validator validator;

    @BeforeClass
    public static void before() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }


    @Test
    public void a_non_excludeded_name_should_not_give_you_a_constraint_violation() {
        // setup
        Candy candy = new Candy("hershey");

        // action
        Set<ConstraintViolation<Candy>> violations
            = validator.validate(candy);

        // assert
        assertEquals(0, violations.size());
    }


    @Test
    public void do_you_get_a_constraint_violation_if_you_use_excluded_name_foo() {
        // setup
        Candy candy = new Candy("foo");

        // action
        ConstraintViolation<Candy> violation
            = validator.validate(candy).iterator().next();

        // assert
        assertEquals("{org.thoth.beanvalidation.propertyvalidator.Excludes.message}", violation.getMessageTemplate());
        assertEquals("The value \"foo\" is one of [foo, bar, shrubbery] which is forbidden.", violation.getMessage());
    }


    @Test
    public void do_you_get_a_constraint_violation_if_you_use_excluded_name_bar() {
        // setup
        Candy candy = new Candy("bar");

        // action
        ConstraintViolation<Candy> violation
            = validator.validate(candy).iterator().next();

        // assert
        assertEquals("{org.thoth.beanvalidation.propertyvalidator.Excludes.message}", violation.getMessageTemplate());
        assertEquals("The value \"bar\" is one of [foo, bar, shrubbery] which is forbidden.", violation.getMessage());
    }


    @Test
    public void do_you_get_a_constraint_violation_if_you_use_excluded_name_shrubbery() {
        // setup
        Candy candy = new Candy("shrubbery");

        // action
        ConstraintViolation<Candy> violation
            = validator.validate(candy).iterator().next();

        // assert
        assertEquals("{org.thoth.beanvalidation.propertyvalidator.Excludes.message}", violation.getMessageTemplate());
        assertEquals("The value \"shrubbery\" is one of [foo, bar, shrubbery] which is forbidden.", violation.getMessage());
    }
}

Custom Class Validator

This example shows how to create your own constraint and your own validator which applies to an entire class.

Listing 5.1 - ValidationMessages.properties

org.thoth.beanvalidation.classvalidator.IdentificationExists.message=At least one of social security number, drivers license number, or passport number must exist.

Listing 5.2 - Constraint annotation

package org.thoth.beanvalidation.classvalidator;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {IdentificationExistsValidator.class})
@Documented
public @interface IdentificationExists {

    String message() default "{org.thoth.beanvalidation.classvalidator.IdentificationExists.message}";

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

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

Listing 5.3 - Constraint validator

package org.thoth.beanvalidation.classvalidator;

import java.util.Objects;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class IdentificationExistsValidator implements ConstraintValidator<IdentificationExists, Identification> {

    @Override
    public void initialize(IdentificationExists a) {}

    @Override
    public boolean isValid(Identification t, ConstraintValidatorContext cvc) {
        boolean invalid =
            Objects.equals(t.getDriversLicenseNumber(), null)
            &&
            Objects.equals(t.getPassportNumber(), null)
            &&
            Objects.equals(t.getSocialSecurityNumber(), null)
        ;
        return !invalid;
    }
}

Listing 5.4 - Bean to validate

package org.thoth.beanvalidation.classvalidator;

@IdentificationExists
public class Identification {
    protected String socialSecurityNumber;
    protected String driversLicenseNumber;
    protected String passportNumber;

    public String getSocialSecurityNumber() {
        return socialSecurityNumber;
    }

    public void setSocialSecurityNumber(String socialSecurityNumber) {
        this.socialSecurityNumber = socialSecurityNumber;
    }

    public String getDriversLicenseNumber() {
        return driversLicenseNumber;
    }

    public void setDriversLicenseNumber(String driversLicenseNumber) {
        this.driversLicenseNumber = driversLicenseNumber;
    }

    public String getPassportNumber() {
        return passportNumber;
    }

    public void setPassportNumber(String passportNumber) {
        this.passportNumber = passportNumber;
    }
}

Listing 5.5 - How to validate

package org.thoth.beanvalidation.classvalidator;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class IdentificationTest {

protected Validator validator;

    @Before
    public void before() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    public void violation_if_all_are_missing() {
        // setup
        Identification id = new Identification();

        // action
        Set<ConstraintViolation<Identification>> violations
            = validator.validate(id);

        // assert
        ConstraintViolation<Identification> v
            = violations.stream().findFirst().get();
        Assert.assertEquals("At least one of social security number, drivers license number, or passport number must exist.", v.getMessage());
    }

    @Test
    public void no_violation_if_social_security_number_exists() {
        // setup
        Identification id = new Identification();
        id.setSocialSecurityNumber("a");

        // action
        Set<ConstraintViolation<Identification>> violations
            = validator.validate(id);

        // assert
        Assert.assertEquals(0, violations.size());
    }

    @Test
    public void no_violation_if_drivers_license_number_exists() {
        // setup
        Identification id = new Identification();
        id.setDriversLicenseNumber("a");

        // action
        Set<ConstraintViolation<Identification>> violations
            = validator.validate(id);

        // assert
        Assert.assertEquals(0, violations.size());
    }

    @Test
    public void no_violation_if_passport_number_exists() {
        // setup
        Identification id = new Identification();
        id.setPassportNumber("a");

        // action
        Set<ConstraintViolation<Identification>> violations
            = validator.validate(id);

        // assert
        Assert.assertEquals(0, violations.size());
    }
}

GroupSequence (Short Circuit)

This example shows how to use @GroupSequence as a short circuit when doing validation. This means if the 1st round of validations do not pass, then validation is “short circuited” and the 2nd round of validations is not performed.

By default, all bean validation constraints are put into a “Default” group sequence. However, by putting a @GroupSequence on a class (like shown below) the “Default” group sequence is redefined just for that class. With the @GroupSequence on a class below, what it basically does is that during beans validation the 1st operation is to validate all constraints in the class that aren’t specifically assigned a group. That would be the @NotNull constraint first. If all of those are OK, then the 2nd operation is to validate all constraints that are in the Second.class group. That would be the @Size constraint. If all of those are OK, then 3rd operation is to validate all of the constraints that are in the Third.class group. That would be the @Pattern constraint. If at any time a group fails to validate, validation is “short circuited” and validation goes no farther.

Listing 6.1 - Bean to validate

package org.thoth.beanvalidation.groupsequence;

import javax.validation.GroupSequence;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@GroupSequence({Candy.class, Candy.Second.class, Candy.Third.class})
public class Candy {

    protected interface Second {}
    protected interface Third {}

    private String name;

    @NotNull()
    @Size(min=4, max=10, groups = Second.class )
    @Pattern(regexp = "[a-z]", groups = Third.class)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Listing 6.2 - How to validate

package org.thoth.beanvalidation.groupsequence;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;

public class CandyTest {

    private Validator validator;

    @Before
    public void before() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    public void short_circuits_first_if_null() {
        // setup
        Candy w = new Candy();

        // action
        Set<ConstraintViolation<Candy>> violations
            //= validator.validate(w, CheckGroupSequence.class);
            = validator.validate(w);

        // assert
        assertEquals(1, violations.size());
        assertEquals("may not be null", violations.iterator().next().getMessage());
    }


    @Test
    public void short_circut_if_size_is_in_violation() {
        // setup
        Candy w = new Candy();
        w.setName("foo");

        // action
        Set<ConstraintViolation<Candy>> violations
            = validator.validate(w);

        // assert
        assertEquals(1, violations.size());
        assertEquals("size must be between 4 and 10", violations.iterator().next().getMessage());
    }


    @Test
    public void short_circuit_if_pattern_is_in_violation() {
        // setup
        Candy w = new Candy();
        w.setName("SHRUBBERY");

        // action
        Set<ConstraintViolation<Candy>> violations
            = validator.validate(w);

        // assert
        assertEquals(1, violations.size());
        assertEquals("must match \"[a-z]\"", violations.iterator().next().getMessage());
    }
}

Summary

Beans validation is a powerful API, especially since it can be used within a Java EE server or in stand-alone Java SE applications. This is just a very short summary of the basics of the beans validation API, but, typically, it is enough to cover most questions developers have about how to use it.

February 11, 2015

Determine JDK version from a *.class file

Sometimes you run into JVM class file compability issues and it's useful to know what JDK version the class file was compiled as.  Doing this is farily easy and involves using the javap command which comes bundled with the JDK. 

Suppose you have a class named org.ferris.util.CalendarTools. To determine the JDK version of this class you would do something like this:

$ cd $PROJECT_HOME/target/classes
$ javap -classpath . -verbose org.ferris.util.CalendarTools

The output from running javap will look something like this:

Compiled from "CalendarTools.java"
public class org.ferris.util.CalendarTools extends java.lang.Object
SourceFile: "CalendarTools.java"
. . .

minor version: 0
major version: 50

. . .
Constant pool:


The important part is "major version: 50".  Visit this wiki page - http://en.wikipedia.org/wiki/Java_class_file#General_layout- to translate what this number means.  You'll see that a version of 50 means "J2SE 6.0 = 50 (0x32 hex)".  So the CalendarTools class was compiled to a JDK 6 format.

Enjoy!

January 21, 2015

Create Your Own Java Bean Validator with a Custom Element

Abstract
The purpose of this article is to demonstrate how to do two things.  The first is how to create your own Java bean validator as specified by JSR 349: Bean Validation 1.1.  The second is adding your own custom element to this validator so as to effect or define the validator's behavior.

System Requirements
This example was developed and run using the following system setup. If yours is different, it may work but no guarantees.
  • JDK 1.7.0_11
  • Eclipse Luna
  • Maven 3.2.1 (Embedded with Eclipse)
Maven Dependencies
The following dependencies are needed in your pom.xml to work with bean validation:

javax.validation
validation-api
1.1.0.Final


org.hibernate
hibernate-validator
5.1.2.Final


com.fasterxml
classmate
1.1.0

What is Bean Validation
JSR 349: Bean Validation 1.1 is the Java standard allowing you to develop reusable constraints and validators to ensure your application's data meets its business requirements. This may sound complicated, but it's actually very simple. Suppose your application is required to get a user's email address before successfully registering them for a new account. Traditionally, a developer would need to manually code this business requirement. Using JSR 349, the same business requirement can be satisfied using a reusable @NotNull constraint from the bean validation framework. Listing 1 demonstrates this.

Listing 1: Validate user's email address is not null
public class User {
@NotNull
protected String email;
// class continues...
}

As you can see from listing 1 the @NotNull constraint and the JSR 349 Bean Validation framework are responsible for validating the email address.  Additionally, the @NotNull constraint has no specific ties to email address meaning it can be reused to validate a users first name, last name, date of birth, or whatever data your business requirements say the user must provide.

The bean validation framework is very powerful in that it's also extensible. @NotNull is a very common constraint and as such is provided by the framework. However your application will no doubt have very specific business requirements which the built-in constraints cannot handle. Let's look at an example of such a requirement and how we can build our own constraints and validators to handle it.

Specific Business Requirement
Suppose your application needs to interact with the computer's file system. The user must select a directory but in order to guarantee your application does not inadvertently modify any existing files, it's required that the directory the user selects must be completely empty. This is a good example of data validation that is very specific to your application and which the bean validation framework does not handle out of the box. Remember though the bean validation framework is extensible. It's possible to create a constraint and validator to satisfy this business requirement.  Let's first look at creating the constraint.

Constraint
A bean validation constraint is a simple annotation. Listing 2 shows a @DirectoryIsEmpty validation constraint annotation we'll use to satisfy our application's business requirement.

Listing 2: DirectoryIsEmpty bean validation constraint
package org.ferris.validation.constraints;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import org.ferris.validation.validator.DirectoryIsEmptyValidator;

@Target({ 
   ElementType.TYPE, ElementType.ANNOTATION_TYPE
 , ElementType.METHOD, ElementType.FIELD
 , ElementType.PARAMETER, ElementType.CONSTRUCTOR })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = { DirectoryIsEmptyValidator.class })
@Documented
public @interface DirectoryIsEmpty {
    String message() default "{org.ferris.validation.constraints.DirectoryIsEmpty.message}";

    Class[] groups() default { };

    Class[] payload() default { };
    
    String[] excludes() default {};
}

Let's take a look at this constraint in detail.

#12 The @Target annotation defines what elements the @DirectoryIsEmpty can be put on.  In general, the annotation can either be put at the class-level, property-level, or parameter-level.  At the class-level, the validation occurs on the class as a whole. This is a way to validated properties which go together, like password and verifiedPassword properties need to be the same. At the property-level, the annotation can either go on the property or on the getter method for the property. At the parameter-level, the annotation goes on a constructor parameter or a method parameter. Typically the @Valid annotation is used at this level so the bean validation framework can validate properties before executing the constructor or method.

#17 The @Constraint annotation tells the bean validation framework which class is responsible for validating this constraint.  Here it defines the DirectoryIsEmptyValidator.class.

#19 @interface DirectoryIsEmpty is the standard way to define an annotation.

#20 The message element is required on bean validation constraint annotations. This element is used by the framework to determine what error message should be displayed if validation fails. You can hard code a plain text message, or, as is seen here, enter a resource bundle key as "{key_value}". By convention, the key value is the fully-qualified-class-name + ".message". The bean validation framework will look in the class path for a ValidationMessages.properties file.  This file is located at the root of the class path.

#22 The groups element is required on bean validation constraint annotations. This is used to group validation constraints together. For example, a field may have four validation constraints divided into three different groups. The @GroupSequence annotation can be used to define the sequence of the validation constraints.  This is helpful if a constraint validation needs to happen in a certain order.

#24 The payload element is required on bean validation constraint annotations, however it is not directly used by the bean validation framework itself. If a payload is present and a constraint violation occurs, the bean validation framework will put the payload into the ConstraintViolation#ConstraintDescriptor object for later use. If a payload is not present, the bean validation framework puts nothing into the object. A payload is a way to pass additional information about the constraint violation to the UI layer (or to any code) responsible for handling the violation. For example, a severity can be assigned to the payload to change the alerting level handling the violation.

#26 The excludes element is custom to this annotation. Just like any annotation, you are able to create your own custom elements in order to pass additional information to the validator to customize the validation. In this example, the excludes element is a String[] and it is used to define the names of directories which are excluded from the constraint validation. For example, suppose you have @DirectoryIsEmpty(excludes={"foo", "bar"}). At validation, the directory will NOT be checked if the name of the directory is either "foo" or "bar".

A constraint annotation is only the first part to creating your own bean validator. As seen on line #17, a class to do the validation is needed. In this example it is DirectoryIsEmptyValidator.class.  Let's take a look at this class next.

Validator
A validator class is the next piece you need to creating your own bean validation after creating the validation constraint annotation.  The annotation is used on whatever class, property, or parameter you want to validate. The validator class is responsible for doing the actual validation. Given our @DirectoryIsEmpty validation constraint annotation, listing 3 shows its validator

Listing 3: DirectoryIsEmptyValidator validator
package org.ferris.validation.validator;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.ferris.validation.constraints.DirectoryIsEmpty;

public class DirectoryIsEmptyValidator 
implements ConstraintValidator< DirectoryIsEmpty, File > {

 private List< String > excludes;
 
 @Override
 public void initialize(DirectoryIsEmpty arg0) {
  String [] strarr = arg0.excludes();
  if (strarr == null) {
   strarr = new String[]{};
  }
  excludes = Arrays.asList(strarr);
 }

 @Override
 public boolean isValid(File file, ConstraintValidatorContext context)
 {
  if (excludes.contains(file.getName())) {
   return true;
  }
  File [] files = file.listFiles();
  if (files != null && files.length > 0) {
   return false;
  } else {
   return true;
  }
 }
}

Let's take a look at this validator in more detail.

#11 Here we see the class implements the ConstraintValidator interface with the specific generics being DirectoryIsEmpty, and FileDirectoryIsEmpty obviously refers to the @DirectoryIsEmpty validation constraint annotation. File defines the @DirectoryIsEmpty annotation must be put on a class that extends File or on a File property or parameter. This of course make sense because our business requirement states the directory picked by the user must be empty if it is to be valid. Directories in Java are represented by the File object.

#13 This property will be used to hold a list of directory names excluded from the validator.

#16 The initialize method is part of the ConstraintValidator interface and can be overridden to do custom initialization of the validator.

#17 Here the excludes() method is called to get the String[] holding the names of the directories to exclude from validation. The excludes element may or may not be defined so the validator must handle both cases.  If the excludes element is defined and the excludes() method call returns a String[] of directory names to be excluded from validation, then the validator must ensure it does not validate those directories. If the excludes element is not defined and the excludes() method call returns nothing, then the validator should not exclude any directory from validation.

#25 The isValid method is part of the ConstraintValidator interface. This is where the magic happens. Code this method to perform any validation you need. Return true if valid, false otherwise.

#27 The code checks the excludes property to see if the list contains the name of the directory being validated. If the list does contain the name, then return true (#28) because that directory should be excluded from validation which means it is automatically valid.

#30 Use the File#listFiles method to get a list of all files and sub-directories. If there are files or sub-directories (#31) return false because the directory the user selected is not empty and fails the business requirement. Otherwise, return true (#34) because the directory the user selected is empty and this satisfies the business requirement.

You've learned how to create your own validation constraint annotation and its associated validator. You've also learned how easily the bean validation framework is extended and hopefully you recognize the great opportunities this gives you.

References
Bernard, Emmanuel. (2013, April). Bean Validation specification. beanvalidation.org. Retrieved January 21, 2015, from http://beanvalidation.org/1.1/spec/

JSR 349: Bean Validation 1.1. (n.d.). Java Community Process. Retrieved January 21, 2015, from https://jcp.org/en/jsr/detail?id=349

Enjoy!

January 09, 2015

Mocking System static void methods..config for Maven, JUnit, PowerMock, PowerMockito, and Mockito

Abstract
I previously wrote about Mocking return values of static methods..config for Maven, JUnit, PowerMock, EasyMock, and Mockito. The previous article focused on the need to mock a static method which returns a value. This article is also about mocking static methods, but static void methods - methods that return no value. Why would you need to mock such a method? Well my unit test needs to verify that a static void method was being called.  Specifically I wanted to Mockito.times(1) verify my application was calling the following System static void method on the Thread class: 

Thread.setDefaultUncaughtExceptionHandler(eh); 
My application's proper error handling depends on setting a default exception handler so it makes sense to have a unit test for it. Performing a Mockito.times(1) verify testing for this System static void method call however, has a number of challenges, including:
  1. It's a static method
  2. It's a static void method meaning it does not return a value
  3. It's a JVM System class
The purpose of this article is to show a simple JUnit code example to verify a call to a JVM System static void method such as Thread.setDefaultUncaughtExceptionHandler(eh).

System Requirements
This example was developed and run using the following system setup. If yours is different, it may work but no guarantees.
  • JDK 1.7.0_11
  • Eclipse Luna
  • Maven 3.2.1 (Embedded with Eclipse)
The rest of the software dependencies can be found in this article.

Maven POM dependencies
Listing 1 shows the Maven POM dependencies needed to run the unit test listed below.  From my research, these are the only dependencies you need.  

WARNING: If you do have JUnit or Mockito as direct dependencies, most likely you'll get at version mismatch and the unit tests will fail to run. They are pulled in as transitive dependencies of what's in Listing 1. 
Listing 1: Maven POM dependencies
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.5.6</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-easymock</artifactId>
    <version>1.5.6</version>
    <scope>test</scope>
</dependency>       
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.5.6</version>
    <scope>test</scope>
</dependency>        
<dependency>
    <groupId>org.easymock</groupId>
    <artifactId>easymock</artifactId>
    <version>3.2</version>
    <scope>test</scope>
</dependency>

Class Using a System static void method
Listing 2 shows a wrapper class which wraps the call to the System static void method Thread.setDefaultUncaughtExceptionHandler(eh). The reason for the wrapper class is described in the Mockito documentation which states such a wrapper class is required "If you need to mock classes loaded by the java system/bootstrap classloader (those defined in the java.lang or java.net etc)." I called my wrapper class ThreadTools.

Listing 2: Java ThreadTools wrapper class
/**
 * @author Michael Remijan mjremijan@yahoo.com @mjremijan
 */
public class ThreadTools {
  public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
    Thread.setDefaultUncaughtExceptionHandler(handler);
  }
} 

As you can see, ThreadTools is very simple. It doesn't add any overhead to your application to use this wrapper class and it is essential for the unit test to work properly. Now that we have a class to test, let's next take a look at what the unit test looks like.

Verifying a static void method in a unit test 
The goal of the unit test is to verify the System static void method Thread.setDefaultUncaughtExceptionHandler(eh)is actually called. In the Mockito world, verifing that a method has been called with certain parameter values is usually accomplished with code that looks like:

Mockito.verify(mockedObject, Mockito.times(1)).someMethod("param");

The above statement is used to verify that someMethod was called on the mockedObject only times(1) with exactly the "param" value passed to the method. We want to do something similary, only with a JVM System static void method, which makes it a little bit harder.
  
Listing 3 shows the Java source code for a very simple unit test which does exactly this. For this unit test you are going to be using a combination of PowerMockRunner, PowerMockito, and Mockito. Let's step through this unit test line by line.

NOTE: You'll be using PowerMockRunner, PowerMockito, and Mockito all at the same time, for sanity's sake, avoid using static imports! Static imports are a great convenience, but when mixing so many different technologies it get very hard to keep straight which methods are coming from which classes.

Listing 3: Java ThreadToolsTest class
import java.lang.Thread.UncaughtExceptionHandler;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ThreadTools.class) 
public class ThreadToolsTest {
  @Test
  public void testSetDefaultUncaughtExceptionHandleIsCalled() throws Exception {
    // Prepare
    PowerMockito.mockStatic(Thread.class);

    // Mock
    UncaughtExceptionHandler handler
      = Mockito.mock(UncaughtExceptionHandler.class);
    
    // Test
    new ThreadTools().setUncaughtExceptionHandler(handler);
    
    // Verify
    PowerMockito.verifyStatic(Mockito.times(1));
    Thread.setDefaultUncaughtExceptionHandler(handler);
  }
}

Let's take a look at this code in a bit more detail.

#9 @RunWith
We need to run the test with the PowerMockRunner, not the normal JUnit runner.

#10 @PrepareForTest
We need to prepare the wrapper class that uses the System static void method. This is important and easy to get confused. Do not prepare the System class, which in this example is Thread.class. You must prepare the wrapper class which is ThreadTools.class. To make the test easy, we created a wrapper class specifically for calling Thread.setDefaultUncaughtExceptionHandler(eh). In general, the class you must @PrepareForTest must be whatever class is making the System static void method call.

#12 PowerMockito.mockStatic(Thread.class)
Use PowerMockito to prepare the Thread.class for mocking.  Unlike normal mocking, this does not return a mock object, it just prepares Thread.class for mocking in the PowerMockito framework.

#18 Mockito.mock(UncaughtExceptionHandler.class)
This is a normal mock of the UncaughtExceptionHandler interface. Ultimately this mock should be passed to Thread.setUncaughtExceptionHander(eh) and  the goal of the unit test is to verify this has happened.

#22 new ThreadTools().setUncaughtExceptionHandler(handler)
This will now perform the test.  An instance of our wrapper class ThreadTools is created and its setUncaughtExceptionHandler(eh) method is called.  This in turn will call a "mocked" Thread.class.  After this test is performed, we should be able to verify the "mocked" Thread.class did get called.  We'll see this in the next lines.

#25 PowerMockito.verifyStatic(Mockito.times(1));
This tells the PowerMockito framework that it needs to verify that the class it statically mocked on line #15 (Thread.class) had a static void method called only 1 time.  But which method?  Look at the next like of code.

#26 Thread.setDefaultUncaughtExceptionHandler(handler);
The previously like, line #25 told PowerMockito to verify the static void method was called only 1 time. This line tells PowerMockito which method, which is setDefaultUncaughtExceptionHandler(eh).  Not only that, but it also tells PowerMockito that the parameter passed that to method should have been the handler object which is the mock of UncaughtExceptionHandler we create on line #18.

Conclusion
Mocking statics is not trivial, and mocking System static void method is even more tricky.  But PowerMockRunner, PowerMockito, and Mockito are powerful tools which make it possible. Put it all together with Maven and you have a good system to verifying your code base.

References
Using PowerMock with Mockito. (n.d.). code.google.com. Retrieved January 2015, from https://code.google.com/p/powermock/wiki/MockitoUsage13

Mocking system classes. (n.d.). code.google.com. Retrieved January 2015, from https://code.google.com/p/powermock/wiki/MockSystem

Class Mockito. (n.d.). docs.mockito.googlecode.com. Retrieved January 2015, from http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#1

fatmind. (2014 May 4). powermock example. github.com. Retrieved January 2015, from https://gist.github.com/fatmind/4110984
Enjoy!

December 31, 2014

Printing content of Java list

This is a very, very simple reference on how to print the contents of a Java List.  The idea is simple. I have a List and I want to loop over it and print whatever is stored in it. But do you really need to code a loop to do this?  Nope.  But I always forget how to correctly do it.  So here it is:

List< String > strings = new LinkedList< String >();
strings.add("one");
strings.add("two");
strings.add("three");

System.out.printf(
 "List< String >.toString()\n%s\n\n"
 ,strings.toString());
System.out.printf(
 "List< String >.toArray().toString()\n%s\n\n"
 ,strings.toArray().toString());
System.out.printf(
 "Arrays.toString(List< String >.toArray())\n%s\n\n"
 ,Arrays.toString(strings.toArray()));

The output looks like this:
List< String >.toString()
[one, two, three]

List< String >.toArray().toString()
[Ljava.lang.Object;@1ea87e7b

Arrays.toString(List< String >.toArray())
[one, two, three] 


Enjoy!


November 24, 2014

Beans Validation java.lang.ClassNotFoundException: com.sun.el.ExpressionFactoryImpl

If you are using the Beans Validation framework (JSR 349), you may encounter this obscure exception when doing your validation.

java.lang.ExceptionInInitializerError
Caused by: javax.el.ELException: Provider com.sun.el.ExpressionFactoryImpl not found
Caused by: java.lang.ClassNotFoundException: com.sun.el.ExpressionFactoryImpl

This exception is caused by a missing key lookup in the ValidationMessages.properties file.  Make sure you have the the key in the properties file.

Enjoy!

November 13, 2014

Remember PreparedStatement?

Simple example using PreparedStatement

Miss the good ole' days when interacting with the database was simple, easy to understand SQL statements and a few lines of code?

Select
public static void main(String[] args) throws Exception {
    String driver = "org.apache.derby.jdbc.EmbeddedDriver";
    
    String dbLocation 
        = String.format("./db/Sample");
    
    String connectionUrl =
        String.format("jdbc:derby:%s;create=true;user=sample;password=elpmas",dbLocation);
    
    Class.forName(driver);
    Connection conn = DriverManager.getConnection(connectionUrl);
    StringBuilder sp = new StringBuilder();
    sp.append("select \n");
    sp.append("    integer_value \n");
    sp.append("  , decimal_value \n");
    sp.append("  , varchar_value \n");
    sp.append("  , timestamp_value \n");
    sp.append("from example \n");
    PreparedStatement stmt = conn.prepareStatement(sp.toString());
    
    ResultSet rs = stmt.executeQuery();
    System.out.printf("ResultSet\n");
    while (rs.next()) {
     int i = rs.getInt(1);
     BigDecimal bd = rs.getBigDecimal(2);
     String s = rs.getString(3);
     Timestamp ts = rs.getTimestamp(4);
     
     System.out.printf("%d\t%f\t%s\t%s\n",i,bd,s, ts.toString());
    }

    conn.commit();
    conn.close();        
    System.out.printf("Goodbye\n");
}

Insert
public static void main(String[] args) throws Exception {
    String driver = "org.apache.derby.jdbc.EmbeddedDriver";
    
    String dbLocation 
        = String.format("./db/Sample");
    
    String connectionUrl =
        String.format("jdbc:derby:%s;create=true;user=sample;password=elpmas",dbLocation);
    
    Class.forName(driver);
    Connection conn = DriverManager.getConnection(connectionUrl);
    StringBuilder sp = new StringBuilder();
    sp.append("insert into example ( \n");
    sp.append("    integer_value \n");
    sp.append("  , decimal_value \n");
    sp.append("  , varchar_value \n");
    sp.append("  , timestamp_value \n");
    sp.append(" ) values ( \n");
    sp.append("    ? \n");
    sp.append("  , ? \n");
    sp.append("  , ? \n");
    sp.append("  , ? \n");
    sp.append(" ) \n");
    PreparedStatement stmt = conn.prepareStatement(sp.toString());
    stmt.setInt(1, 19);
    stmt.setBigDecimal(2, new BigDecimal("100.45"));
    stmt.setString(3, "Hello");        
    stmt.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
    
    int cnt = stmt.executeUpdate();
    
    System.out.printf("count = %d\n", cnt);

    conn.commit();
    conn.close();        
    System.out.printf("Goodbye\n");
}

Enjoy!

November 08, 2014

SSL JNDI Realm for Tomcat Catalina

Using JNDI as an authentication realm for Tomcat is quite common. What's also quite common is communication with the server needs to happen over SSL. In production, certificates are not a problem. In non-production (and especially development) environments, expired, self-signed, and untrusted SSL certificates are the norm. This project is an JNDI Realm for Tomcat Catalina which is designed to accept any SSL certificate, basically bypassing all security provided by certificates. So only use in development environments.


end

October 25, 2014

Mocking return values of static methods..config for Maven, JUnit, PowerMock, EasyMock, and Mockito

Abstract
I recently was working on code improvement and refactoring driven by unit testing when I came across the need to mock a Java static public method.  This is something I had never done before, but given the emphasis on testing these days, how hard could it be?  Well it took a number of hours to get working. Why so long? All examples I found showed the code but that is only 1/2 of what you need.  The other half, which is even more important, are the Maven dependencies. The purpose of this article is to show a simple code example of mocking a Java public static method and the Maven dependencies you need to get it all working.

System Requirements
The code was developed and run using the following system setup. If yours is different, it may work but no guarantees.
  • JDK 1.7.0_65
  • NetBeans 8.0.1
  • Maven 3.0.5 (bundled with NetBeans)
The rest of the software dependencies can be found in this article.

Maven POM dependencies
Listing 1 shows the Maven POM dependencies needed to run he unit test listed below.  From my research, these are the only dependencies you need.  NOTE that there is NO JUnit dependency and there is NO Mockito direct dependency. These are pulled in as transitive dependencies.  If you do have them as direct dependencies, most likely you'll get at version mismatch and the unit tests will fail to run. 

Listing 1: Maven POM dependencies
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.5.6</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-easymock</artifactId>
    <version>1.5.6</version>
    <scope>test</scope>
</dependency>       
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.5.6</version>
    <scope>test</scope>
</dependency>        
<dependency>
    <groupId>org.easymock</groupId>
    <artifactId>easymock</artifactId>
    <version>3.2</version>
    <scope>test</scope>
</dependency>

Class with a static method
Listing 2 shows the Java source code for a very simple class with a static method.  The goal is to mock this method.  Although this method is harmless and would not cause any problems in a unit test, most uses of static methods follow the builder design pattern and hence are responsible for constructing complex objects. In more real-world examples, the mock of the static method is needed to avoid the construction of the real object and instead return another mock object provided by the unit test. 

Listing 2: Java HelloStatic class
/**
 * @author Michael Remijan mjremijan@yahoo.com @mjremijan
 */
public class HelloStatic {
    public static String getHello() {
        return "Hello";
    }
}

Class using a static method
Listing 3 shows the Java source code for a very simple class which uses a static method.  Again the goal is to mock the static method call to return what we want. 

Listing 3: Java GreetingInstance class
/**
 * @author Michael Remijan mjremijan@yahoo.com @mjremijan
 */
public class GreetingInstance {    
    public String getGreeting(String name) {
        return String.format(
            "%s, %s"
          , HelloStatic.getHello(), name);
    }
} 

Mock the static method in a unit test
Listing 4 shows the Java source code for a very simple unit test which accomplishes the goal of mocking the static method so the unit test can control what the static method returns for asserting purposes. 

When mocking a static method, you are going to be using a combination of PowerMock, EasyMock, and JUnit.  Your unit test class may have other test methods testing other things with Mockito, so there is a lot of technology going on here.  For sanity's sake, avoid using static imports! Static imports are a great convenience, but when mixing so many different technologies it get very hard to keep straight which methods are coming from which classes.

Listing 4: Java GreetingInstanceTest class
/**
 * @author Michael Remijan mjremijan@yahoo.com @mjremijan
 */
@RunWith(PowerMockRunner.class) 
@PrepareForTest(HelloStatic.class)
public class GreetingInstanceTest {
    
    @Test
    public void echo() 
    {
        String shrubbery = "Shrubbery";
        String expected = "Shrubbery, Rita Red";
        String actual = null;
        
        PowerMock.mockStatic(HelloStatic.class);
        EasyMock.expect(HelloStatic.getHello()).andReturn(shrubbery);
        PowerMock.replay(HelloStatic.class);
        {
            actual = new GreetingInstance().getGreeting("Rita Red");
        }       
        PowerMock.verify(HelloStatic.class);
        Assert.assertEquals(expected, actual);
    }    
} 

Let's take a look at this code in a bit more detail.

#4 @RunWith
We need to run the test with the PowerMockRunner, not the normal JUnit runner.

#5 @PrepareForTest
We need to prepare the class with the static methods before running the unit test

#15 PowerMock.mockStatic(. . .)
Use PowerMock to mock the static methods.

#16 EasyMock.expect(. . .)
Use EasyMock to change what the static method returns.

#17 PowerMock.replay(. . .)
This changes the PowerMock mode to replay, which is the mode PowerMock needs to be in in order to run tests.

#19 actual = . . .
Run you test!  The static method should be mocked and return what you set it to return on line #16.

#21 PowerMock.verify(. . .)
This changes the PowerMock mode to verify, which is the mode PowerMock needs to be in in order to verify tests.

#22 Assert.equals(. . .)
Make sure the actual matches the expected where the expected is constructed by mocking the static method to return a different value.

Conclusion
That's it.  Quick, easy, and to the point.

References
johan.ha...@gmail.com. (2010 February 4). MockStatic. Retrieved October 2014, from https://code.google.com/p/powermock/wiki/MockStatic

sachin grover. (2013, June 25). PowerMock:: [java.lang.IllegalStateException: no last call on a mock available]. Retrieved October 2014, from http://stackoverflow.com/questions/17293780/powermock-java-lang-illegalstateexception-no-last-call-on-a-mock-available

end