java

Five random lessons learned about Scala

Posted in java, scala, software development on April 15th, 2009 by Joerg – 7 Comments

Since a week I am playing around with Scala to see what all this fuss is about. After Twitter has anounced that they are using Scala (see this presentation) there is a real hype now. So far I must admit I am impressed. This language is really nice. I will certainly have a very detailed look. The book “Programming in Scala” is already on its way from Amazon.

The following lessons learned are just a kind of note to self. These are some random experiences I made when playing around. Your first lessons will probably be completely different.

1. Scala != Groovy
Although this is obvious, when you have prior experience in Groovy it is tempting to fall into your Groovy habits. Both languages look similar at a glance but are very different in detail. For instance I very often write def when defining a variable where it should be val or var. The fact that def is a valid keyword in Scala and is used to define methods is not helpful in this regard. There are so many other subtile differences that I can’t mention them here. Just be aware of that.

2. Use a decompiler
A decompiler can be very useful when learning Scala. Just compile the Scala class and then decompile it. This way you can easily see, what the Scala compiler is creating when using certain language features. I discovered a nice decompiler while doing this. It can be found here. The decompiler was key for solving the next issue.

3. Be careful with field level annotations
It is a great feature of Scala that you can use established Java frameworks and just replace the Java code with Scala. This way you can easily use Spring and the likes. I did that but had sudden problems with the Spring @Autowired annotation. I annotated the field like that:

@Autowired
var pollService: IPollService = _;

Spring was starting to complain about missing parameters on the annotated method. What?
Ok, I was aware that Scala generates corresponding methods for a field just like Groovy does. But what was the issue here? The Spring annotation is defined as field level and method level annotation. But when it is used on a method it has to be a setter which gets at least one parameter. The decompiler saved the day. It shows that Scala is applying the annotation three times. At the field, at the setter pollService_$eq() and the getter pollService(). The last causes the Spring exception. (For all Scala experts, the @BeanProperty annotation does not solve the problem)
The (ugly) workaround is to create the setter manually and annotate only this. Here is how:

var pollService: IPollService = _;

@Autowired
def setPollService(pollService: IPollService) = {this.pollService = pollService}

4. Switch of “Compile Scala files first” in IDEA

There is a small bug/inconvinience in the current Scala plugin of IntelliJ Idea. It occurs when you have a project with combined Java and Scala sources. Any Java class that is located in a test source folder will not compile. You will get an error message “ClassX is already defined as class ClassX”. To fix this you can simply change the Scala compiler settings. Go to Settings->Compiler->Scala and uncheck “Compile Scala Files First”. It is not perfect, as you might need to manually (Ctrl-Shift-F9) compile Scala sources that Java files depend on. But at least you can compile everything now.

5. Use Scalatest!
If you want to write tests in Scala try Scalatest. It shows perfectly what can be done in Scala. It enables different styles of testing like xUnit or BDD just by applying different traits. And it enables you to use TestNG in your Scala tests. This way you can just start tests in Scala as if they where Java, at least in Intellij Idea. Here is a small example how a Test can look like:

@Test def testCreateTopicPoll() = {
  val pollDto = preparePoll
  val pollId = pollService saveOrUpdateTopicPoll pollDto;
  pollId should not be null
}

Look at the last line. Isn’t that beautiful? This is real code. You would not need any comments to explain, what is under test here.

I can strongly recommend that you have a look into Scala. It is a very interesting language with some nice concepts. I hope that some of my lessons learned help you when doing your first steps. Then let me know what lessons you learned!

Inheritance of class annotations in TestNG

Posted in java, software development, testing on April 5th, 2009 by Joerg – 1 Comment

Recently Oliver Fischer introduced TestNG at the Berlin-Brandenburg JUG. At one point there was an interesting discussion with the audience about class level annotations. Why should they be used? You can annotate a class like this:

@Test
public class Foo 
{
...

Now every public method in this class is considered a test method. Several people in the audience mentioned that they would still prefer to mark the test explicitly. This is just more readable. But if so, what might be a good reason to use class level annotations?

One very nice characteristic of class level annotations is that they can be inherited. Let’s assume you want several classes in a specific testgroup. What you don’t want to do is to annotate each and every test method with @Test(groups = {“MyTestGroup”}). This is simply not DRY. Using inheritance, you can instead create a base-class like this:

@Test(groups = {"MyTestGroup"})
public class BaseClass 
{
...

Now each test class that should be in this group can just extend BaseClass.

public class MyTestClass extends BaseClass 
{
...

Every public method in these classes is a test method and they belong to the group MyTestGroup. You probably still want to add the @Test annotation to each of the methods for readability. The group assignment is still valid.

What other ideas do you have for making use of annotation inheritance in TestNG?

Tomahawk and Spring Webflow

Posted in java, software development on March 20th, 2009 by Joerg – Be the first to comment

I recently ran into a configuration problem when using Apache Tomahawk and Spring Webflow together. When using some of the more advanced components like <t:inputDate> I got an error message:

...
java.lang.IllegalStateException: ExtensionsFilter not correctly configured. JSF mapping missing.
...

I did configure the MyFacesExtensionsFilter like shown in the documentation but that was not enough:

