Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

2026-02-11

Extending Java Libraries with Service Loader

Introduction

When designing a Java library, extensibility is often a key requirement, especially in the latter phases of the project. Library authors want to allow users to add custom behavior or provide their own implementations without modifying the core codebase. Java addresses this need with the Service Loader API, a built-in mechanism for discovering and loading implementations of a given interface at runtime.

Service Loader enables a clean separation between Application Programming Interface (API) and implementation, making it a solid choice for plugin-like architectures and Service Provider Interfaces (SPI). In this post, we’ll look at how Service Loader can be used in practice, along with its advantages and limitations when building extensible Java libraries.

Example Usage

In the demo project, the library allows customizing the naming strategy based on annotations, for which dedicated SPI implementations are provided.

SPI definition

First, let’s start with the SPI in the core library module:

public interface TypeAliasHandler<T extends Annotation> {
    Class<T> getSupportedAnnotation();

    String getTypeName(T annotation, Class<?> annotatedClass);
}

To enable Service Loader API to discover implementations of this interface, a configuration file must be created in the META-INF/services/ directory on the classpath. The file name must exactly match the fully qualified name of the interface. Inside this file, list the fully qualified class names of all implementing classes, one per line. This mechanism allows Service Loader to automatically find and load all available implementations at runtime.

Built-in providers

Within the same JAR file, we can define built-in annotations and their default behavior. For architectural consistency and convenience, the handler responsible for the built-in annotation also implements the SPI interface. This approach ensures that both internal and external implementations are treated uniformly by the Service Loader mechanism.

public class BuiltInTypeAliasHandler implements TypeAliasHandler<TypeAlias> {
    @Override
    public Class<TypeAlias> getSupportedAnnotation() {
        return TypeAlias.class;
    }

    @Override
    public String getTypeName(TypeAlias annotation, Class<?> annotatedClass) {
        return annotation.value();
    }
}

and the annotation is:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TypeAlias {
    String value();
}

The implementation needs to be defined in META-INF/services/com.github.alien11689.serviceloaderdemo.coreservice.spi.TypeAliasHandler with content:

com.github.alien11689.serviceloaderdemo.coreservice.builtin.BuiltInTypeAliasHandler

Extensions module

You can create a separate project (or JAR file) that provides custom annotations and their implementations. Such an extension module can be developed independently from the main library and added to the classpath as needed. This demonstrates the true power of Service Loader - the ability to add new functionality without modifying the main library’s source code. No recompilation or redeployment of the core library is required.

Let’s start with the annotations:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CustomTypeAlias {
    String nameOfTheType();
}

and

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface UpperCasedClassSimpleNameTypeAlias {
}

and their handlers - meaning the implementations of the SPI:

@ServiceProvider
public class CustomTypeAliasHandler implements TypeAliasHandler<CustomTypeAlias> {
    @Override
    public Class<CustomTypeAlias> getSupportedAnnotation() {
        return CustomTypeAlias.class;
    }

    @Override
    public String getTypeName(CustomTypeAlias annotation, Class<?> annotatedClass) {
        return annotation.nameOfTheType();
    }
}

and

@ServiceProvider
public class UpperCasedClassSimpleNameTypeAliasHandler implements TypeAliasHandler<UpperCasedClassSimpleNameTypeAlias> {
    @Override
    public Class<UpperCasedClassSimpleNameTypeAlias> getSupportedAnnotation() {
        return UpperCasedClassSimpleNameTypeAlias.class;
    }

    @Override
    public String getTypeName(UpperCasedClassSimpleNameTypeAlias annotation, Class<?> annotatedClass) {
        return annotatedClass.getSimpleName().toUpperCase();
    }
}

Since I used @ServiceProvider annotation available from Avaje, I don’t need to create the META-INF/services/com.github.alien11689.serviceloaderdemo.coreservice.spi.TypeAliasHandler manually. It will be created automatically during the build with the following content:

com.github.alien11689.serviceloaderdemo.extensions.custom.CustomTypeAliasHandler
com.github.alien11689.serviceloaderdemo.extensions.uppercased.UpperCasedClassSimpleNameTypeAliasHandler

Discovering the implementation

In one of the modules (even the one providing the SPI), there should be code that uses Service Loader API to discover all implementations and utilize them. In this example, I placed the discovery code in the core module, which is a practical approach - the central module can aggregate all available implementations and provide convenient access to the rest of the application.

In the static initialization block, Service Loader scans the whole classpath for configuration files and automatically creates instances of all found implementations:

public class TypeAliasProvider {

    private static Map<Class<? extends Annotation>, TypeAliasHandler> annotationToTypeNameHandler = new HashMap<>();

    static {
        var loader = ServiceLoader.load(TypeAliasHandler.class);
        loader.forEach(typeNameHandler -> annotationToTypeNameHandler.put(typeNameHandler.getSupportedAnnotation(), typeNameHandler));
    }

    // ...
}

In the same class, the discovered implementations can then be used based on the annotations present on a given class:

public class TypeAliasProvider {
    // ...

    public String getTypeName(Object o) {
        var aClass = o.getClass();
        for (Annotation annotation : aClass.getAnnotations()) {
            var typeNameHandler = annotationToTypeNameHandler.get(annotation.annotationType());
            if (typeNameHandler != null) {
                return typeNameHandler.getTypeName(annotation, aClass);
            }
        }
        return aClass.getName();
    }
}

Let’s test it together

To test the extension mechanism effectively, all SPI implementations must be available on the classpath. This means you need to include both the core module with the SPI definition and all extension modules containing specific implementations in the test project. Service Loader will automatically discover all available services and enable their use during test execution.

I prepared some test classes using the annotations:

@TypeAlias("class_a")
class ClassWithDefaultTypeAlias {
}

@CustomTypeAlias(nameOfTheType = "Class B with custom alias")
class ClassWithCustomTypeAlias {
}

@UpperCasedClassSimpleNameTypeAlias
class UpperCaseClass {
}

and a parameterized test verifying the resulting type names:

class TypeAliasExtensionMappingTest {

    private final TypeAliasProvider typeAliasProvider = new TypeAliasProvider();

    @ParameterizedTest
    @MethodSource("objectToTypeName")
    void should_map_object_to_type_name(Object o, String expectedTypeName) {
        Assertions.assertEquals(expectedTypeName, typeAliasProvider.getTypeName(o));
    }

    private static Stream<Arguments> objectToTypeName() {
        return Stream.of(
                arguments(new Object(), "java.lang.Object"),
                arguments(new ClassWithDefaultTypeAlias(), "class_a"),
                arguments(new ClassWithCustomTypeAlias(), "Class B with custom alias"),
                arguments(new UpperCaseClass(), "UPPERCASECLASS")
        );
    }
}

Full code

Full sample code you can find on my GitHub. The demo was initially designed to demonstrate extension possibilities for Javers.

Pros

  • Lightweight and dependency-free - Service Loader is part of the JDK and requires no additional runtime libraries.
  • Standardized solution - Works consistently across all JVM environments.
  • Automatic service discovery - Implementations are discovered at runtime without explicit registration in code.
  • Decoupled architecture - Encourages clean separation between core and pluggins.

Cons

  • No constructor arguments – Service implementations must provide a no-argument constructor, making configuration and dependency passing difficult. Some additional methods in SPI are necessary e.g. void configure(Properties properties)
  • No built-in dependency injection - Service Loader does not manage dependencies, scopes, or lifecycle.
  • Public class requirement - Service implementations must be declared as public, which limits encapsulation and hides fewer internal details.
  • Limited configurability - Conditional or environment-based service loading is not supported out of the box.
  • Harder to debug - Missing or incorrect service definitions may fail silently at runtime.
  • Not ideal for complex systems - For advanced use cases, full DI frameworks such as Spring or Guice offer more flexibility.

Summary

Service Loader is a simple yet powerful tool for building extensible Java libraries. It excels in scenarios where minimal dependencies, portability, and clear API boundaries are important. While it has notable limitations - particularly around constructor flexibility, dependency injection, and visibility constraints - it remains an excellent choice for lightweight extension mechanisms.

With the help of tools like Avaje, some of the traditional pain points of Service Loader can be reduced, making it an even more attractive option for modern Java library design.

2018-09-27

Testing Kotlin with Spock Part 3 - Interface default method

