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.

Tuesday, February 14, 2012

Pushing the Limits in Java's Random

Dr Heinz M. Kabutz, editor of Java Specialist's Newsletter, just published another fascinating article, this time about Java's Math.random(). This time with help from Dr. Wolfgang Laun, from Vienna. You can read the whole post here:

http://www.javaspecialists.eu/archive/Issue198.html

The important information is that, to get a random number from zero to some_int, we shouldn't use this code:

(int)(Math.random() * some_int)

Instead we should use nextInt(some_int) from java.util.Random class. Since Java 7, due to concurrency, we should use:

ThreadLocalRandom.current().nextInt(some_int);

But things are not so easy. There is a bug in Java 7 versions prior to 1.7.0_02, that results in returning the same value for all threads. I strongly recommend to any professional to read the whole post and also older posts from Dr. Kabutz's newsletter.

BTW: Dr Heinz M. Kabutz is a member of Java Champion group, an exclusive group of passionate Java technology and community leaders who are community-nominated and selected under a project sponsored by Oracle.

Monday, January 30, 2012

Immutable and no unit tests

This is something I came across recently in our codebase:
 public String doSomething(SomeClass inputParameter) {
...
if(result != null)
result.trim();
return result;
}

Well as you (probably) know the method will return untrimmed result. This turned into a nasty bug found during UAT testing, which took us couple of hours to find and solve. But this type of bug could be easily found with unit tests (if written properly). This is one of the reasons why I like Test Driven Development.