2018-03-13

Testing Kotlin with Spock Part 1 - Object

The object keyword in Kotlin creates singleton in a very convenient way. It can be used for example as a state of an operation. Spock Framework is one of the most expressive and readable test framework available in the Java ecosystem. Let's see how Kotlin object can be used in the Spock tests.

What do we want to test?

We have a single method validate in Validator interface which returns validation status: Ok or Error.

sealed class ValidationStatus
object Ok : ValidationStatus()
object Error : ValidationStatus()

interface Validator<T> {
    fun validate(value: T): ValidationStatus
}

We also provide a simple implementation of this interface:

class AdultValidator : Validator<Int> {
    override fun validate(value: Int) = if (value >= 18) Ok else Error
}

How to test it with Spock?

First - silly approach

First, let's write a parameterized test for the validator:

AdultValidator sut = new AdultValidator()

def 'should validate age #age'() {
    expect:
        sut.validate(age) == result
    where:
        age | result
        0   | Error
        17  | Error
        18  | Ok
        19  | Ok
}

We expect it to pass, but it fails... Error and Ok are classes in the code above.

Second - naive approach

We need instances instead, so we modify the test a little:

def 'should validate age #age'() {
    expect:
        sut.validate(age) == result
    where:
        age | result
        0   | new Error()
        17  | new Error()
        18  | new Ok()
        19  | new Ok()
}

And again, this one fails as well. Why? It is because Error and Ok classes do not have overridden equals method. But why? We expects Kotlin objects (those created with object keyword, not plain object) to have it implemented correctly. What is more, it works correctly in Kotlin:

fun isOk(status:ValidationStatus) = status == Ok

Third - correct approach

Let's look into the class file:

$ javap com/github/alien11689/testingkotlinwithspock/Ok.class
Compiled from "Validator.kt"
public final class com.github.alien11689.testingkotlinwithspock.Ok extends com.github.alien11689.testingkotlinwithspock.ValidationStatus {
  public static final com.github.alien11689.testingkotlinwithspock.Ok INSTANCE;
  static {};
}

If we want to access the real object that Kotlin uses in such comparisson, then we should access the class static property called INSTANCE:

def 'should validate age #age'() {
    expect:
        sut.validate(age) == result
    where:
        age | result
        0   | Error.INSTANCE
        17  | Error.INSTANCE
        18  | Ok.INSTANCE
        19  | Ok.INSTANCE
}

Now the test passes.

Fourth - alternative approach

We can also check the method result without specific instance of the object class and use instanceof or Class#isAssignableFrom instead.

def 'should validate age #age'() {
    when:
        ValidationStatus result = sut.validate(age)
    then:
        result.class.isAssignableFrom(expected)
    where:
        age | expected
        0   | Error
        17  | Error
        18  | Ok
        19  | Ok
}

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.

2017-11-14

Karaf configuration as Groovy file

Introduction

By deafault, Apache Karaf keeps configuration for bundles in the etc directory as flat properties files. We can override configuration for the storing mechanism by providing own implementation of the org.apache.felix.cm.PersistenceManager interface and use much more readable format for bundle properties, e. g. groovy config.

Turning off built-in Karaf persistence

As we can read in Karaf documentation:
Apache Karaf persists configuration using own persistence manager in case of when available persistence managers do not support that.
We will use our custom implementation of persistence, so Karaf persistence is not needed. We can turn it off by setting variable storage to an empty value:
$ cat etc/org.apache.karaf.config.cfg
storage=
This option is available since version 4.1.3 when this issue was resolved.

Registering custom Persistence Manager

First we have to create and register an OSGi service implementing org.apache.felix.cm.PersistenceManager. If we build and install the bundle with such service while Karaf is running (e.g. by putting jar in the deploy directory), then we should have at least two PersistenceManager services registered:
karaf@root()> ls org.apache.felix.cm.PersistenceManager
[org.apache.felix.cm.PersistenceManager]
----------------------------------------
 service.bundleid = 7
 service.description = Platform Filesystem Persistence Manager
 service.id = 14
 service.pid = org.apache.felix.cm.file.FilePersistenceManager
 service.ranking = -2147483648
 service.scope = singleton
 service.vendor = Apache Software Foundation
Provided by :
 Apache Felix Configuration Admin Service (7)
