Dark Expression Blend Theme for Eclipse

A while back I discovered the Dark Expression Blend Theme for Visual Studio and having been using it ever since. Jealous while working in Eclipse one day, I decided to follow suit and prettify the daily Java experience. Thanks to the Color Theme plugin, it was all too easy. Without further ado: http://www.eclipsecolorthemes.org/?view=theme&id=4103

Naturally the mapping is imperfect—due to inherent limitations of the two IDEs, there are some differences. For example, Visual Studio does not offer a style option for inherited methods, but Eclipse does; so I decided to apply the same color as interfaces, which makes it easy to spot API consumption. Also, while Eclipse does support background colors for some constructs, string literals do not fall into this category and so we lose some of the richness in presentation compared to the Visual Studio version.

First Attempts with Restfuse: ClassFormatError

When InfoQ first broke news of Restfuse, I was very excited to try it out seeing as how I'd begun experimenting with the likes of Jersey and CXF at work. Given the 1.0.0 release status, it was my hope that plugging this thing into an existing project via Maven would take the whole of 5 minutes, but things just never work like that in the real world. Running a basic test similar to the snippet provided on the framework homepage produced the following result:

java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/mail/MessagingException at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) at java.lang.ClassLoader.defineClass(ClassLoader.java:616) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) at java.net.URLClassLoader.defineClass(URLClassLoader.java:283) at java.net.URLClassLoader.access$000(URLClassLoader.java:58) at java.net.URLClassLoader$1.run(URLClassLoader.java:197) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:248) at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2427) at java.lang.Class.getDeclaredMethods(Class.java:1791) at com.sun.jersey.core.reflection.MethodList.getAllDeclaredMethods(MethodList.java:70) at com.sun.jersey.core.reflection.MethodList.(MethodList.java:64) at com.sun.jersey.core.spi.component.ComponentConstructor.getPostConstructMethod(ComponentConstructor.java:126) at com.sun.jersey.core.spi.component.ComponentConstructor.(ComponentConstructor.java:120) at com.sun.jersey.core.spi.component.ProviderFactory.__getComponentProvider(ProviderFactory.java:165) at com.sun.jersey.core.spi.component.ProviderFactory.getComponentProvider(ProviderFactory.java:137) at com.sun.jersey.core.spi.component.ProviderServices.getComponent(ProviderServices.java:256) at com.sun.jersey.core.spi.component.ProviderServices.getServices(ProviderServices.java:160) at com.sun.jersey.core.spi.factory.MessageBodyFactory.initReaders(MessageBodyFactory.java:176) at com.sun.jersey.core.spi.factory.MessageBodyFactory.init(MessageBodyFactory.java:162) at com.sun.jersey.api.client.Client.init(Client.java:342) at com.sun.jersey.api.client.Client.access$000(Client.java:118) at com.sun.jersey.api.client.Client$1.f(Client.java:191) at com.sun.jersey.api.client.Client$1.f(Client.java:187) at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:193) at com.sun.jersey.api.client.Client.(Client.java:187) at com.sun.jersey.api.client.Client.(Client.java:159) at com.sun.jersey.api.client.Client.create(Client.java:669) at com.eclipsesource.restfuse.internal.InternalRequest.createRequest(InternalRequest.java:130) at com.eclipsesource.restfuse.internal.InternalRequest.get(InternalRequest.java:72) at com.eclipsesource.restfuse.internal.HttpTestStatement.callService(HttpTestStatement.java:83) at com.eclipsesource.restfuse.internal.HttpTestStatement.sendRequest(HttpTestStatement.java:70) at com.eclipsesource.restfuse.internal.BasicStatement.evaluate(BasicStatement.java:30) at com.eclipsesource.restfuse.internal.HttpTestStatement.evaluate(HttpTestStatement.java:55) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Not very encouraging. Attempts to rectify the problem by adding javax.mail.mail to the list of dependencies were proving futile until I found this little gem (corollary to Wisdom of the Ancients?):

This happens if your code compiles against incomplete classes, like the JavaEE6 Api and your Unit tests try to access code thats not there.

....

The Solution You have to compile against real-implementations of the classes. You do that by adding those dependencies before the most generic dependency in your pom.xml

As example, we add javax.mail BEFORE javaee6-api like this

<project ...>
...
    <dependencies>
 
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
</project>

Lowe and behold: green bar.