Kotlin allows you to put method implementation in an interface. The same mechanism can be found in Java interfaces as default methods (and also Groovy or Scala traits). Let's see the difference between the Kotlin and Java default methods in interface by testing it with Groovy and Spock.

What do we want to test?

We often have an interface for access object from the database. In domain, they might look similar to this KotlinOrderRepository:

interface KotlinOrderRepository {
    fun save(order: Order)

    fun find(orderId: OrderId): Order?

    fun get(orderId: OrderId): Order =
            find(orderId) ?: throw NotFound()
}

How to fake it with Groovy?

When we want to use such interface in tests, we can, of course, mock it. However, it is far better to fake repositories with a simple, in-memory implementation. Let's create FakeKotlinOrderRepository in Groovy:

class FakeKotlinOrderRepository implements KotlinOrderRepository {
    private Map<OrderId, Order> data = [:]

    @Override
    void save(Order order) {
        data[order.id] = order
    }

    @Override
    Order find(OrderId orderId) {
        return data[orderId]
    }
}

Unfortunately, this causes a compilation error

/testing-kotlin-in-spock/src/test/groovy/com/github/alien11689/testingkotlinwithspock/defaultmethod/FakeKotlinOrderRepository.groovy: 3: Can't have an abstract method in a non-abstract class. The class 'com.github.alien11689.testingkotlinwithspock.defaultmethod.FakeKotlinOrderRepository' must be declared abstract or the method 'com.github.alien11689.testingkotlinwithspock.defaultmethod.Order get(com.github.alien11689.testingkotlinwithspock.defaultmethod.OrderId)' must be implemented.
 @ line 3, column 1.
   class FakeKotlinOrderRepository implements KotlinOrderRepository {
   ^

1 error

The compiler doesn't see the implementation of the get method in the Kotlin interface. We have to use some magic to make it work in groovy.

Solution

To solve the problem, let's look into the generated classes:

$ ls build/classes/main/com/github/alien11689/testingkotlinwithspock/defaultmethod/
JavaOrderRepository.class
KotlinOrderRepository.class
KotlinOrderRepository$DefaultImpls.class
NotFound.class
Order.class
OrderId.class

The KotlinOrderRepository$DefaultImpls class is the one we're looking for as we can use it in Groovy to implement the missing operation.

class FakeKotlinOrderRepository implements KotlinOrderRepository {

    // ...

    Order get(OrderId orderId) {
        return KotlinOrderRepository.DefaultImpls.get(this, orderId)
    }
}

Now the code compiles and tests pass:

class KotlinRepositoryWithDefaultMethodTest extends Specification {
    OrderId orderId = new OrderId(UUID.randomUUID() as String)
    Order order = new Order(orderId, 'data')
    KotlinOrderRepository kotlinOrderRepository = new FakeKotlinOrderRepository()

    def 'should get order from kotlin repository'() {
        given:
            kotlinOrderRepository.save(order)
        expect:
            kotlinOrderRepository.get(orderId) == order
    }

    def 'should throw NotFound when order does not exist in kotlin repository'() {
        when:
            kotlinOrderRepository.get(orderId)
        then:
            thrown(NotFound)
    }
}

Is there the same problem with Java?

Let's have a quick look at how this works with Java interfaces. If we write a similar repository in Java:

public interface JavaOrderRepository {
    void save(Order order);

    Optional<Order> find(OrderId orderId);

    default Order get(OrderId orderId) {
        return find(orderId).orElseThrow(NotFound::new);
    }
}

and create a fake implementation in Groovy:

class FakeJavaOrderRepository implements JavaOrderRepository {
    private Map<OrderId, Order> data = [:]

    @Override
    void save(Order order) {
        data[order.id] = order
    }

    @Override
    Optional<Order> find(OrderId orderId) {
        return Optional.ofNullable(data[orderId])
    }
}

there is no compilation error and the tests pass:

class JavaRepositoryWithDefaultMethodTest extends Specification {
    OrderId orderId = new OrderId(UUID.randomUUID() as String)
    Order order = new Order(orderId, 'data')
    JavaOrderRepository javaOrderRepository = new FakeJavaOrderRepository()

    def 'should get order from java repository'() {
        given:
            javaOrderRepository.save(order)
        expect:
            javaOrderRepository.get(orderId) == order
    }

    def 'should throw NotFound when order does not exist in java repository'() {
        when:
            javaOrderRepository.get(orderId)
        then:
            thrown(NotFound)
    }
}

Groovy can implement Java interfaces with the default methods without any problems.

Show me the code

Code is available here.

2018-05-28

Testing Kotlin with Spock Part 2 - Enum with instance method

The enum class with instance method in Kotlin is quite similar to its Java version, but they are look a bit different in the bytecode. Let's see the difference by writing some tests using Spock.


What do we want to test?

Let's see the code that we want to test:
enum class EnumWithInstanceMethod {
    PLUS {
        override fun sign(): String = "+"
    },
    MINUS {
        override fun sign(): String = "-"
    };

    abstract fun sign(): String
}
Obviously, it can be written in a better way (e. g. using enum instance variable), but this example shows the case we want to test in the simplest way.


How to test it with Spock?

The simplest test (that does not work)

First, we can write the test like we would do it with a Java enum:
def "should use enum method like in java"() {
    expect:
        EnumWithInstanceMethod.MINUS.sign() == '-'
}
The test fails:
Condition failed with Exception:

EnumWithInstanceMethod.MINUS.sign() == '-'
                             |
                             groovy.lang.MissingMethodException: No signature of method: static com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethod$MINUS.sign() is applicable for argument types: () values: []
                             Possible solutions: sign(), sign(), is(java.lang.Object), find(), with(groovy.lang.Closure), find(groovy.lang.Closure)


    at com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethodTest.should use enum method like in java(EnumWithInstanceMethodTest.groovy:11)
Caused by: groovy.lang.MissingMethodException: No signature of method: static com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethod$MINUS.sign() is applicable for argument types: () values: []
Possible solutions: sign(), sign(), is(java.lang.Object), find(), with(groovy.lang.Closure), find(groovy.lang.Closure)
    ... 1 more
Interesting... Why is Groovy telling us that we are trying to call a static method? Maybe we are not using the enum instance but something else?. Let's create a test where we pass the enum instance to method:
static String consume(EnumWithInstanceMethod e) {
    return e.sign()
}

def "should pass enum as parameter"() {
    expect:
        consume(EnumWithInstanceMethod.MINUS) == '-'
}
Error message:
Condition failed with Exception:

consume(EnumWithInstanceMethod.MINUS) == '-'
|
groovy.lang.MissingMethodException: No signature of method: static com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethodTest.consume() is applicable for argument types: (java.lang.Class) values: [class com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethod$MINUS]
Possible solutions: consume(com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethod)


    at com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethodTest.should pass enum as parameter(EnumWithInstanceMethodTest.groovy:29)
Caused by: groovy.lang.MissingMethodException: No signature of method: static com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethodTest.consume() is applicable for argument types: (java.lang.Class) values: [class com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethod$MINUS]
Possible solutions: consume(com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethod)
    ... 1 more
Now we see that we passed the class com.github.alien11689.testingkotlinwithspock.EnumWithInstanceMethod$MINUS, not the enum instance.


But it works in Java...

Analogous code in JUnit works perfectly and the test passes:
@Test
public void shouldReturnSign() {
    assertEquals("-", EnumWithInstanceMethod.MINUS.sign());
}
Java can access Kotlin's instance method without problems, so maybe something is wrong with Groovy...
But the Java enum with instance method, e. g.
public enum EnumWithInstanceMethodInJava {
    PLUS {
        public String sign() {
            return "+";
        }
    },
    MINUS {
        public String sign() {
            return "-";
        }
    };

    public abstract String sign();
}
works correctly in the Spock test:
def "should use enum method"() {
    expect:
        EnumWithInstanceMethodInJava.MINUS.sign() == '-'
}


What's the difference?

We can spot the difference just by looking at the compiled classes:
$ tree build/classes/main/
build/classes/main/
└── com
    └── github
        └── alien11689
            └── testingkotlinwithspock
                ├── AdultValidator.class
                ├── EnumWithInstanceMethod.class
                ├── EnumWithInstanceMethodInJava$1.class
                ├── EnumWithInstanceMethodInJava$2.class
                ├── EnumWithInstanceMethodInJava.class
                ├── EnumWithInstanceMethod$MINUS.class
                ├── EnumWithInstanceMethod$PLUS.class
                ├── Error.class
                ├── Ok.class
                ├── ValidationStatus.class
                └── Validator.class
Java generates anonymous classes (EnumWithInstanceMethodInJava$1 and EnumWithInstanceMethodInJava$2) for the enum instances, but Kotlin names those classes after the enum instances names (EnumWithInstanceMethod$MINUS and EnumWithInstanceMethod$PLUS).
How does it tie into the problem with Groovy? Groovy does not need the .class when accessing class in code, so when we try to access EnumWithInstanceMethod.MINUS, Groovy converts it to EnumWithInstanceMethod.MINUS.class, not the instance of the enum. The same problem does not occur in Java code since there is no EnumWithInstanceMethodInJava$MINUS class.


Solution

Knowing the difference, we can solve the problem of accessing Kotlin's enum instance in our Groovy code.
The first solution is accessing the enum instance with valueOf method:
def "should use enum method working"() {
    expect:
        EnumWithInstanceMethod.valueOf('MINUS').sign() == '-'
}
The second way is to tell Groovy explicitly that we want to access the static field which is the instance of enum:
def "should use enum method"() {
    expect:
        EnumWithInstanceMethod.@MINUS.sign() == '-'
}
You can choose either solution depending on style of your code and your preferences.


Show me the code

Code is available here.

2018-01-18

MapStruct mapper injection in OSGi Blueprint

What is MapStruct?

According to MapStruct website:
MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. The generated mapping code uses plain method invocations and thus is fast, type-safe and easy to understand.

Inject MapStruct mapper in Blueprint OSGi

Such mappings are sometimes necessary in our integration projects. We also use OSGi to create our applications and Blueprint for dependency injection. Blueprin Maven Plugin makes it very easy to use, providing annotation support.
MapStruct supports component models like cdi, spring and jsr330, so generated classes could be used as beans. Fortunately, Blueprint Maven Plugin uses annotations from JSR 330, such as Singleton or Named.
The only thing we have to do is to add property componentModel with value jsr330 to a mapping interface:
@Mapper(componentModel = "jsr330")
public interface PersonMapper {
    Person toDomain(PersonDto personDto);
}
and now we can inject PersonMapper to our beans:
@Singleton
@AllArgsConstructor
public class CreatePersonHandler {
    private final PersonRepository personRepository;
    private final PersonMapper personMapper;

    // ...
}
Blueprint Maven Plugin will generate an XML file with bean PersonMapperImpl and inject it to CreatePersonHandler:
<?xml version="1.0" encoding="UTF-8"?><blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
    <bean id="createPersonHandler" class="com.github.alien11689.osgi.mapstructblueprint.CreatePersonHandler">
        <argument ref="personRepository"/>
        <argument ref="personMapperImpl"/>
    </bean>
    <bean id="personMapperImpl" class="com.github.alien11689.osgi.mapstructblueprint.PersonMapperImpl"/>
    <bean id="personRepository" class="com.github.alien11689.osgi.mapstructblueprint.PersonRepository"/>
</blueprint>

Generate all mappers with JSR 330 annotations

If you have multiple mappers and all of them should be beans, then you can simply add one compiler argument in configuration and all the mappers will have @Singleton and @Named annotations by default.
<?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">
    ...
    <build>
        <plugins>
            ...
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin.version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArgs>
                        <compilerArg>
                             -Amapstruct.defaultComponentModel=jsr330
                        </compilerArg>
                    </compilerArgs>
                </configuration>
            </plugin>
            ...
        </plugins>
    </build>
</project>

Try it on your own

The code is available at Github.

2016-08-16

Deploy WSDL file as OSGI Bundle in Apache Karaf

Introduction

WSDL file describes webservices. Java classes are often generated from WSDL. For this purpose, we could use command line tools (e. g. wsdl2Java or wsimport) or using maven plugin.

From the other side, we have Apache Karaf which is OSGI container. Karaf has installed by default many deployers for creating OSGi bundles from files, e. g. Blueprint deployer, Spring deployer or War deployer.

It is easy to generate java classes from WSDL file and also to create custom deployer for Karaf, so why do not join these two features?

Installation of WSDL deployer

Source code of my WSDL deployer is provided here. You can download and build it:

mvn clean install

We also need Karaf. I will use the newest version 4.0.5. It could be download from Karaf website. When you download and unpack it, you can run it:

$ cd PUT_PATH_TO_KARAF_DIR_HERE
$ ./bin/karaf
    __ __                  ____      
   / //_/____ __________ _/ __/      
  / ,<  / __ `/ ___/ __ `/ /_        
 / /| |/ /_/ / /  / /_/ / __/        
/_/ |_|\__,_/_/   \__,_/_/         

Apache Karaf (4.0.5)

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown Karaf.

karaf@root()>

and install commons-io and wsdl-delpoyer bundles:

karaf@root()> install -s mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-io/1.4_3
Bundle ID: 52
karaf@root()> install -s mvn:com.github.alien11689.karaf/wsdl-deployer/1.0.0-SNAPSHOT
Bundle ID: 53

Install WSDL from Karaf shell

I will test deployer using WSDL file named exampleService-2.0.0.wsdl (provided WSDL is similar to this, but has another namespace in types schama for testing purpose):

<?xml version="1.0"?>
<wsdl:definitions
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:tns="http://Example.org"
  xmlns:sns="http://Example.org/schema"
  xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
  xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
  xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract"
  xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
  xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
  xmlns:wsa10="http://www.w3.org/2005/08/addressing"
  xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
  targetNamespace="http://Example.org"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
      <xsd:schema targetNamespace="http://Example.org/schema" elementFormDefault="qualified" >
  <xsd:element name="Add">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" name="a" type="xsd:int" />
        <xsd:element minOccurs="0" name="b" type="xsd:int" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="AddResponse">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" name="result" type="xsd:int" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="Subtract">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" name="a" type="xsd:int" />
        <xsd:element minOccurs="0" name="b" type="xsd:int" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="SubtractResponse">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="0" name="result" type="xsd:int" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="ICalculator_Add_InputMessage">
    <wsdl:part name="parameters" element="sns:Add" />
  </wsdl:message>
  <wsdl:message name="ICalculator_Add_OutputMessage">
    <wsdl:part name="parameters" element="sns:AddResponse" />
  </wsdl:message>
  <wsdl:message name="ICalculator_Subtract_InputMessage">
    <wsdl:part name="parameters" element="sns:Subtract" />
  </wsdl:message>
  <wsdl:message name="ICalculator_Subtract_OutputMessage">
    <wsdl:part name="parameters" element="sns:SubtractResponse" />
  </wsdl:message>
  <wsdl:portType name="ICalculator">
    <wsdl:operation name="Add">
      <wsdl:input wsaw:Action="http://Example.org/ICalculator/Add" message="tns:ICalculator_Add_InputMessage" />
      <wsdl:output wsaw:Action="http://Example.org/ICalculator/AddResponse" message="tns:ICalculator_Add_OutputMessage" />
    </wsdl:operation>
    <wsdl:operation name="Subtract">
      <wsdl:input wsaw:Action="http://Example.org/ICalculator/Subtract" message="tns:ICalculator_Subtract_InputMessage" />
      <wsdl:output wsaw:Action="http://Example.org/ICalculator/SubtractResponse" message="tns:ICalculator_Subtract_OutputMessage" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="DefaultBinding_ICalculator" type="tns:ICalculator">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="Add">
      <soap:operation soapAction="http://Example.org/ICalculator/Add" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="Subtract">
      <soap:operation soapAction="http://Example.org/ICalculator/Subtract" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="CalculatorService">
        <wsdl:port name="ICalculator" binding="tns:DefaultBinding_ICalculator">
            <soap:address location="http://localhost/ICalculator" />
        </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

We could install it via command:

karaf@root()> install -s wsdl:file:PUT_PATH_TO_WSDL_HERE/exampleService-2.0.0.wsdl\$package=org.github.alien11689.example&s1=http://Example.org/schema&t1=org.github.alien11689.example.schema
Bundle ID: 54

File must have format ${bundleSymbolicName}-${version}.wsdl.

Provided options are:

  • package - allows to change package of generated interface
  • pair s1 and t1 - maps schema in WSDL to package (WSDL deployer is in draft verion nowadays provides options to map only one schema).

Karaf has installed this file:

karaf@root()> headers 54

Bundle 54
---------
Manifest-Version = 2

Bundle-ManifestVersion = 2
Bundle-SymbolicName = exampleService-2.0.0.wsdl
Bundle-Version = 2.0.0

Export-Package =
    org.github.alien11689.example.schema;version=2.0.0,
    org.github.alien11689.example;version=2.0.0
Import-Package =
    javax.jws,
    javax.jws.soap,
    javax.xml.bind.annotation,
    javax.xml.namespace,
    javax.xml.ws

Install WSDL by putting it into Karaf drop folder

You can also install WSDL file by copying it to deploy directory:

cp PUT_PATH_TO_WSDL_HERE/exampleService-2.0.0.wsdl PUT_PATH_TO_KARAF_DIR_HERE/deploy/deployedExampleService-2.0.0.wsdl

It is much more simple to do, but do not allow for customization (e. g. namespace to package mapping). It creates bundle:

karaf@root()> list | grep deployedExampleService
55 | Active |  80 | 2.0.0          | deployedExampleService-2.0.0.wsdl
karaf@root()> headers 55

Bundle 55
---------
Manifest-Version = 2

Bundle-ManifestVersion = 2
Bundle-SymbolicName = deployedExampleService-2.0.0.wsdl
Bundle-Version = 2.0.0

Export-Package =
    org.example;version=2.0.0,
    org.example.schema;version=2.0.0
Import-Package =
    javax.jws,
    javax.jws.soap,
    javax.xml.bind.annotation,
    javax.xml.namespace,
    javax.xml.ws

How does it work?

Deployer uses wsimport command to create in temporary directory and compile generated java classes. Compiled class are packed with MANIFEST.MF into service.jar and such jar is really installed in OSGi container. For example, my temporary directory is /tmp/4ff81631-3c08-487a-b731-1f95c568026f:

$ tree /tmp/4ff81631-3c08-487a-b731-1f95c568026f
/tmp/4ff81631-3c08-487a-b731-1f95c568026f
├── Jaxb-binding.xml
├── Jaxws-binding.xml
├── service.wsdl
├── src
│   └── org
│       └── github
│           └── alien11689
│               └── example
│                   ├── CalculatorService.java
│                   ├── ICalculator.java
│                   └── schema
│                       ├── Add.java
│                       ├── AddResponse.java
│                       ├── ObjectFactory.java
│                       ├── package-info.java
│                       ├── Subtract.java
│                       └── SubtractResponse.java
└── target
    ├── org
    │   └── github
    │       └── alien11689
    │           └── example
    │               ├── CalculatorService.class
    │               ├── ICalculator.class
    │               └── schema
    │                   ├── Add.class
    │                   ├── AddResponse.class
    │                   ├── ObjectFactory.class
    │                   ├── package-info.class
    │                   ├── Subtract.class
    │                   └── SubtractResponse.class
    └── service.jar

And my service.jar contains:

$ jar tf /tmp/4ff81631-3c08-487a-b731-1f95c568026f/target/service.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/github/
org/github/alien11689/
org/github/alien11689/example/
org/github/alien11689/example/schema/
org/github/alien11689/example/schema/Add.class
org/github/alien11689/example/schema/ObjectFactory.class
org/github/alien11689/example/schema/Subtract.class
org/github/alien11689/example/schema/SubtractResponse.class
org/github/alien11689/example/schema/package-info.class
org/github/alien11689/example/schema/AddResponse.class
org/github/alien11689/example/ICalculator.class
org/github/alien11689/example/CalculatorService.class

Conclusion

WSDL generation and Karaf deployers could be easily joined and simplified creation of OSGi bundles without explicite creation of jar. Provided WSDL deployer is just draft, but could be very useful when we have many WSDLs and do not want to create separate artifacts for them.

Source code of WSDL deployer is provided here.

2016-01-17

Do not use AllArgsConstructor in your public API

Introduction

Do you think about compatibility of your public API when you modify classes from it? It is especially easy to miss out that something incompatibly changed when you are using Lombok. If you use AllArgsConstructor annotation it will cause many problems.

What is the problem?

Let's define simple class with AllArgsConstructor:

@Data
@AllArgsConstructor
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
}

