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.

July 23, 2009

A template for building Scheme applications for iPhone/Mac OS X in Xcode

I have often played with the idea of writing Mac and iPhone applications in Scheme, but as a result of not knowing the right compiler to embed (and lack of experience in Scheme), I could not execute on it. While programming in Objective-C is definitely doable (and of course you can use Objective-C++), I like to have more options for native application development.

Luckily, this month, there was one blog entry about Gambit-C on the iPhone which was a great starting point (and James has since put out more interesting posts on the topic). In addition to the fantastic advice found there, I wanted a better integration within Xcode, since for now, it seems impossible to develop (legally) for the iPhone outside of the IDE (personally, I prefer setting up builds based on cmake and make them as cross-platform as possible). In particular, I wanted a build phase to compile from Scheme to C without having to invoke the Scheme compiler manually. I have created a template for this purpose for later use and have put it on github in case other people might be interested to use it. The source is released under the new BSD license, so feel free to experiment !

The principle used is similar to the one described in James blog – all Scheme modules defined in the project are compiled to C files and linked into a single executable. When using the Gambit-C compiler, one has to pay attention to the code that it generates: when linking statically, we need to:

  • provide the -link switch to the compiler command
  • include all the Scheme source files we want to link into the executable

If we would compile each file separately with the link option there would be a flat link file for each Scheme module and we would get linker errors due to duplicate symbols. Calling gsc with all the needed Scheme modules provides it with the necessary information to generate a single flat link file. The template assumes that all the Scheme files are in the scheme sub directory. In order to invoke the compiler with the correct parameters, I added an external target (a small Ruby build script) that scans the scheme directory and feeds it to the gsc command and it also includes a clean action that removes the generated C files.

To use the template in a different environment, the user simply needs to set the variable GAMBITC_BASEPATH, which could be as simple as /usr/local. This can be set either in the .MacOSX/environment.plist or the bash .profile script in the home directory. After a change to these, the user needs to log out and log in again so Xcode can recognize the change to the user settings. I personally prefer to install development tools somewhere in my home directory, which has the advantage that I can use different configurations and don’t pollute my system directories.

The contents of my personal GAMBITC_BASEPATH look like this:

$(GAMBITC_BASEPATH)/Debug
$(GAMBITC_BASEPATH)/Release
$(GAMBITC_BASEPATH)/Debug-iphonesim
$(GAMBITC_BASEPATH)/Release-iphonesim
$(GAMBITC_BASEPATH)/Debug-iphoneos
$(GAMBITC_BASEPATH)/Release-iphoneos

These are the directories that are the parameters to the –prefix option in the configure call when compiling gambit-c (see James’ blog). In fact, I simply built a version for each platform (Mac OS X, iPhone Simulator and iPhone Device) and symlink’ed the directories to reflect the layout above, since I do not need separate Debug and Release versions for Gambit-C.

In the build rules for the main target, I added a dummy rule which specifies the output files of the “compile scheme” target. This is the only part that I find a little ugly, because whenever the list of Scheme modules changes, this list needs to be changed, so the C compiler can include these files in the builds. I still find this solution better than checking in generated files into version control or including C files in the project tree which do not exist.

The github repository contains templates for a Mac command line tool and one for an OpenGL ES application on the iPhone. Since I am a game developer, the OpenGL ES template is most useful to me, but it is pretty easy to adapt the setup for other kinds of iPhone (or Mac OS X) applications. The initialization point in my template differs from the one described in James Long’s blog: the main.mm is unmodified, instead, the Scheme system is initialized when the view is initialized, because that is the place where I currently pull up my engine.

Happy Hacking :-)

Blog at WordPress.com.