Tuesday, November 7, 2017

Why you should always write unit tests. Event if it is not possible.

I became fan of test driven development couple of years ago, after my colleague Viktor introduced it to our team. I was bit skeptical but soon I realized that I can test my services without the need to deploy the application and laborious data typing into web forms. Over the years I used unit tests and test driven development whenever I had the chance. And I learned a lot about them.
   One thing I learned is that the argument that it is not possible to write unit tests is often just an excuse. The aversion to unit tests is not due to laziness but due to people not knowing the true benefits of unit tests.
   Here are two most recurring myths:

Unit tests test only happy day scenario. That's basically true, although it depends on the developer, who might include some border condition or invalid cases. But it is most useful when you are refactoring or changing some functionality, which is on any live project almost always. On any big project even subtle changes can break some remote functionality.

It takes time and effort to write and maintain unit tests. Yes, it takes effort. But deploying application and typing data takes even more effort. Simulating even most common possibilities takes even more time. I've never felt that writing unit tests delays me. Some scientific papers have shown that development with unit tests requires equal time as doing without it, but the resulting code was less bugy.

But the greatest benefit is the code readability. It requires "special" skills to test driven develop large unreadable method with spaghetti code. Instead you usually end up with many small methods that do little bit. Such code is much more readable and maintainable. If you ever end-up with such large and spaghetti method, with unit test it is very easy to refactor the code. The unit tests also serve as a kind of documentation. It is much easier to read unit tests and see method inputs and outputs, instead of guessing or reading method code.
  

Sunday, October 15, 2017

NullPointerException on non null object

Today I run into an odd problem. I was receiving NullPointerException (NPE) on a code, which simplified looked like this:

 if (input != null) {  
      process(input.getLength()); //This line was throwing NullPointerException  
 }  