Used by:
 Apache Felix Configuration Admin Service (7)

[org.apache.felix.cm.PersistenceManager]
----------------------------------------
 osgi.service.blueprint.compname = groovyConfigPersistenceManager
 service.bundleid = 56
 service.id = 117
 service.pid = com.github.alien11689.osgi.util.groovyconfig.impl.GroovyConfigPersistenceManager
 service.ranking = 100
 service.scope = bundle
Provided by :
 groovy-config (56)
Used by:
 Apache Felix Configuration Admin Service (7)
Loaded configurations will be cached by configuration admin. We can use org.apache.felix.cm.NotCachablePersistenceManager interface if we want to implement custom caching strategy.

Creating a new properties file

Let's create a new properties file in groovy, e.g:
$ cat etc/com.github.alien11689.test1.groovy
a = '7'
b {
    c {
        d = 1
        e = 2
    }
    z = 9
}
x.y.z='test'
If we search for properties with pid com.github.alien11689.test1, Karaf will find these.
karaf@root()> config:list '(service.pid=com.github.alien11689.test1)'
----------------------------------------------------------------
Pid:            com.github.alien11689.test1
BundleLocation: null
Properties:
   a = 7
   b.c.d = 1
   b.c.e = 2
   b.z = 9
   service.pid = com.github.alien11689.test1
   x.y.z = test
If we make any change to the file they won't be mapped to properties, because there are no file watchers defined for it.
We could manage such properties using Karaf commands instead.

Managing configuration via Karaf commands

We can define a new pid using Karaf commands:
karaf@root()> config:property-set -p com.github.alien11689.test2 f.a 6
karaf@root()> config:property-set -p com.github.alien11689.test2 f.b 'test'
Since our PersistenceManager has higher service.ranking (100 > -2147483648), new pid will be stored as a groovy file:
$ cat etc/com.github.alien11689.test2.groovy
f {
    b='test'
    a='6'
}
We can also change/remove properties or remove the whole configuration pid using karaf commands and it will all be mapped to groovy configuration files.

Sources

Sources are available on github.

2017-08-24

Using Kotlin extensions in Groovy

Extensions in Kotlin and Groovy

Kotlin and Groovy have mechanisms for extending existing classes without using inheritance or decorators. In both languages, the mechanisms are called extension methods. Their source code looks different, but generated bytecode is quite similar. Thanks to that, Groovy is able to use Kotlin extensions just like its own.

Why would I want to use such extensions in Groovy? The main reason is that I want to test my extensions using the best testing framework available for the JVM - Spock Framework.

Code is available here.

Extensions in Kotlin

There are many types of extensions in Kotlin. I decided to focus only on extension functions and properties.

As an example, I extend the java.lang.String class. First, I create an extension function skipFirst, which skips first N characters:


Next, I create an extension property answer, which is the Answer to the Ultimate Question of Life, the Universe, and Everything:


Both extensions are declared in package com.github.alien11689.extensions, in file called StringExtensions. However, the generated class in target directory is named StringExtensionsKt and this is the name that must be used when accessing from other languages. Specific class name can be forced by annotation @file:JvmName.

Using Kotlin extensions in Groovy

There are two ways for using extensions in Groovy that are supported by good IDEs. First, you can declare scope where the extensions are available by use method:


It is acceptable, but is not very convenient. The second and much better way is to use an extension module definition. The extension module is defined in file org.codehaus.groovy.runtime.ExtensionModule in directory src/main/resources/META-INF/services/. The same directory is monitored by ServiceLoader, but the file format is completely different:


The tests look much better now:

2017-02-18

OSGi Blueprint visualization

What is blueprint?

Blueprint is a dependency injection framework for OSGi bundles. It could be written by hand or generated using Blueprint Maven Plugin. Blueprint file is only an XML describing beans, services and references. Each OSGi bundle could have one or more blueprint files.

Blueprint files represent architecture of our bundle. Let's visualize it using groovy script and graphviz available in my github repository and analyze.

Example generation

Pre: All you need is groovy and graphviz installed on your OS

I am working mostly with bundles with generated blueprint, so I will use blueprint file generated from Blueprint Maven Plugin tests as example. All examples are included in github repository.

Generation could be invoked by running run.sh script with given destination file prefix (png extension will be added to it) and path to blueprint file:

