Skip to content


Exception Erasure

One of Scala’s biggest selling points is its seamless integration with regular Java code. Another, albeit much smaller selling point is the lack of checked exceptions. However when mixed, these two features can cause some confusion when Scala code is called from Java code.

Let’s take the following small example. I have some Scala library code that pulls the protocol off a URL represented as a String. Nothing complicated, it just news up a URL object and returns whatever getProtocol does.

package org.mccv
 
import java.net.URL
 
class CheckedEraser{
  def getProtocol(urlStr:String):String = {
    val url = new URL(urlStr)
    url.getProtocol
  }
}

What does the same thing in Java look like? Something like this

package org.mccv;
 
import orc.mccv.CheckedEraser;
 
import java.net.URL;
import java.net.MalformedURLException;
 
public class CheckedJava {
    public String getProtocol(String urlStr)
    throws MalformedURLException{
        URL u = new URL(urlStr);
        return u.getProtocol();
    }
}

Note that I have to declare that it throws MalformedURLException here. This isn’t surprising… as a Java developer working with URLs I’m probably all too familiar with MalformedURLException. Now comes the tricky part. I want to call my Scala code from Java. Here we go…

package org.mccv;
 
import orc.mccv.CheckedEraser;
 
import java.net.URL;
import java.net.MalformedURLException;
 
public class CheckedCaller {
    public static void main(String [] args){
        String urlStr = "www.google.com";
        String protocol = null;
 
        // Scala
        System.out.println("trying with Scala...");
        CheckedEraser ce = new CheckedEraser();
        protocol = ce.getProtocol(urlStr);
    }
}

As you can see, I didn’t actually pass in a valid URL… so what happens? I get a MalformedURLException thrown. Ok, so I should catch that. But does this work?

        try{
            protocol = ce.getProtocol(urlStr);
        }catch(MalformedURLException e){
            System.out.println("caught an exception of type " 
               + e.getClass().getName());
            e.printStackTrace();
        }

Nope, won’t compile. My Scala method doesn’t throw a MalformedURLException, because I was lazy and didn’t add my throws annotation. I’m forced to just catch Exception, and deal with refinement of that exception in my catch block, which is pretty ugly.

So a word of caution when handing Scala libraries over to Java developers… if you aren’t rigorous on your throws annotations, you are handing them a different exception handling contract. This may be ok, but it almost certainly needs to be explicitly stated. Note that this same exception erasure issue applies to Groovy, and likely other JVM languages that lack typed exceptions.

Posted in scala.

Tagged with , .


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.