Coding Naked in a Box of Rats

August 30, 2009

Snow Leopard and Java compatibility issues

Filed under: Java, Mac OS X — Wei-ju Wu @ 1:16 am
Tags: , , , ,

Contrary to my regular habits, I bought the latest update to Mac OS X, “Snow Leopard” on the first day of release. Our local Apple store opened early (I think around 8-ish) on the 28th and I picked up my copy as soon as I saw the doors opened.

The truth is, since the days of the Amiga, I have not been as excited for an operating system release. My confidence in the quality that comes out Apple is also almost limitless, so I just popped the DVD into my computer and waited about an hour for the install to finish, hoping that there would be 7 GB magically reclaimed from my hard disk. I was wrong – it turned out to be a whopping 14 GB, which I thought was pretty impressive.

The next thing was for me to look for apparent problems, but apart from my “A Lot of Water” screen saver stopping to work (some changes to OpenGL in Snow Leopard might have caused this *sniff*), I did not notice any problems, just the “it just works” that I am used to from Apple. Well – until I started to do some development in Java. The Snow Leopard installation seems to remove  an installation of Java SE 5 and instead link the Java SE 6 version to it.

So what’s the problem, Java SE 6 is compatible to Java SE 5, some would say. Yes, almost. Unfortunately there are some incompatible changes in JDBC (in my case, the Connection interface) that requires me to work on a Java SE 5.

Luckily someone had the same problem and has published a solution for that problem: The bottom line is to download a Leopard version of Java 5 and redirect the symbolic links to that downloaded version.

After following the instructions, I could continue working on my Java project as before.

Update: I had another issue with maven even though I had already changed the version in Java Preferences. This could be fixed by adding a line

JAVA_VERSION=1.5

to the  ~/.mavenrc file.

August 7, 2009

Setting up maven for Scala and ProGuard

Filed under: Java, Mac OS X, Maven, Scala, software development — Wei-ju Wu @ 11:22 pm

I have started to use Scala occasionally since last year, it is less scary than it initially looked to me and thanks to good tool support (specs comes to my mind), it is even a joy to program in Scala.

What I initially found irritating though was the fact that the Scala library (despite running on a platform with one of largest standard libraries in existence) is huge – almost 3 megabytes in size – reminds me of my first “Hello world” written in Eiffel 15 years ago (that was about 4 MB). For applications to be run on the server one could simply say: who cares ? Still, I do write quite a bit of applications that are distributed over the Internet, be it applets, Webstart or Android applications and I strongly believe Scala is good for the server as well as the client side. For downloadable client applications, actually size does matter (at least to me).

Fortunately, there are tools that can strip out unused code from class files and further optimize the size of the generated jar files. ProGuard, which is Open Source, is such a tool and it even works for Android. Since I plan to replace Java with Scala as my main static JVM language (haven’t settled on the dynamic one, but so far, it looks good for Clojure), I fiddled a bit with a maven POM, that I can use as a template for my projects and thought I might share the relevant pieces that took me a bit of experimentation to get working. Maven 2 has now become my standard Java build tool, simply because I can generalize my builds a lot when working with JVM languages and they integrate well into my Hudson/git/jira/Eclipse environment.

I like my Java applications to be started with a simple java -jar <jarfile>, so I configured the maven-assembly-plugin to set the main class into the manifest file and linked it to the package phase in order to avoid that the assembly plugin would add my class files to the jar file twice (ProGuard complains about this) – therefore the assembly:single phase is invoked.

...
      <!-- Assembly: jar-with-dependencies -->
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-assembly-plugin</artifactId>
	<version>2.2-beta-4</version>
	<configuration>
	  <descriptorRefs>
	    <descriptorRef>jar-with-dependencies</descriptorRef>
	  </descriptorRefs>
	  <archive>
	    <manifest>
	      <mainClass>com.boxofrats.App</mainClass>
	    </manifest>
	  </archive>
	</configuration>
	<executions>
	  <execution>
	    <id>make-assembly</id>
<phase>package</phase>
	    <goals><goal>single</goal></goals>
	  </execution>
	</executions>
      </plugin>
...

ProGuard is linked to the package phase as well and runs after the assembly goal. <includeDependency> is set to false to avoid warnings about duplicates, because we have already pulled the dependencies into the jar file in the assembly goal:

...
      <!-- ProGuard -->
<plugin>
	<groupId>com.pyx4me</groupId>
	<artifactId>proguard-maven-plugin</artifactId>
	<executions>
	  <execution>
<phase>package</phase>
	    <goals><goal>proguard</goal></goals>
	  </execution>
	</executions>
	<configuration>
	  <includeDependency>false</includeDependency>
	  <injar>${project.build.finalName}-jar-with-dependencies.jar</injar>
	  <outjar>${project.build.finalName}-small.jar</outjar>
<proguardInclude>${basedir}/proguard.conf</proguardInclude>
	</configuration>
      </plugin>
...

My proguard.conf looks like this, note that this is a setup, for Mac OS X, where the JDK’s jar files are at a different location than on Windows, Solaris and Linux (they should be in $JAVA_HOME/lib/rt.jar:$JAVA_HOME/lib/jsse.jar):

-dontwarn
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-libraryjars /System/Library/Frameworks/JavaVM.framework/Classes/classes.jar:/System/Library/Frameworks/JavaVM.framework/Classes/jsse.jar
-keep class com.boxofrats.App {
  public static void main(java.lang.String[]);
}

When building application with mvn package, there is a significant reduction in size of the resulting jar file, which is exactly what I wanted. “Hello world” is about 3-4 K, but that’s of course not representative. The bottom line is: we do not have to carry around 3 megs of dead baggage, we just take what we need. Being able to create smaller applications makes development in Scala much more reasonable for mobile platforms.

August 6, 2009

Migrating ZMPP to git

Filed under: Java, ZMPP, software development — Wei-ju Wu @ 11:24 pm
I did it. Finally I moved from Subversion to git. Until today, ZMPP was the
only larger project that was still in a Subversion repository.
To be fair, in the two years I used it for my projects, I have never really experienced
larger problems. It felt exactly like it was intended to be: A better, more modern CVS,
and it has great tool support as well, something where git could still improve.
Still, after using git in parallel to svn and cvs for about a year now, nothing really
beats the comfort working with a DVCS.

I did it. Finally I moved from Subversion to git. Until today, ZMPP was the only larger project maintained by me that was still in a Subversion repository. To be fair, in the two years I used it for my projects, I have never really experienced larger problems. It felt exactly like it was intended to be: A better, more modern CVS, and it has great tool support as well, something where git could still improve.

Still, after using git in parallel to svn and cvs for about a year now, nothing really beats the joy working with a DVCS, even when used solely through the command line. Personally, the way git handles branching and merging is perfect for me: it really invites one to make wild experiments. Another nice thing is that due to its decentralized nature, it is much easier for me to add ZMPP to my Hudson setup, work on my local copy and just push the changes to Sourceforge when I think they are good enough.

Blog at WordPress.com.