Friday, 26 July 2013

Lombok’s Sneaky Throws

I finally found a real life scenario where I want to use “Sneaky Throws” Lombok’s feature. According to the documentation:

@SneakyThrows

To boldly throw checked exceptions where no one has thrown them before!

Overview

@SneakyThrows can be used to sneakily throw checked exceptions without actually declaring this in your method’s throws clause. This somewhat contentious ability should be used carefully, of course. The code generated by lombok will not ignore, wrap, replace, or otherwise modify the thrown checked exception; it simply fakes out the compiler. On the JVM (class file) level, all exceptions, checked or not, can be thrown regardless of the throws clause of your methods, which is why this works.
More info about this feature. here: http://projectlombok.org/features/SneakyThrows.html
The scenario is the following:
We have a helper class that retrieves a field using reflection and in turn uses the Apache Commons’ PropertyUtils class. 
The latter throws 4 checked exceptions we don’t want to propagate to the final user. 
In other words, if some of these exceptions are thrown, we want everything to explode (especially, because we use this helper only for unit tests). So, the options were:
  1. Wrap everything around a big try{} catch (Exception) block and throw a RuntimeException such as IllegalArgumentException.
    • Con: Sonar would complain that we are catching the generic class “Exception”.
  2. Throw all exceptions.
    • Con: ugly. User will have to explicitly catch all these exceptions. Not really an option.
  3. Use Lombok’s “Sneaky Throws” feature. This would throw all of the above mentioned exceptions but without forcing users to explicitly catch them. This is the approach:
@SneakyThrows(value = { SecurityException.class, NoSuchFieldException.class, IllegalArgumentException.class, IllegalAccessException.class })
public static <T> void setPrivateStaticFinalField(Class<T> targetClass, T targetObject, String fieldName, Object newValue) {
    Field logField = ReflectionUtils.findField(targetClass, fieldName);
    logField.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(logField, logField.getModifiers() & ~Modifier.FINAL);
    ReflectionUtils.setField(logField, targetObject, newValue);
}

Thursday, 27 June 2013

Intercept an @annotation with Aspetcj in Spring

Intercepting a method call marked with an @Annotation using AspectJ and Spring it's easy enough and it's a good approach in terms of flexibility, scalability and design.

  • It's flexible because in the case you want to intercept a different method, you just have to move your annotation somewhere else.
  • It's scalable because if you want to intercept more than one method, you just need to add the annotation in other methods.
  • It results also in a good and clean code.


First thing you need to do is include the dependencies. In case of maven the following will do it.
<!-- Dependencies for AspectJ and Spring AOP -->
                <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aop</artifactId>
                        <version>${spring.version}</version>
                </dependency>
 
                <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>1.6.11</version>
                </dependency>
 
                <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjweaver</artifactId>
                        <version>1.6.11</version>
                </dependency>



Second, we need to create the annotation that we will use to mark the methods in the business logic.
package com.marco.aspect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CommitTransaction {
}
 

Now, we need to create an interceptor. In this case (@After) it will be triggered when the method intercepted is finished.
For the full list of pointcuts and advises see the following pointcuts and advise
package com.marco.aspect;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import com.marco.some.package.SomeClass;
import com.marco.some.package.SomeBean;
@Aspect
@Component
public class CommitTransactionInterceptor {

        private static final Logger LOGGER = Logger.getLogger(CommitTransactionInterceptor.class);

        @Inject
        private SomeBean someBean;

        @After("@annotation(com.marcot.CommitTransaction)")
        public void after() {

                LOGGER.debug("An invocation to " + SomeClass.class.getSimpleName() + " has been intercepted.");

                someBean.sendSomeEmail();

        }
}
 


Activate the aspectj and the interceptor in Spring adding the following in your application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

        <aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true" />

        <bean id="commitTransactionInterceptor" class="com.marco.aspect.CommitTransactionInterceptor"/>
</beans>


And of course, remember to load it in your spring configuration classes
@Configuration
@ImportResource({ "classpath:application-context.xml" })
public class YourSpringConfiguration {
....
}


All done, now you can mark all the methods you want to intercept with your annotation and you will see the magic happening.
package com.marco.business.logic;

public class SomeLogic {

        private static final Logger LOGGER = Logger.getLogger(SomeLogic.class);

        @CommitTransaction
        public void executeSomeLogic(Object someObject) {
             // a transaction finished
        }
}




Wednesday, 15 May 2013

When do you think a daily stand up is too crowded?

Recently, looking at the daily stand-ups in my company, it makes me smile a bit.



I think too many = chaos and dispersion. 
Proper and efficient stand-ups should be 4 pigs and occasionally 2 or 3 chickens. 

This is my opinion, what is yours?

Friday, 10 May 2013

Building smart Builders