Now we can use generated constructor in spock test:

def 'use generated allArgsConstructor'() {
    when:
        Person p = new Person('John', 'Smith', 30)
    then:
        with(p) {
            firstName == 'John'
            lastName == 'Smith'
            age == 30
        }
}

And the test is green.

Let's add new optional field to our Person class - email:

@Data
@AllArgsConstructor
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
    private String email;
}

Adding optional field is considered compatible change. But our test fails...

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.github.alien11689.allargsconstructor.Person(java.lang.String, java.lang.String, java.lang.Integer)

How to solve this problem?

After adding field add previous constructor

If you still want to use AllArgsConstructor you have to ensure compatibility by adding previous version of constructor on your own:

@Data
@AllArgsConstructor
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
    private String email;

    public Person(String firstName, String lastName, Integer age) {
        this(firstName, lastName, age, null);
    }
}

And now our test again passes.

Annotation lombok.Data is enough

If you use only Data annotation, then constructor, with only mandatory (final) fields, will be generated. It is because Data implies RequiredArgsConstructor:

@Data
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
}
class PersonTest extends Specification {
    def 'use generated requiredFieldConstructor'() {
        when:
            Person p = new Person('John', 'Smith')
            p.age = 30
        then:
            with(p) {
                firstName == 'John'
                lastName == 'Smith'
                age == 30
            }
    }
}