mkdir -p target

./run.sh target/fullBlueprint fullBlueprint.xml

Visualization is available here.

Separating domains

First if you look at the image, you see that some beans are grouped. You could easily extract such domains with tree roots: beanWithConfigurationProperties and beanWithCallbackMethods to separate blueprint files and bundles in future and generate images from them:

./run.sh target/beanWithCallbackMethods example/firstCut/beanWithCallbackMethods.xml
./run.sh target/beanWithConfigurationProperties example/firstCut/beanWithConfigurationProperties.xml
./run.sh target/otherStuff example/firstCut/otherStuff.xml

Now we have three, a bit cleaner, images: beanWithConfigurationProperties.png, beanWithCallbackMethods.png and otherStuff.png.

We also could generate image from more than one blueprint:

./run.sh target/joinFirstCut example/firstCut/otherStuff.xml example/firstCut/beanWithConfigurationProperties.xml example/firstCut/beanWithCallbackMethods.xml

And the result is here. The image contains beans grouped by file, but if you do not like it, you could force generation without such separation using option --no-group-by-file:

./run.sh target/joinFirstCutGrouped example/firstCut/otherStuff.xml example/firstCut/beanWithConfigurationProperties.xml example/firstCut/beanWithCallbackMethods.xml --no-group-by-file

It will generate image with all beans from all files.

Exclusion

Sometimes it is difficult to spot and extract other domains. It will be easier to do some experiments on blueprint. For example, bean my1 is a dependency for too many other beans. You could consider converting my1 bean to OSGi service and extracting it to another bundle.

Let's exclude my1 bean from generation via -e option and see what happens:

./run.sh target/otherStuffWithoutMy example/firstCut/otherStuff.xml -e my1

Result is available here. Now we see, that tree with root bean myFactoryBeanAsService could be separated and my1 could be inject to it as osgi service in another bundle.

You could exclude more than one bean adding -e switch for each of them, e. g. -e my1 -e m2 -e myBean123.

Conclusion

Blueprint is great for dependency injection for OSGi bundles, but it is easy to create quite big context containing many domains. It is much easier to recognize or search for such domains using blueprint visualizer script.


YOUR CODE HRER

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-31

Easy Hoogle usage from bash

What is Hoogle?

Hoogle is Google for searching of Haskell functions. You could ask it for function name or its signature.

There is available command hoogle, which could be installed using stack:

$ stack install hoogle

Using hoogle from command line

To hoogle a function you could just pass it as parameter:

$ hoogle fmap
Prelude fmap :: Functor f => (a -> b) -> f a -> f b
Data.Functor fmap :: Functor f => (a -> b) -> f a -> f b
Control.Monad fmap :: Functor f => (a -> b) -> f a -> f b
Control.Monad.Instances fmap :: Functor f => (a -> b) -> f a -> f b
Data.Traversable fmapDefault :: Traversable t => (a -> b) -> t a -> t b
Network.Stream fmapE :: (a -> Result b) -> IO (Result a) -> IO (Result b)

or pass its signature:

$ hoogle "(a -> b -> c) -> [a] -> [b] -> [c]"
Prelude zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Data.List zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Control.Applicative liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
Control.Monad liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
Prelude scanl :: (a -> b -> a) -> a -> [b] -> [a]
Data.List scanl :: (a -> b -> a) -> a -> [b] -> [a]
Prelude scanr :: (a -> b -> b) -> b -> [a] -> [b]
Data.List scanr :: (a -> b -> b) -> b -> [a] -> [b]
Data.List deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
Data.List intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
...

But it shows only list of the signatures of the functions. Sometimes we want to see more information about function. If you use option -i, then additional information will be shown:

$ hoogle -i "(a -> b -> c) -> [a] -> [b] -> [c]"
Prelude zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

zipWith generalises zip by zipping with the function given as the first argument, instead of a tupling function. For example, zipWith (+) is applied to two lists to produce the list of corresponding sums.

From package base
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

And again it is not enough, because it shows only documentation of first function from the list. We have to move a counter to see documentation of further functions, e. g. to show information about third item from the list:

$ hoogle -i -s 3 "(a -> b -> c) -> [a] -> [b] -> [c]"
Control.Applicative liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

Lift a binary function to actions.

From package base
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

Easier hoogle usage in bash

