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;




Sunday, July 1, 2012

Why I like Java in Groovy

For many people the option in Groovy to switch to Java seems useless and as an extra burden. But I find it very useful, with great potential (just like option to inline assembler in C or Pascal, in the good old days). And I have an example where I can show you how I used it in real life.
   Because for the past year I was responsible for our builds, I wrote some scripts to simplify the tedious and error prone work. First I wrote some bash and Ant scripts, which I latter ported to Gradle. I found Gradle to be more suitable for the tasks our build required.
   Recently I was writing a task to manipulate some binary files, when I run into an odd problem with Gradle/Groovy. With following implementation:


// wrong implementation

File inputFile = new File("location.tmp");
locationTemplate = inputFile.getText();
byte[] tmplContent = locationTemplate.getBytes();
byte[] resultContent = new byte[ tmplContent.length];

//do something with the content and copy it to resultContent
f = new File(metaFilePath);
f.write(new String(resultContent));


Some bytes/characters were changed during saving, which was a problem. So I changed it to following implementation:

//working implementation
File fin = new File("location.tmp");
long length = fin.length();
byte[] tmplContent = new byte[(int)length];
FileInputStream fis = new FileInputStream(fin);
fis.read(tmplContent);
fis.close();

//do something with the content
FileOutputStream fos = new FileOutputStream(new File(metaFilePath));
fos.write(resultContent);
fos.close();


So I came to a point where I was thankful to Groovy and Gradle that I can switch seamlessly between Groovy and Java.