After adding new field email test still passes.

Use Builder annotation

Annotation Builder generates for us PersonBuilder class which helps us create new Person:

@Data
@Builder
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
}
class PersonTest extends Specification {
    def 'use builder'() {
        when:
            Person p = Person.builder()
                    .firstName('John')
                    .lastName('Smith')
                    .age(30).build()
        then:
            with(p) {
                firstName == 'John'
                lastName == 'Smith'
                age == 30
            }
    }
}

After adding email field test still passes.

Conclusion

If you use AllArgsConstructor you have to be sure what are you doing and know issues related to its compatibility. In my opinion the best option is not to use this annotation at all and instead stay with Data or Builder annotation.

Sources are available here.

2015-12-13

Primitives and its wrapped types compatibility

Introduction

How often do you think about possible changes in your API? Do you consider that something required could become optional in future? How about compatibility of such change? One of this changes is going from primitive (e. g. int) to its wrapped type (e. g. Integer). Let's check it out.

API - first iteration

Let's start with simple DTO class Dep in our public API.

public class Dep {
    private int f1;

    public int getF1(){
        return f1;
    }

    public void setF1(int f1){
        this.f1 = f1;
    }

    // other fields and methods omitted
}

f1 is obligatory field that never will be null.

Let's use it in Main class:

public class Main {
    public static void main(String... args) {
        Dep dep = new Dep();
        dep.setF1(123);
        System.out.println(dep.getF1());
    }
}

compile it:

$ javac depInt/Dep.java
$ javac -cp depInt main/Main.java

and run:

$ java -cp depInt:main Main
123

It works.

API - obligatory field become optional

Now suppose our business requirements have changed. f1 is not longer obligatory and we want possibility to set it to null.

So we provide next iteration of Dep class where f1 field has type Integer.

public class Dep {
    private Integer f1;

    public Integer getF1(){
        return f1;
    }

    public void setF1(Integer f1){
        this.f1 = f1;
    }

    // other fields and methods omitted
}

We compile only the new Dep class because we do not want to change the Main class:

$ javac depInteger/Dep.java

and run it with old Main:

$ java -cp depInteger:main Main
Exception in thread "main" java.lang.NoSuchMethodError: Dep.setF1(I)V
    at Main.main(Main.java:4)

Wow! It does not work...

Why does it not work?

We can use javap tool to investigate Main class.

$ javap -c main/Main.class
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String...);
    Code:
       0: new           #2                  // class Dep
       3: dup
       4: invokespecial #3                  // Method Dep."<init>":()V
       7: astore_1
       8: aload_1
       9: bipush        123
      11: invokevirtual #4                  // Method Dep.setF1:(I)V
      14: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      17: aload_1
      18: invokevirtual #6                  // Method Dep.getF1:()I
      21: invokevirtual #7                  // Method java/io/PrintStream.println:(I)V
      24: return
}