I was puzzled. Because I am subscriber to Heinz Kabutz's newsletter about concurrency, I immediately suspect problem with threads. I had no idea how to test, if the problem is a result of thread run or something else, and I expected it to be a bit hard task. So I started to investigate the input variable and its content. I wrote short unit test to test given method.
  Soon I realized that if length (the return value of getLength() method) is null, the test crashes on NPE.
  That was really odd. But soon I realized where the problem was. The method process has signature

 private void process (int length) {  

and method getLength

 public Integer getLength() {  
   return length;  
 }  

The problem is that Java has to do unboxing, aka converting from Integer to int. It does it quietly in the background. It compiles the code from the first snipped to something like this:

 if (input != null) {  
      process(input.getLength().intValue());  
 }  

well because getLength() returns null, calling intValue() on null object produces NPE.

An odd problem, which took me some time to figure out. The resulting problem is a result of two other problems.
   First problem is broken implementation of method getLength(). The method should return int, because for an object (Integer) null is completely valid value. If for some reason it is necessary to return Integer, then for an empty object the method should return 0 instead of null. If null length represents uninitiated object, then this is broken design. There should be separate method for testing if the object is or isn't initiated.
  The second problem is autounboxing, which hides some code from the developer, which than fails. It should fail with message that unboxing failed due to null value. I wonder if it is possible to disable autounboxing in Eclipse (or Java compiler)?

Maven Global Excludes



Just recently I run into a problem in our project with maven dependencies. Transitively we had dependency on two different versions of 3rd party library. We ended up with both jars on our classpath, with the older version being higher in classpath. Thus our application failed with an erroru. To solve this problem we needed to exclude the older version. Here is a nice blog describing how to do it.

http://jlorenzen.blogspot.sk/2009/06/maven-global-excludes.html

Friday, May 5, 2017

Forcing jar or class loading order in Spring

Just recently I run into an odd problem. Due to the need to optimize some  SQL select in a one library we use, we needed to put its optimized SQL higher in the classpath. That was ok, as long as the XML file containing the optimized select was in our final module. That way it ended up inside the fat jar in "BOOT-INF/classes/" folder. Unfortunately this SQL select has to be available to all our modules so we needed it to be in our common jar.
   Unfortunately the Spring boot has no rule for jar class loading inside a directory. Fortunately there is nice Spring configuration feature called "loader.path". If set, Spring will put jars or classes provided in this path higher in classpath.
   Here is an example:

loader.path=BOOT-INF/classes/ThisClassFirst.class:BOOT-INF/lib/ThisJarNext.jar

You can place loader.path configuration into loader.properties file. That's what we did. But our common jar is versioned, so it looked something like this:

loader.path=BOOT-INF/lib/our-common-stuff-1.0.1-SNAPSHOT.jar

So now we had to solve the problem of replacing the version dynamically. To do that we used maven-replacer-plugin. So now our loader.properties file looked like:

loader.path=BOOT-INF/lib/our-common-stuff-@@COMMON_VERSION@@.jar

And our pom.xml contained following code:

<plugin>
  <groupid>com.google.code.maven-replacer-plugin</groupid>
  <artifactid>maven-replacer-plugin</artifactid>
  <version>1.3.5</version>
  <executions>
    <execution>
      <id>replaceTokens</id>
      <phase>prepare-package</phase>
      <goals>
        <goal>replace</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <file>target/classes/loader.properties</file>
    <replacements>
      <replacement>
        <token>@@COMMON_VERSION@@</token>
        <value>${our-common.version}</value>
      </replacement>
    </replacements>
  </configuration>
</plugin>


And now it works perfectly. Happy coding.

The credit for replacement plugin configuration goes to:
https://crushedbeans.wordpress.com/2013/06/08/using-maver-replacer-plugin-to-replace-strings-from-a-properties-file/

Thursday, April 20, 2017

Oracle's input parameters limit

Recently I stomped on an odd problem. One of our SQL selects failed with an error "ORA-01795: maximum number of expressions in a list is 1000". The problem was, that our IN expression had more than 1500 elements.

First it seamed like an unsolvable problem. I was really worried that I will have to split our call into multiple calls with less parameters and then combine and filter the results. That would be really painful. But there is a simple workaround.

Instead of this select (which will throw an error):
SELECT * FROM foo WHERE some_param IN ('1', ..., '1500')

You can rewrite your SQL select:
SELECT * FROM foo WHERE some_param IN ('1', ..., '999') OR

some_param IN ('1000', ..., '1500');

Tuesday, August 21, 2012

WSDL versioning

A few weeks ago I was asked how to version WSDLs. Well I had no idea, as I have never needed to do that. I worked in tightly environment where new versions of consumers and publishers were deployed at the same time. Sometimes not very successfully, but we didn't need to support multiple versions.
  I found the problem of WSDL interesting so I start googling and here are some information I found. The WSDL doesn't support versioning, so there are couple of ways how to do it.
  • Including service version in URI
  • Versioning using namespace (more information can be found here)
  • Using UDDI (more can be found here)
 I personally prefer versioning using namespace.

Monday, August 20, 2012

Correct singleton implementation

This is a bit outdated problem, but for my easy reference and for those who haven't stumbled on this problem I decided to write short article about correct singleton implementation. Much longer and descriptive article can be found here.
   It is quite common to see singleton implementation like this:

public class DBConnection {

    private static DBConnection instance;
    
    private DBConnection() {
        //DO something
    }
    
    public static final DBConnection getInstance() {
        
        if (instance == null) {
            instance = new DBConnection();
        }
        
        return instance;
    }    
}

Unfortunately this code doesn't work in multi threaded environment. Sometimes people try to fix it with following code:

public static final DBConnection getInstance() {
        
        if (instance == null) {
            synchronized (instance) {
                instance = new DBConnection();
            }
        }
        
        return instance;
}

This also doesn't work, due to Java memory model. There are some thread safe implementation, which actually differ between Java 1.4 and 1.5 up. For Java 1.4 the correct (lazy) implementation is:

public class DBConnection {

    private static class DBConnectionHelper {
        static DBConnection instance = new DBConnection();
    }
    
    private DBConnection() {
        //DO something
    }
    
    public static final DBConnection getInstance() {
        return DBConnectionHelper.instance;
    }    
}

Non lazy implementation for Java 1.4:

public class DBConnection {

    private static DBConnection instance = 
                           new DBConnection();
    
    private DBConnection() {
        //DO something
    }
    
    public static final DBConnection getInstance() {
        return instance;
    }    
}

From Java 1.5 up, there is available other implementation:

public class DBConnection {

    private static volatile DBConnection instance = null;
    
    private DBConnection() {
        //DO something
    }
    
    public static final DBConnection getInstance() {
        if (instance == null) {
            synchronized (this) {
                if (instance == null) {
                    instance = new DBConnection();
                }
                
            }
        }
        return instance;
    }    
}

And from Java 1.5 singletons can be implemented using enum:

public enum DBConnection {

    instance;
    
    private DBConnection() {
        //DO something
    }    
}

The instance is then accessible following way:

DBConnection connection = DBConnection.instance;