It is cumbersome to count each time you want to read info about further functions, so I have prepared bash function which makes it easier.

To search for function type:

$ hoog "(a->b) -> f a -> f b"
1) Data.Traversable fmapDefault :: Traversable t => (a -> b) -> t a -> t b
2) Prelude fmap :: Functor f => (a -> b) -> f a -> f b
3) Data.Functor fmap :: Functor f => (a -> b) -> f a -> f b
4) Control.Monad fmap :: Functor f => (a -> b) -> f a -> f b
5) Control.Monad.Instances fmap :: Functor f => (a -> b) -> f a -> f b
6) Data.Functor (<$>) :: Functor f => (a -> b) -> f a -> f b
7) Control.Applicative (<$>) :: Functor f => (a -> b) -> f a -> f b

Each function will have its counter at the beginning and just add its number at the end of command to show more information about specific function:

$ hoog "(a->b) -> f a -> f b" 6
Searching for: (a -> b) -> f a -> f b
Data.Functor (<$>) :: Functor f => (a -> b) -> f a -> f b

An infix synonym for fmap.

From package base
(<$>) :: Functor f => (a -> b) -> f a -> f b

How to install hoog command?

Command is available here. To use this command just add it to your ~/bashrc file.

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-08

Spring autowire with qualifiers

Introduction

Autowired is great annotation, which by default inject beans by type to annotated element (constructor, setter or field). But how to use it, when there is more than one bean of requested type.

Autowired with one bean

Suppose we will work with small interface:

interface IHeaderPrinter {
    String printHeader(String header)
}

When we have only one bean implementing IHeaderPrinter:

@Component
class HtmlHeaderPrinter implements IHeaderPrinter{
    @Override
    String printHeader(String header) {
        return "<h1>$header</h1>"
    }
}

then everything works great and test passes.

@Autowired
IHeaderPrinter headerPrinter

@Test
void shouldPrintHtmlHeader() {
    assert headerPrinter.printHeader('myTitle') == '<h1>myTitle</h1>'
}

Two implementations

But what will happen, if we add another implementation of IHeaderPrinter, e. g. MarkdownHeaderPrinter?

@Component
class MarkdownHeaderPrinter implements IHeaderPrinter {
    @Override
    String printHeader(String header) {
        return "# $header"
    }
}

Now out test with fail with exception:

Error creating bean with name 'com.blogspot.przybyszd.spring.autowire.SpringAutowireWithQualifiersApplicationTests': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.blogspot.przybyszd.spring.autowire.IHeaderPrinter com.blogspot.przybyszd.spring.autowire.SpringAutowireWithQualifiersApplicationTests.headerPrinter; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.blogspot.przybyszd.spring.autowire.IHeaderPrinter] is defined: expected single matching bean but found 2: markdownHeaderPrinter,htmlHeaderPrinter

We have to decide which implementation we want to use in our test, so ...

Two implementations with Qualifier

Each bean is registered with name equal its class. For example HtmlHeaderPrinter is named htmlHeaderPrinter. The name is also its qualifier. We have to tell Autowired, that it should inject htmlHeaderPrinter:

@Autowired
@Qualifier('htmlHeaderPrinter')
IHeaderPrinter headerPrinter

Now our test passes again.

Two implementations qualified by field name

If field is names like implementing class (for example htmlHeaderPrinter), then this class implementation will be injected:

@Autowired
IHeaderPrinter htmlHeaderPrinter

And test passes:

@Test
void shouldPrintHtmlHeader() {
    assert htmlHeaderPrinter.printHeader('myTitle') == '<h1>myTitle</h1>'
}

Thanks to @marcinjasion.

Two implementation with Primary

We often have one implementation which we almost always want to inject, so do we still have to put Qualifier with its name wherever we want to use it? No.

We could mark one implementation as Primary and this bean will be wired by default (unless we explicit give another Qualifier to use injection point):

@Component
@Primary
class HtmlHeaderPrinter implements IHeaderPrinter{
    // ...
}
@Autowired
IHeaderPrinter headerPrinter

Summary

Autowired annotation allows us to inject dependencies to beans. It works great without additional configuration, when each bean could be uniquely find by type. When we have more than one bean, that could be injected, we have to use Qualifier or Primary annotation to help it find desired implementation.

Source code is available here.