The most important are 11th and 18th instructions of main method. Main lookups for methods which use int (I in method signature).

Next let's compile the Main class with Dep which has f1 of type Integer:

$ javac -cp depInteger main/Main.java

and use javap on this class:

$ javap -c main/Main.class
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String...);
    Code:
       0: new           #2                  // class Dep
       3: dup
       4: invokespecial #3                  // Method Dep."<init>":()V
       7: astore_1
       8: aload_1
       9: bipush        123
      11: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      14: invokevirtual #5                  // Method Dep.setF1:(Ljava/lang/Integer;)V
      17: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
      20: aload_1
      21: invokevirtual #7                  // Method Dep.getF1:()Ljava/lang/Integer;
      24: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      27: return
}

Now we see the difference. The main method:

  • converts int to Integer in instruction 11th,
  • invokes method setF1 which takes parameter of type Integer (Ljava/lang/Integer;) in instruction 14th,
  • invokes method getF1 which returns Integer in instruction 21st.

These differences do not allow us to use the Main class with Dep without recompilation if we change f1.

How about Groovy?

We have GroovyMain class which do the same as Main class written in Java.

class GroovyMain {
    static void main(String... args) {
        Dep dep = new Dep(f1: 123)
        println(dep.f1)
    }
}

We will compile GroovyMain class only with Dep which uses int:

$ groovyc -cp lib/groovy-all-2.4.5.jar:depInt -d main main/GroovyMain.groovy

It runs great as expected with int:

$ java -cp lib/groovy-all-2.4.5.jar:depInt:main GroovyMain
123

but with Integer... It works the same!

$ java -cp lib/groovy-all-2.4.5.jar:depInteger:main GroovyMain
123

Groovy is immune to such change.

With CompileStatic

But what if we compile groovy with CompileStatic annotation? This annotation instructs groovy compiler to compile class with type checking and should produce bytecode similar to javac output.

GroovyMainCompileStatic class is GroovyMain class with only CompileStatic annotation:

import groovy.transform.CompileStatic

@CompileStatic
class GroovyMainCompileStatic {
    static void main(String... args) {
        Dep dep = new Dep(f1: 123)
        println(dep.f1)
    }
}

When we compile this with Dep with int field:

$ groovyc -cp lib/groovy-all-2.4.5.jar:depInt -d main main/GroovyMainCompileStatic.groovy

then of course it works:

$ java -cp lib/groovy-all-2.4.5.jar:depInt:main GroovyMainCompileStatic
123

but with Dep with Integer field it fails like in Java:

$ java -cp lib/groovy-all-2.4.5.jar:depInteger:main GroovyMainCompileStatic
Exception in thread "main" java.lang.NoSuchMethodError: Dep.setF1(I)V
    at GroovyMainCompileStatic.main(GroovyMainCompileStatic.groovy:6)

Conclusion

Change from primitive to its wrapped java type is not compatible change. Bytecode which uses dependent class assumes that there will be method which consumes or returns e. g. int and cannot deal with the same class which provides such method with Integer in place of int.

Groovy is much more flexible and could handle it, but only if we do not use CompileStatic annotation.

The source code is available here.

2015-12-02

Scheduling tasks using Message Queue

Introduction

How to schedule your task for later execution? You often create table in database, configure job that checks if due time of any task occured and then execute it.

But there is easier way if only you have message broker with your application... You could publish/send your message and tell it that it should be delivered with specified delay.

Scheduling messages using ActiveMQ

ActiveMQ is open source message broker written in Java. It is implementation of JMS (Java Message Service).

You could start its broker with scheduling support by adding flag schedulerSupport to broker configuration:

<beans ...>
    ...
    <broker xmlns="http://activemq.apache.org/schema/core"
            brokerName="localhost"
            dataDirectory="${activemq.data}"
            schedulerSupport="true">
            ...
    </broker>
    ...
</beans>

Now, if you want to delay receiving message by few seconds, you could add property during message creation, e.g.:

message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 8000)

Delay unit is miliseconds.

Of course queue must be persisted.

When you listen for message on the same queue, then you will see that message indeed will be received with 8 second delay.

...
Send time: Tue Dec 01 18:51:23 CET 2015
...
Message received at Tue Dec 01 18:51:31 CET 2015
...

Scheduling messages using RabbitMQ

Scheduling tasks is not only the feature of ActiveMQ. It is also available with RabbitMQ.

RabitMQ is message broker written in Erlang. It uses protocol AMQP.

First you have to install plugin rabbitmq_delayed_message_exchange. It could be done via command:

rabbitmq-plugins enable --offline rabbitmq_delayed_message_exchange

You have to define exchange in RabbitMQ which will use features from this plugin. Queue for delayed messages should be bound to this exchange. Routing key should be set to queue name.

channel.exchangeDeclare(exchange, 'x-delayed-message', true, false, ['x-delayed-type': 'direct']);
channel.queueBind(queue, exchange, queue);
channel.queueDeclare(queue, true, false, false, null);

Of course queue must be persisted.

To test it just publish new message with property x-delay:

channel.basicPublish(exchange,
                    queue,
                    new AMQP.BasicProperties.Builder().headers('x-delay': 8000).build(),
                    "Message: $currentUuid".bytes)

Message will be delayed with 8 seconds:

...
Send time: Tue Dec 01 19:04:18 CET 2015
...
Message received at Tue Dec 01 19:04:26 CET 2015
...

Conclusion

Why you create similar mechanism for handling scheduled tasks on your own, when you could use your message brokers and delayed messages to schedule future tasks?

Sources are available here.

2014-04-02

Guice Tutorial - 03 - Providers

Introduction

Dependencies injected by Guice are generally created using annotated constructor. But sometimes you need a generator of specific class objects or you have to initialize your class before using it. These goals you can meet using providers. First, suppose you have ReportController, which stores given message with actual date in some place (database, file).


Injecting Provider

If you want to write good unit tests, you should protect yourself against changing date, so you can inject a kind of date generator - Provider of Date.
public class DateProviderTest {
    @Test
    public void shouldGetAnotherTimeForEachGet() throws InterruptedException {
        // given
        Injector injector = Guice.createInjector();
        Provider<Date> sut = injector.getProvider(Date.class);
        // when
        Date firstDate = sut.get();
        Thread.sleep(1);
        Date secondDate = sut.get();
        // then
        assertNotNull(firstDate);
        assertNotNull(secondDate);
        assertNotEquals(firstDate.getTime(), secondDate.getTime());
    }
}
In unit tests for classes, which use this provider you only need to mock Provider interface and return fixed date on each call.


Injecting via provider

Sometimes your objects should be additionally prepared before using, for example you have to call initialize method. It also could be done in described above way or you could use ProvidedBy annotation and explicit define Provider for your class. First, let's define class which should be initialized before using:
@ProvidedBy(ReportSessionFactory.class)
public class ReportSession {
    private boolean initialized;

    public ReportSession() {}

    public void init() {
        this.initialized = true;
    }

    public boolean isInitialized() {
        return initialized;
    }
    public boolean report(final String reportMessage, final Date date) {
        if(!initialized){
            return false;
        }
        // ...
        return true;
    }
}
ProvidesBy points to class which implements Provider interface:
public class ReportSessionFactory implements Provider<ReportSession> {
    @Override
    public ReportSession get() {
        ReportSession reportSession = new ReportSession();
        reportSession.init();
        return reportSession;
    }
}
Now when we will inject object of class ReportSession it will be given to us from provider and already initialized:
public class ReportSessionProviderTest {
    @Test
    public void shouldInitReportSession() {
        // given
        Injector injector = Guice.createInjector();
        ReportSession sut = injector.getInstance(ReportSession.class);
        // when
        boolean result = sut.isInitialized();
        // then
        assertTrue(result);
    }
}

Conclusion

When you need to inject a generator of runtime dependent objects or have to call method of dependency immediately after constructor, Guice providers are the best options for you. Sources are available here.

2014-03-23

Guice Tutorial - 02 - Injection points

Introduction

There are three points, where you can inject your dependecies. In previous part of this tutorial I have use injection to costructor. Available are also injections to setters or directly to fields. Today our domain will be order processing.

