Skip to content

Setting up maven for Scala and ProGuard

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 , 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.


...

  
    com.pyx4me
    proguard-maven-plugin
    
      
        package
        proguard
      
    
    
      false
      ${project.build.finalName}-jar-with-dependencies.jar
      ${project.build.finalName}-small.jar
      ${basedir}/proguard.conf
    
  
...

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


...

  
    com.pyx4me
    proguard-maven-plugin
    
      
        package
        proguard
      
    
    
      false
      ${project.build.finalName}-jar-with-dependencies.jar
      ${project.build.finalName}-small.jar
      ${basedir}/proguard.conf
    
  
...

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.

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*