2013/05/17

Book review: Well-grounded Java developer

Vital techniques of Java 7 and polyglot programming

  • Publisher: Manning
  • Authors: Benjamin J. Evans and Martijn Verburg
  • Ranking: I would definitely recommend this book

Originally, I wanted to write a complete review of this book but I found some really good reviews already available on the internet. What I would like to say is that this book is exactly what the title reads. If you want to be a good Java developer and you mean it, you should know all the information in this book. A great thing about it is that it has a very balanced level of details. The information are presented in a compact well understandable form without wasting the reader's time. So if you did not read it yet, go to the nearest book store or library.

2013/01/03

HashMap serialization issue

Today, we discovered an interesting behaviour in Oracle JDK 7 with my colleague. This also affects OpenJDK 7. There is a change in the implementation of the HashMap serialization. If you serialize and then deserialize a HashMap, two private fields are changed. The first is threshold and the second is table. While these changes do not seem to have any effect on the public behaviour of the class, it makes various testing a little bit harder.

For example, you developed a client/server application that exchanges some objects. These objects might hold some properties in a HashMap. To test the correctness of the communication channel, you send a serialized object from the client to the server. The server deserializes the object, changes an attribute and sends the serialized version back to the client. The client performs the same changes to its version of the object and serializes it too. Then the client compares the serialized byte arrays. With JDK 7 it finds them different and this is a problem in my opinion. Or do you find it a completely insane integration test scenario? I already found it in many projects so I suppose it is not that uncommon and bad.

A reproducer can be found at GitHub. I also logged an issue with Oracle. They are now about to review it. However, I suppose they are not going to fix the issue since it does not influence the public API. Who cares about testers...

2012/09/05

How to really delete a commit from Git

I really wanted to remove a huge binary file from a Git repository that has been committed by mistake. I found a bash script on the internet but the data still remained in the .git directory.

After some changes I came to this solution that really worked for me. But do not try that at home, it might corrupt your data!

#!/bin/bash
set -o errexit

if [ $# -eq 0 ]; then
    exit 0
fi

if [ ! -d .git ]; then
    echo "Error: must run this script from the root of a git repository"
    exit 1
fi

files=$@
git filter-branch --prune-empty --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD

rm -rf .git/refs/original/ && git reflog expire --expire=now --all &&  git gc --aggressive --prune=now && git repack -a -d -l

2012/07/20

JBoss Technologies 1 in Czech

I would just like to bring your attention to my recent blog post on JBoss. The target audience is the Czech JBoss Community, so the article is in Czech only.

2012/04/11

Move a java keystore certificate to openssl

A very good article on moving a self-signed certificate from a Java keystore to an openssl based keystore. Just the last step is missing:
openssl pkcs12 -name my_alias -export -in test.crt -inkey test.key -out keystore.p12

2012/01/07

Byteman plays with Drools

Due to my recent suspicion that there is a bug in Drools I needed to monitor its guts in detail. To be more specific, I needed to see what is in the working memory after execution of all rules.

Debbuger was not a good option since there were hundruds of invocations of the problematic part and I needed to get overview of quite a large amount of data. If I inly could store all the data for each invocation in a file and then grep through it.

But wait! Of course I can. Byteman will help me! The identified point in source code was execution of fireAllRules() in org.drools.common.AbstractWorkingMemory. Ideally, just before return from the method. So here is the corresponding rule:

RULE Debug fireAllRules
HELPER org.drools.planner.examples.tournaments.helper.BytemanHelper
CLASS ^org.drools.common.AbstractWorkingMemory
METHOD fireAllRules
AT EXIT
IF TRUE
DO
  printWorkingMemory($0.getKnowledgeRuntime());
ENDRULE

Just a few notes to it:

  • ^ means to apply to child classes as well
  • $0 refers to this

As you can see there is a custom helper class to print the working memory content since Byteman rules are little bit limited in the supported Java syntax.

import org.drools.impl.StatefulKnowledgeSessionImpl;
import org.jboss.byteman.rule.Rule;
import org.jboss.byteman.rule.helper.Helper;

public class BytemanHelper extends Helper {
   protected BytemanHelper(Rule rule) {
      super(rule);
   }
   
   public void printWorkingMemory(Object obj) {
      StatefulKnowledgeSessionImpl session = (StatefulKnowledgeSessionImpl) obj;
      debug("vvvvvvvvvvvvvvvvvvvvvvvvvvv");
      debug(session.toString());
      for (Object o: session.getObjects()) {
         debug(o.toString());
      }
      debug("^^^^^^^^^^^^^^^^^^^^^^^^^^^");
   }
}

And now I was able to get some nice output of individual working memories! So the resulting bug is JBRULES-3337.

. .