Main

First some classes, which will be our dependecies:
public class Order {
    private final String item;
    private final int amount;

    public Order(final String item, final int amount) {
        this.item = item;
        this.amount = amount;
    }

    public String getItem() {
        return item;
    }

    public int getAmount() {
        return amount;
    }
}

public class OrderProcessor {
    public void process(final Order order) {
        // ...
    }
}

public class OrderDao {
    public void save(final Order order) {
        // ...
    }
}

class OrderValidator {
    public void validate(final Order order) {
        // ...
    }
}

Controller which has all these dependecies is here:
public class OrderController {
    private final OrderDao orderDao;

    private OrderProcessor orderProcessor;

    @Inject
    private OrderValidator orderValidator;

    @Inject
    public OrderController(final OrderDao orderDao) {
        this.orderDao = orderDao;
    }

    @Inject
    public void setOrderProcessor(final OrderProcessor orderProcessor) {
        this.orderProcessor = orderProcessor;
    }

    public void invokeProcessing(final Order order) {
        orderValidator.validate(order);
        orderDao.save(order);
        orderProcessor.process(order);
    }
}

As you can see, the Inject annotation is set on constructor of whole class, setter of OrderDao and on OrderValidator field. Injecting to constructor is the best option in my opinion, because all needed dependecies should be inject, when class is created.
Setter injection sometimes is helpful, for example when you need to inject something later using injectMember (it will be cover in one of next parts).
Field injecting is often a bad idea, because during testing this field should be protected or default (or public, but this is the worst idea) to mock this dependency. Of course you can use refletion, but reflection API is not easy to use. But you have this opportunity to inject field.

Testing

One simple test to prove that all this injection points works and there are not NullPointerExceptions.
public class OrderControllerIT {
    @Test
    public void shouldInjectAllDependency() {
        //given
        Injector injector = Guice.createInjector();
        Order order = new Order("apple", 10);
        //when
        OrderController sut = injector.getInstance(OrderController.class);
        //then
        sut.invokeProcessing(order);
    }
}


Conclusion

You could inject dependecies in three placess in classes, but you almost always should use constructor injector. Injecting to setters should be hardly ever used. Field injecting is available, but should not be used.
All sources are available here.

2014-03-16

Guice Tutorial - 01 - The simplest injection

Introduction

Guice is very powerful and simple dependency injection library from Google. There is no need to create xml configuration or have container to use it. Moreover, it gives us objects already casted to desired types. In this post I will show how to start working with guice and make the simplest injection. In this case, domain will be adding persons. All sources are available here.


Main

First, we have to add maven dependency to guice and optionally to javax.inject:
<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>3.0</version>
</dependency>
<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>
Guice has own annotations to describe injections, but I like to use javax.inject annotation, which could also be used with Guice and are part of JavaEE.


Person is described by given class:
public class Person {
    private String firstName;
    private String lastName;
    private Integer age;

    public Person(final String firstName, final String lastName, 
                  final Integer age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    //...
}
We also need PersonDao and PersonValidator:
public class PersonDao {
    public void persist(final Person user) {
        // ...
    }
}
public class PersonValidator {
    void validate(final Person user) throws PersonValidationException {
        // ...
    }
}
Now we have all dependencies so let's create controller, which will use this classes:
public class PersonController {
    private final PersonValidator userValidator;
    private final PersonDao userDao;

    @Inject
    public PersonController(final PersonValidator userValidator, 
                            final PersonDao userDao){
        this.userValidator = userValidator;
        this.userDao = userDao;
    }

    public void add(final Person user) throws PersonValidationException{
        userValidator.validate(user);
        userDao.persist(user);
    }
}
The magic is in annotation Inject. In Guice, when we want to use class with not default, no argument constructor, we have to add this annotation to one of constructor.


Testing

It is time to test it. I will use JUnit.
@Test
public void shouldGetPersonControllerFromInjectorAndPersistPerson() {
    //given
    Injector injector = Guice.createInjector();
    Person user = new Person("John", "Smith", 25);
    //when
    PersonController userController = injector.getInstance(PersonController.class);
    //then
    userController.add(user);
}
All classes could be obtained from Guice via Injector. Injector collects all classes in classpath and allows to get their instances if they have default constructors or constructors annotated with Inject (from Guice or javax).
Method add of userController pass without exception so Guice has injected PersonDao and Person Validator classes. 


Conclusion

Guice is very simple and in basic cases we need only to use Inject annotation on class with dependecies. We only have to call getInstance and tell Guice which class (or interface) we want.

2014-02-09

JUnit lifecycle

Introduction

JUnit is basic and first tool which is used for testing in Java. JUnit uses annotations to describe lifecycle, but sometimes order of operations executed by this library is not obvious. For example: when constructor of test class is called or when static initalization block is executed?

Main

This JUnit test class will be used to show when methods and blocks are executed.
package com.blogspot.przybyszd.junitlifecycle;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JunitLifecycleTest{
    private static final Logger LOG = LoggerFactory.getLogger(JunitLifecycleTest.class);
    
    static{
        LOG.info("In static initialization block");
    }
    
    public JunitLifecycleTest(){
        LOG.info("In constructor");
    }
    
    {
        LOG.info("In initialization block");
    }
    
    @Test
    public void test1(){
        LOG.info("In test 1");
    }
    
    @Test
    public void test2(){
        LOG.info("In test 2");
    }
    
    @BeforeClass
    public static void oneTimeSetUp(){
        LOG.info("In before class");
    }
    
    @Before
    public void prepareTest(){
        LOG.info("In before");
    }
    
    @After
    public void tearDown(){
        LOG.info("In after");
    }
    
    @AfterClass
    public static void oneTimeTearDown(){
        LOG.info("In after class");
    }
}

And this is output after executing tests from this class.
2014-02-09 17:36:52,931 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:19 - In static initialization block
2014-02-09 17:36:52,935 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:42 - In before class
2014-02-09 17:36:52,936 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:27 - In initialization block
2014-02-09 17:36:52,937 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:23 - In constructor
2014-02-09 17:36:52,938 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:47 - In before
2014-02-09 17:36:52,938 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:32 - In test 1
2014-02-09 17:36:52,938 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:52 - In after
2014-02-09 17:36:52,940 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:27 - In initialization block
2014-02-09 17:36:52,941 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:23 - In constructor
2014-02-09 17:36:52,941 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:47 - In before
2014-02-09 17:36:52,941 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:37 - In test 2
2014-02-09 17:36:52,941 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:52 - In after
2014-02-09 17:36:52,942 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:57 - In after class

As we can see, static initialization block is executed before metchod annotated with BeforeClass. You can initialize here heavy objects, like Hibernate SessionFactory.

Before each test not only method annotated with Before is called. Earlier initialization block and constructor is called. There you can create resources, which should be not shared between tests (for example to get Hibernate Session from SessionFactory).

At the end of each test method annotated with After is called (for example to close Hibernate Session) and at the end of whole class, method annotated with AfterClass could free your resources (for example Hibernate SessionFactory).

Conclusion

It is why JUnit is great for unit testing. State for each test could be created in initial block, constructor of before method and it does not share it between test methods, because for each test new class is created. Of course, You can always store something in static variables, for example heavy objects which You want to create only once.

2014-01-13

Properties from maven

Introduction

Sometimes your code should work in many environments using varaibles defined in many places. There could be default variable in code (when configuration is not defined), variable in configuration file or pom.xml for tests and maybe each developer should have own variable value...

Property reader code

All examples will be tests and will be use PropertyReader class which is defined below.
package com.blogspot.przybyszd.sandbox.propertyplaceholders;

import java.util.Properties;

public class PropertyReader{
    
    public static Properties readProperties(final String configurationFile){
        Properties properties = new Properties();
        try{
            properties.load(PropertyReader.class.getResourceAsStream(configurationFile));
        }catch(Exception e){
            System.err.println("Configuration file was not found");
        }
        return properties;
    }   
}
All properties files will be defined in src/test/resources.

Default properties in code

First, assume that properties file is not provided or property is not given:
package com.blogspot.przybyszd.sandbox.propertyplaceholders;

import static org.junit.Assert.assertEquals;
import java.util.Properties;
import org.junit.Test;

public class PropertyReaderTest{
    