 <filter>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
     ...
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
  </filter-mapping>

After some debugging it turned out that this filter was never called. The solution is simple. When you combine Spring Webflow and JSF the Faces Servlet has no real function. It just needs to be there for some compatibility reasons. The real servlet that needs to be filtered is the Spring MVC Dispatcher Servlet. So you need to change the filter mapping like this:

<filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
</filter-mapping>

This also applies for all other filters that are usually applied to the faces servlet, like the Trinidad filter.

XML to POJO via Groovy

Posted in groovy, java, software development on March 8th, 2009 by Joerg – 9 Comments

Transforming data in XML to several Java-Objects is a pretty common task. There are a lot of technologies that support this. One example would be JAXB. It is also not uncommon that the structure of the original XML and the Java objects does not match. The obvious choice for XML transformation in such a situation would be XSLT.
There is another approach that uses Groovy to transform XML directly into a POJO structure in one step. I will show you how this looks like.

Lets assume, we have a XML-file like this:

<data>
  <person>
    <firstname>Otto</firstname>
    <lastname>Mueller</lastname>
    <street>Lange Strasse</street>
    <city>Berlin</city>
  </person>
  <financial>
    <netincome>120000</netincome>
  </financial>
</data>

The target structure are two POJOs that look like this:
Target Objects

Both structures differ. There are also some small conversions to do. The XML includes yearly income, where the POJOs needs monthly income. The POJOs contains a field for zipcode, but the XML does not deliver it.

So, here is the Groovy-Code that does all the transformation:

public class XmlTransformer
{

  Person transform(File xml)  //1
  {
    def xmlData = new XmlSlurper().parse(xml)   //2

    Person person = new Person()

    person.firstName = xmlData.person.firstname   //3
    person.lastName = xmlData.person.lastname

    Address address = new Address()
    address.city = xmlData.person.city
    address.street = xmlData.person.street
    address.zipCode = ZipCodeFinder.find(xmlData.person.city.toString(),   //4
            xmlData.person.street.toString())
    person.address = address

    BigInteger yearlyIncome = new BigInteger(xmlData.financial.netincome.toString())
    person.monthlyIncome = yearlyIncome.divide(12)  //5

    return person
  }

}

What happens in detail (numbers on the list match the numbers in code comments):

  1. This is a simple Groovy class that contains one method called transform. This method gets the XML-file as input and returns a Person object. The Person class itself is defined in Java.
  2. XMLSlurper  is the Groovy XML-Parser that allows the easy access to all xml elements. For more details on it see here.
  3. This uses some Groovy magic. On the left side we assign the value to the property firstName of the person object. This is a shortcut for using person.setFirstName(). On the right side we see the slurper at work to get us the XML value.
  4. We can call any Java-class from within the transformation code. Here we call an example helper-class, that would return a zipcode for a given city and street.
  5. Finally we also do some calculations within our transformation to convert the yearly income to a monthly value.

Groovy can be called from Java in several ways. If you do not need to change the transformation often I recommend to just compile the Groovy code. In that case it will be called from Java as if it would be Java code:

XmlTransformer transformer = new XmlTransformer();
Person person = transformer.transform(inputFile);

This kind of transformation code can easily be embedded into a Java project. There are several advantages, when using the Groovy method:

  • Just one step for transformation including conversions.
  • Easy debugging, when using an IDE like IntelliJ IDEA.
  • Java-like syntax, no learning of XSLT required.
  • Easy code-structuring. The transformation can use all features of a dynamic object-oriented language.
  • Simple unit-testing. If you split the code into several methods, you can test each logical unit using established frameworks like JUnit or TestNG.

So what is your opinion? What are your current methods of transforming XML to POJOs?

XMind on Mac with Java 6

Posted in apple, java, tools on February 27th, 2009 by Joerg – 2 Comments

The Problem

XMind is a very nice mind mapping software. It is platform independent and it’s free. I started using it at work on a Windows PC. When I installed it on my Mac I had a bad surprise. When starting it, it stopped immediately with a message that the JVM terminated.

xminderror

Xmind is based on Eclipse RCP. Eclipse itself is using the Carbon framework on the Mac for it’s GUI. But Carbon is not supported on 64 Bit. But Java 1.6 on the Mac does only work on 64 Bit. So it will of course not work.

The Solution

You don’t need to uninstall Java 6 in order to run XMind. It turned out the solution was much simpler. You have to tell the XMind app what JVM to use. To do this use your favorite text editor and open the following file (I recommend VI 🙂 ):

/Applications/XMind.app/Contents/Info.plist

Look for the following text and uncomment the -vm option:

<!-- to use a specific Java version (instead of the platform's default) uncomment 
         the following options:-->
<string>-vm</string>
<string>/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Commands/java</string>

Make sure it points to the right JVM. I had to change it to 1.5.0 as it did only point to Current, which was 1.6.

Save, start XMind again and have fun creating Your mindmaps.