When building an API, you should always think about who is going to use it.
When the API is simply and clear to use, then the users are happy. When the users are happy then everyone is happy too :).

But great usability is not always easy to achieve. 

There are patterns that help on this, on this post I will focus on the classic builder pattern and how you can enhance it with the step builder pattern in order to build objects with a no brain interface, easy to use, impossible to get wrong.

So lets start painting some context, we have 2 domain objects representing a user configuration to connect to some remote or local server. When remote credentials are required, when local no.

package com.marco.sbp;
public class UserConfiguration {
        private final String name;
        private ServerDetails serverDetails;

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

        public void setServerDetails(ServerDetails serverDetails) {
                this.serverDetails = serverDetails;
        }

        public String getName() {
                return name;
        }

        public ServerDetails getServerDetails() {
                return serverDetails;
        }
}



package com.marco.sbp;
public class ServerDetails {

        private final String host;
        private String user;
        private String password;

        public ServerDetails(String host) {
                this.host = host;
        }

        public void setUser(String user) {
                this.user = user;
        }

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

        public String getHost() {
                return host;
        }

        public String getUser() {
                return user;
        }

        public String getPassword() {
                return password;
        }
}


We want to abstract the construction of the objects above using 2 different techniques, the classic builder pattern and the step builder pattern.

The classic builder pattern is pretty straightforward, it works masking the creation of the UserConfiguration and the ServerDetails using properly named methods like onLocalHost, onRemoteHost, etc.
package com.marco.sbp.builder;
import com.marco.sbp.ServerDetails;
import com.marco.sbp.UserConfiguration;
public class ClassicBuilder {
        
        private String name;
        private String host;
        private String user;
        private String password;

        
        public ClassicBuilder(String name){
                this.name = name;
        }
        
        public ClassicBuilder onLocalHost(){
                this.host = "localhost";
                return this;
        }
        
        public ClassicBuilder onRemoteHost(String remoteHost){
                this.host = remoteHost;
                return this;
        }
        
        
        public ClassicBuilder credentials(String user, String password){
                this.user = user;
                this.password = password;
                return this;
        }
        
        public UserConfiguration build(){
                UserConfiguration userConfiguration = new UserConfiguration(name);
                ServerDetails serverDetails = new ServerDetails(host);
                serverDetails.setUser(user);
                serverDetails.setPassword(password);                    
                userConfiguration.setServerDetails(serverDetails);
                return userConfiguration;
        }
}



The step builder pattern is still using smart names to construct the object, but it's exposing these methods only when needed using interfaces and proper encapsulation.
package com.marco.sbp.builder;
import com.marco.sbp.ServerDetails;
import com.marco.sbp.UserConfiguration;

/** "Step Builder" */
public class StepBuilder {
        public static NameStep newBuilder() {
                return new Steps();
        }

        private StepBuilder() {
        }

        public static interface NameStep {
                /**
                 * @param name
                 *            unique identifier for this User Configuration
                 * @return ServerStep
                 */
                ServerStep name(String name);
        }       

        public static interface ServerStep {
                /**
                 * The hostname of the server where the User Configuration file is stored will be set to "localhost".
                 * 
                 * @return BuildStep
                 */
                public BuildStep onLocalhost();

                /**
                 * The hostname of the server where the User Configuration file is stored.
                 * 
                 * @return CredentialsStep
                 */
                public CredentialsStep onRemotehost(String host);
        }

        public static interface CredentialsStep {
                /**
                 * Username required to connect to remote machine Password required to connect to remote machine
                 * 
                 * @return BuildStep
                 */
                public BuildStep credentials(String user, String password);
        }

        public static interface BuildStep {
                /**
                 * @return an instance of a UserConfiguration based on the parameters passed during the creation.
                 */
                public UserConfiguration build();
        }

        private static class Steps implements NameStep, ServerStep, CredentialsStep, BuildStep {

                private String name;
                private String host;
                private String user;
                private String password;

                public BuildStep onLocalhost() {
                        this.host = "localhost";
                        return this;
                }
                
                public ServerStep name(String name) {
                        this.name = name;
                        return null;
                }

                public CredentialsStep onRemotehost(String host) {
                        this.host = host;
                        return this;
                }

                public BuildStep credentials(String user, String password) {
                        this.user = user;
                        this.password = password;
                        return this;
                }

                public UserConfiguration build() {
                        UserConfiguration userConfiguration = new UserConfiguration(name);
                        ServerDetails serverDetails = new ServerDetails(host);
                        serverDetails.setUser(user);
                        serverDetails.setPassword(password);                    
                        userConfiguration.setServerDetails(serverDetails);
                        return userConfiguration;
                }

                
        }
}



Lets see now what is the user experience with both of our builders.