    @Test
    public void shouldUseDefaultPropertyFromCode(){
        // given
        Properties properties = PropertyReader.readProperties("/no-existing-file.properties");
        // when
        String value = properties.getProperty("address", "localhost");
        // then
        assertEquals("localhost", value);
    }
}
But when property file exists and has this property then it will be used:
@Test
public void shouldUsePropertyFromFile(){
    // given
    Properties properties = PropertyReader.readProperties("/existing-file.properties");
    // when
    String value = properties.getProperty("address", "localhost");
    // then
    assertEquals("10.10.10.10", value);
}
Property in file existing-file.properties:
address=10.10.10.10

Default properties in pom.xml

Properties could be also defined in pom.xml and then placeholders could be used in property file. Test is going first:
@Test
public void shouldUsePropertyFromPom(){
    // given
    Properties properties = PropertyReader.readProperties("/file-with-placeholder.properties");
    // when
    String value = properties.getProperty("address", "localhost");
    // then
    assertEquals("trololo.com", value);
}
Instead of value in properties file there is only placeholder (file file-with-placeholder.properties):
address=${address}

Value of property is defined in pom.xml (filtering of test resources must be set to true and, optionally, resource filtering could be set to true):
<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>
 <groupId>property-placeholders</groupId>
 <artifactId>property-placeholders</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>PropertyPlaceholder</name>

 <properties>
  <address>google.com</address>
 </properties>

 <build>
  <resources>
   <resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
   </resource>
  </resources>
  <testResources>
   <testResource>
    <directory>src/test/resources</directory>
    <filtering>true</filtering>
   </testResource>
  </testResources>
 </build>

 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.11</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
</project>
Now variable could be also set from command line:
mvn -Daddress=my-address clean test

Default property in settings.xml

Each developer (or each environment) could define some properties in settings.xml in $HOME/.m2 directory and these properties overwrite properties defined in pom.xml.
Test first:
@Test
public void shouldUsePropertyFromSettingsXMl(){
    // given
    Properties properties = PropertyReader.readProperties("/file-with-placeholder.properties");
    // when
    String value = properties.getProperty("address2", "localhost");
    // then
    assertEquals("yahoo.com", value);
}
I add new property address2 so I have to add property placeholder in properties file and in pom.xml.
Properties file:
address=${address}
address2=${address2}
pom.xml:
<properties>
 <address>google.com</address>
 <address2>bing.com</address2>
</properties>
And now variable address2 will be redefined in settings.xml file :
<settings>
  <profiles>
    <profile>
      <id>property-placeholder</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <address2>yahoo.com</address2>
      </properties>
    </profile>
  </profiles>
</settings>
This profile is active by default so there is not need to use -P parameter.
Not the tests pass.

Conclusion

Use Maven and define properties anywhere.

2014-01-11

Try catch with resources

Introduction

Today I would like to describe a try catch with resource, which is available in Java 7. Additional I show template for Eclipse, which generate such try-resource for reading file.


Try catch in Java 6

In Java 6 (or earlier) you have to write try catch like this:
BufferedReader bin = null;
try{
    bin = new BufferedReader(new FileReader("trolo.txt"));
    String line = null;
    while((line = bin.readLine()) != null){
        // parse line
    }
}catch(IOException e){
    LOG.error("IO exception when creating reader or reading", e);
    throw new MyException(e);
}finally{
    try{
        if(bin != null){
            bin.close();
        }
    }catch(IOException e){
        LOG.error("IO exception when closing", e);
        throw new MyException(e);
    }
}

It is not quite nice... You have to declare BufferedReader before try block and close it in finally (of course if it is not null). Additionally close method could throw IOException which should be handle...

Try catch with resource in Java 7

Java 7 came to us with resources for try. Each resource have to implement interface AutoClosable. It has only one method: close, which is called at the end of try catch with resource. Ant this is an example of use:
try (BufferedReader bin = new BufferedReader(new FileReader("trolo"))){
    String line = null;
    while((line = bin.readLine()) != null){
        // parse line
    }
}catch(IOException e){
    LOG.error("IO exception", e);
    throw new MyException(e);
}
Shorter? Creating, reading or closing BufferedReader could throw exception so we still need catching of IOException, but only once. Finally block is ommited.

Eclipse template

In Eclipse you could define a template, which insert try catch with resource and you job is only name the variables and give file name. I was inspired by this post, to write this template.
${:import(java.io.BufferedReader, java.io.FileReader, java.io.Exception)}
try(BufferedReader ${buffName} = new BufferedReader(new FileReader(${fileName}))){
 String ${line} = null;
 while((${line} = ${buffName}.readLine()) != null) {
        ${cursor}
 }
}catch(IOException e){
    // TODO Auto-generated stub
    throw new UnsupportedOperationException("Not implemented yet");
}

Conclusion

Java 7 came with big improvement for try catch. Now is is shorter to use in try any resource which have to be closed at the end.

2014-01-04

Eclipse configuration for Java

Introduction

Eclipse is an great IDE, but only with some plugins (or only one) and changes in default settings. I show you how to prepare the best in my opinion environment to developing in Java with TDD style.

Settings

First open Window menu and select preferences. There you have some interesting settings.

Java -> Appearance -> Type filters

Add here class java.lang.Object to not see methods of Object class: equals, wait, notify etc. Add also package java.awt. Always annoys me when i have to import java.util.List but first class List is derived from java.awt.

Java -> Code style

Exception variable name is set to e and option 'Add @Override annotation for new overriding methods' is set.

Java -> Code style -> Clean Up

Eclipse could perform some tasks when you clean up your code from source menu. Create new profile and set:
  1. In first tab (Code Organizing): 
    • Format source code
    • Organize imports
  2. In Code Style tab:
    • Use blocks in if/while/for/do statements -> Always (because when you add code to your if body you could forget to put it into block)
    • Convert 'for' loops to enhanced
    • Use modifier 'final' where possible (select only parameters, because when you assign variable to parameter it is code smell and this protects you from doing bad things) 
  3. In Member Accesses tab:
    • Use declaring class as qualifier (select only access through instance and subtypes)
  4. In Missing Code tab:
    • Add missing annotations: @Override, @Override when implementation of method from interface and @Deprecated
    • Add serial version ID (generated)
    • Add unimplemented method (body will be taken from code template)
  5. In Unnecessary Code tab:
    • Remove unused imports
    • Remove unnecessary casts
    • Remove unnecessary '$NON-NLS$' tags

Java -> Code style -> Code templates

Method, constructor and catchblock body will be change to throw exception when is generated. When you forget to implement method or block you obtain UnsupportedOperationException.
Set method and catch block body to:
// ${todo} Auto-generated catch block
throw new UnsupportedOperationException("Not implemented yet");
Set constructor body to:
${body_statement}
// ${todo} Auto-generated constructor stub
throw new UnsupportedOperationException("Not implemented yet");

Java -> Code style -> Formatter

This options helps me read code and I just like this form of code. The same defined formatter rules should be used by all team members, so you could export configuration and give to your team mates.
  1. In tab Indentation:
    • Declarations within class body
    • Declarations within enum body
    • Declarations within class constants
    • Declarations within annotation body
    • Statements within method/constructor body
    • Statements within blocks
    • Statements within 'switch' body
    • Statements within 'case' body
    • 'break' statements
    • Empty lines
  2. In tab Braces:
    • All options set to 'Same line'
  3. In tab White Space:
    • Declarations:
      • Classes: after comma in implemented clause
      • Fields: after comma in multiple field declarations
      • Constructors: after comma in parameters and after comma in 'throws' clause
      • Methods: after comma in parameters, before ellipsis in vararg parameters, after ellipsis in vararg parameters and after comma in 'throws' clause
      • Labels: after colon
      • Annotations: after comma
      • Enum types: after comma between constants and after comma in constant arguments
    • Control statements:
      • 'for': after comma in initialization, after comma in increments, after semicolon, befor colon and after colon
      • 'try-with-resources': before opening parenthesis and after semicolon
      • 'assert': before colon and after colon
      • 'return': before parenthesized expressions
      • 'throw': before parenthesized expressions
    • Expressions:
      • Function invocations: after comma in methods arguments, after comma in object allocation arguments and after comma in in explicit constructor call
      • Assignments: before assignment operation and after assignment operation
      • Operators before binary operations and after binary operations
      • Type casts: after closing parenthesis
      • Conditionals: before question mark, after question mark, before colon and after colon
    • Arrays:
      • Arrays initializers: after comma
    • Parameterized types:
      • Type reference: after comma
      • Type arguments: after comma
      • Type parameters: after comma in parameters, before '&' in type bounds and after '&' in type bounds
  4. In tab Blank Lines:
    • 0 blank lines before package declaration, before first declaration, before field declarations and at begining of method body
    • 1 otherwise
  5. In tab New Lines:
    • after labels
    • at end of files
    • put empty statements on new line
    • insert new line after annotations on package
    • insert new line after annotations on types
    • insert new line after annotations on fields
    • insert new line after annotations on methods
    • insert new line after annotations on local variables
  6. In tab Control Statements:
    • Keep 'else if' on one line
  7. In tab Line Wrapping:
    • Prefer wrapping outer expressions (keep nestedexpression in one line)
    • Annotations: wrap all elements, every element on a new line
    • Class declarations: Do not wrap
    • Constructor declarations: Do not wrap
    • Method declarations: Do not wrap
    • 'enum' declarations: wrap all elements, every element on a new line
    • Function calls: Do not wrap
    • Expressions: Do not wrap
    • Statements:
      • Compact 'if else' and 'multi-catch': Do not wrap
      • 'try-with-resource': Wrap all elements, except first element if not necessary (additionally set indentation policy to Indent on column)
  8. In tab Comments:
    • Enable Javadoc comment formatting
    • Enable block comment formatting
    • Enable line comment formatting
    • Format line comments on first column
    • Enable header comment formatting
    • Never join lines
    • Format HTML tags
    • Format Java code snippets inside 'pre' tags
    • Indent Javadoc tags
    • /** and */ after separate lines
    • Remove blank lines
    • /* and */ after separate lines
    • Remove blank lines
    • Maximumline width for comments: 200
  9. Off/On Tags (Disable formatting between some comments):
    • Enable Off/On tags
    • Off tag: DO NOT INDENT
    • On tag: NOW INDENT

Java -> Code style -> Organize Imports

Set only number of import and static import needed for * to 100. I do not like imports with * when I am using IDE.

Java -> Compiller -> Building

There are problems which could occur with whole project.
  1. General
    • Enable use of exclusion patterns in source folders 
    • Enable use of multiple output locationsfor source folders
  2. Build path problems 
    • warnings on Incompatible required libraries and No strictly compatible JRE for execution environment available
    • errors otherwise
  3. Output folder
    • warning when duplicated resource
    • I scrub output folders when cleaning projects

Java -> Compiller -> Error/Warnings

There are problems which could occurs in code.
  1. Code style
    • warning on:
      • Non-static access to static member
      • Access to non-accessiblemember of enclosing type
      • Parameter assignment
      • Method with a constructor name
    • ignore otherwise
  2. Potential programming problems
    • error on:
      • Possible accidentalboolean assignment
      • Dead code
    • warning on:
      • Comparing identical values
      • Assignment has no effect
      • Using a char arrayin string concatenation
      • Inexact type match for varargs arguments
      • Empty statement
      • Unused object allocation
      • Incomplete 'switch' case on enum
      • Hidden catch block
      • 'finally' does not complete normally
      • Resource leak
      • Seralizable class without serialVersionID
      • Missing synchronization modifier on inherited method
      • Class overides 'equals()' but not 'hashCode()'
    • ignore otherwise
  3. Name shadowing and conflicts
    • warning on:
      • Type parameter hides another type
      • Method does not override package visible method
      • Interface method conflicts with protected 'Object' method
    • ignore otherwise
  4. Deprecated and restricted API
    • error on forbidden reference
    • warning on:
      • Deprecated API (both options checked)
      • Discourage reference
  5. Unnecessary code: all options set to warnings and selected 'Ignore in overriding and implementing methods' boxes
  6. Generic types: all options set to warnings and selected 'Ignore unavoidable generic type problems'
  7. Annotations: all options set to warnings and selected 'Include implementations of interface methods' and 'Enable @SuppressWarnings annotations' boxes
  8. Null analysis
    • warning on null pointer access
    • ignore otherwise

Java -> Compiller -> Javadoc

There are problems which could occurs in javadoc comments.
Select 'Process Javadoc comments'. Set warning on malformed Javadoc comments, but only on public members and then validate tag arguments, report non visible references, deprecated references and validate all standard tags missing description.
When tag is missing then warning should apear but only on public members, ignoring overriding and implementing methods and method type parameters.
Ignore missing Javadoc comments. Why? Because you do not need javadoc, but when you do then you should have valid comments.

Java -> Editor -> Content Assist

This options are used when CTRL+Space are pressed. I have set:
  1. Insertion
    • Completion inserts
    • Insert single proposals automatically
    • Add import instead of qualified name
    • Use static imports
    • Fill method arguments and show guessed arguments
    • Insert best guessed arguments (It really could quess what you think)
  2. Sorting and filtering
    • Sort proposals by revelance
    • Show camel case matches
    • Hide proposals not visible in the invocation context
  3. AutoActivation should be enable and activate after 200 ms or on . (dot) sign.

Java -> Editor -> Content Assist -> Advanced

Choose only these proposals which you will be use. I suggest to add templete and word proposals and set them at the beggining of content assist cycle.

Java -> Editor -> Content Assist -> Favourites

There you can set static methods, static fields or classes for quick proposals. It is extremely useful for tests. I have here:
  1. Static members from:
    • com.googlecode.catchexception.CatchException
    • org.fest.assertions.Assertions
    • org.hamcrest.CoreMatchers
    • org.hamcrest.Matchers
    • org.junit.Assert
    • org.junit.Assume
    • org.junit.matchers.JUnitMatchers
    • org.mockito.Matchers
    • org.mockito.Mockito
  2. Classes from package:
    • org.junit

Java -> Editor -> Save Actions

I have set all options like in clean up.

Java -> Editor -> Templates

I use many templates written on my own. There are some or them:
  1. after: method which have to be invoke after each JUnit test:
    ${:import (org.junit.After)}
    @After
    public void tearDown() {
        ${cursor}
    }
  2. before: method which have to be invoke before each JUnit test:
    ${:import(org.junit.Before)} 
    @Before
    public void prepareTest() {
     sut = new ${cursor} 
    }
  3. indent-off: when I do not want to have formatted code, for example when using long invocations in fluent API:
    // DO NOT INDENT
    