The classic builder  will be constructed using the name of the user configuration, then it will expose all of its methods leaving the user a bit too free to choose what's next.



For example, a not careful user could end up with a UserConfiguration set with localhost where no authentication is required, still passing user and password.
This is confusing and it can lead to run-time exceptions.

These are some of the possible combinations of UserConfigurations that the user can end up with, some are correct, lots are wrong:


A complete different story is with the step builder, here only one step at the time is exposed:

If the credentials are not needed they will not be exposed and the build() method is offered only when the state of the object is sure to be coherent and complete:


Only 2 possible UserConfigurations can be built with this pattern, and both make sense and are clear to the user.

 Conclusion

The step builder pattern is not the replacement of the classic Bloch one, sometimes you want to force the user to fill some parameter before advancing with the creation, in this case the step builder is doing the job, otherwise when a more open approach is required than the classic builder is your guy.





Sunday, 28 April 2013

Even in the jdk there is bad code.

Java 7, TreeSet and NullPointerException.

Recently I tried to compile with java 7 a project developed with java 6.

Lot of fun happened during tests execution, tests that in java 6 were  running smoothly, with java 7, they were strangely failing!
So, I had to understand why and this is what I discovered...

The context first:
In that project I have a simple Hibernate Entity more or less like the following. 
package com.marco.test;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.validator.NotNull;
@Entity
@Table(...)
public class ABean {
        
        ...
        
        private String name;

        @Column(name = "name", nullable = false)
        @NotNull
        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }
}
note that the field "name" is nullable=false and marked with @NotNull.
This to tell Hibernate to fail the validation in the case a user tries to create or update this column to Null.

I also have a comparator for that Entity.
This comparator uses the name field to compare the Entity ( this is just a simplified version of what I have in the project, of course I don't order a bean based on the string length :) )
package com.marco.test;
import java.util.Comparator;
public class ABeanComparator implements Comparator<ABean> {

        @Override
        public int compare(ABean o1, ABean o2) {
                if (o1.getName().length() > o2.getName().length()) {
                        return 1;
                } else if (o1.getName().length() < o2.getName().length()) {
                        return -1;
                } else {
                        return 0;
                }
        }
}
note that there is no null check on the field name, in my project, Hibernate is already taking care of it.

Now, I have a test that create one empty Entity and it stores it into a TreeSet, and then doees other stuff that we do not really care here.
The beginning of the test is similar to the code below:  
package com.marco.test;
import java.util.SortedSet;
import java.util.TreeSet;
public class SortedTestTest {

        public static void main(String[] args) {

                ABean aBean = new ABean();

                SortedSet<ABean> sortedSet = new TreeSet<ABean>(new ABeanComparator());

                sortedSet.add(aBean);
        }
}
If I run this with java 6, everything is OK.

But, with java 7 I have a NullPointerException.  
Exception in thread "main" java.lang.NullPointerException
        at com.marco.test.ABeanComparator.compare(ABeanComparator.java:9)
        at com.marco.test.ABeanComparator.compare(ABeanComparator.java:1)
        at java.util.TreeMap.compare(TreeMap.java:1188)
        at java.util.TreeMap.put(TreeMap.java:531)
        at java.util.TreeSet.add(TreeSet.java:255)
        at com.marco.test.SortedTestTest.main(SortedTestTest.java:14)
Why?

This is why:
    public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
In java 7 when the first Object is added ( if (t == null) ) to a TreeSet, a compare against itself (compare(key,key)) is executed.  

The compare method will then call the comparator (if there is one) and we will have the NullPointerException on the name property. 
    // Little utilities

    /**
     * Compares two keys using the correct comparison method for this TreeMap.
     */
    final int compare(Object k1, Object k2) {
        return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
            : comparator.compare((K)k1, (K)k2);
    }

This raises more questions than answers:


  • Why running a compare if you know that the Object in the TreeSet is the first and only one ?
    • My guess is that what they wanted to do was running a simple Null check.
  • Why not create a proper null check method ?
    • No Answer
  • Why wasting CPU and memory running a comparison that is not needed ?
    • No Answer
  • Why compare an object against itself (compare(key,key))??
    • No Answer


This is the put method of the TreeSet in java 6 and as you can see the compare was commented out.
public V put(K key, V value) {
                Entry<K, V> t = root;
                if (t == null) {
                        // TBD:
                        // 5045147: (coll) Adding null to an empty TreeSet should
                        // throw NullPointerException
                        //
                        // compare(key, key); // type check
                        root = new Entry<K, V>(key, value, null);
                        size = 1;
                        modCount++;
                        return null;
                }
You see the comment?  Adding null to an empty TreeSet should throw NullPointerException
So just check if key is null, don't run a useless comparison!


The conclusion? Always try to analyze the code you use, because even in the jdk there is bad code!