    //NOW INDENT
  4. logger: add log4j logger static member:
    private static final Logger LOG = LoggerFactory.getLogger(${enclosing_type}.class); ${imp:import(org.slf4j.Logger)} ${i:import(org.slf4j.LoggerFactory)}
  5. test: add JUnit test template:
    @${testType:newType(org.junit.Test)}
    public void should${cursor}() {
     //given
     
     //when
     
     //then
     fail(); ${staticImport:importStatic('org.junit.Assert.*','org.mockito.Mockito.*')} 
    }

Java -> Editor -> Typing

    Select all options. Everything is perfect.

    Plugins

    In fact, you need only one powerful plugin named MoreUnit. Additionally, when you start programming in TDD you could find useful plugin Pulse.

    MoreUnit

    Great plugin, which enable jumping between class implementation and tests using shortcuts:
    • CTRL+R - run tests for classes
    • CTRL+J - jump to test/implementation or create test class if not exist
    MoreUnit requires a few settings to work perfectly. Open Window menu, select Preferences and MoreUnit. In Java subpreferences set test source folder as src/test/java (when you use Maven). 
    I have unit and integration tests and I recognize them by suffix of test class name: unit test class ends with word Test and integration tests ends with IT, so as rule for MoreUnit I have set pattern '${srcFile}(Test|IT)' (the same pattern should be set in User Language subpreferences of MoreUnit).  Additionally, all test methods have content 'throw new RuntimeException("not yet implemented");' and I have enabledextended search for test methods, so that I can jump also between method implementation and tests using this method.

    Pulse

    It is simple plugin, which you have to start in pulse view and you could observe your 'TDD pulse' i.e. red (write failing test) -> green (make test pass by implementing class) -> refactor (implementation of class and test class) -> red -> ... as if it was hearbeats.

    Conclusion

    Eclipse is very powerful IDE. But when you download it, it requires some additional settings and, as you can see, one or two plugins to work perfectly and highly support programmer work.