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.

MyBatis Extended ResultMap Woes

In the months between 3.0.4 and the latest 3.0.6-SNAPSHOT of MyBatis, a breaking change was introduced regarding extended resultmaps. Consider the following example:

<resultMap id="summaryMap" type="Foo">
  <constructor> 
    <idarg column="id" javaType="String"/>  
  </constructor>  ...
</resultMap>

<resultMap id="detailsMap" type="Foo" extends="summaryMap">
  ...
</resultMap>

While this worked fine in version 3.0.4, upgrading to 3.0.6 resulted in exceptions thrown during parsing of the mapper file (and ambiguous ones at that, having nothing to do with the actual problem). It turns out the problem is the constructor specified in summaryMap. Perhaps this falls in line with the documented usage where a discriminator is used to instantiate derived types in a hierarchy, implying a potential need for diverging constructors, but it seems wasteful to repeat property mappings if it can be avoided...

<resultMap id="baseMap" type="Foo">
  ...
</result>

<resultMap id="summaryMap" type="Foo" extends="baseMap">
  <constructor> 
    <idarg column="id" javaType="String"/>  
  </constructor>  ...
</resultMap>

<resultMap id="detailsMap" type="Foo" extends="baseMap">
  <constructor> 
    <idarg column="id" javaType="String"/>  
  </constructor>  ...
</resultMap>

By going all out with resultMap extension, we can offload common properties into a base map and stay DRY. Regrettably, repeating the constructor cannot be avoided as it is the culprit behind the problem at hand, but this is certainly better than repeating everything.

Java-esque Enums in .NET

In the process of porting some code from an existing Java application to C#, I came across the following enum:

public enum UnitType
{
    APT("Apartment"),
    BOX("Box"),
    LOT("Lot"),
    PIER("Pier"),
    RM("Room"),
    RR("Rural Route"),
    SLIP("Slip"),
    ST("Street"),
    STE("Suite"),
    UNIT("Unit"),
    WHARF("Wharf"),
    WING("Wing");
 
    private String label;
 
    UnitType(String label)
    {
        this.label = label;
    }
 
    public String getLabel()
    {
        return label;
    }
}

That's all well and good, but .NET enums are not full-blown objects as they are in Java. Since I really just need key-value associations in this case, a Dictionary would fit the bill here. But what about the calling code? It would be nice not to muddy things up with extraneous explicit trips to said dictionary. Let's apply some extension method magic…

public enum UnitType
{
    APT, BOX, LOT, PIER, RM, RR, SLIP, ST, STE, UNIT, WHARF, WING
}

public static class UnitTypeExtensions
{
    public static String GetLabel(this UnitType enumValue)
    {
        return UnitTypeLabels[key: enumValue];
    }

    private static IDictionary<UnitType, string> UnitTypeLabels = 
        new Dictionary<UnitType, string>
        {
            { UnitType.APT  , "Apartment" },
            { UnitType.BOX  , "Box" },
            { UnitType.LOT  , "Lot" },
            { UnitType.PIER , "Pier" },
            { UnitType.RM   , "Room" },
            { UnitType.RR   , "Rural Route" },
            { UnitType.SLIP , "Slip" },
            { UnitType.ST   , "Street" },
            { UnitType.STE  , "Suite" },
            { UnitType.UNIT , "Unit" },
            { UnitType.WHARF, "Wharf" },
            { UnitType.WING , "Wing" }
        };
}

Perfect. Without adding too much code, requesting mapped labels is now a part of UnitType's API:

string label = UnitType.APT.GetLabel(); // label value is "Apartment"

Loading Persisted Null Values Into Objects with MyBatis

It almost makes sense: only invoke that setter if there's a value to invoke it with. But what about when a null value is meaningul? From org.apache.ibatis.executor.resultset.FastResultSetHandler:

  protected boolean applyPropertyMappings(ResultSet rs, ResultMap resultMap, List<string> mappedColumnNames, MetaObject metaObject, ResultLoaderMap lazyLoader) throws SQLException {
    boolean foundValues = false;
    final List<resultmapping> propertyMappings = resultMap.getPropertyResultMappings();
    for (ResultMapping propertyMapping : propertyMappings) {
      final String column = propertyMapping.getColumn();
      if (propertyMapping.isCompositeResult() || (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH)))) {
        Object value = getPropertyMappingValue(rs, metaObject, propertyMapping, lazyLoader);
        if (value != null) {
          final String property = propertyMapping.getProperty();
          metaObject.setValue(property, value);
          foundValues = true;
        }
      }
    }
    return foundValues;
  }

A javabean with a default value for one of its properties certainly won't benefit from this logic. Ignoring the persisted null will lead to an improperly reconstituted instance where the getter will return the assigned default value instead of null—not particularly helpful. What are the alternatives?

Reconstitute via a specialized constructor

On the one hand, this is a good place to enforce proper state when bringing the instance back, and writing a test against this setup would be a walk in the park. On the flip side, this will get ugly real fast as the realization that 30 args is a few too many sets in. And the lack of named parameters in Java won't help make those tests any more readable.

Don't assign default values in Javabeans

Given that MyBatis facilitates the DTO approach, we could fully embrace the idiom and dumb classes all the way down. The silver lining here is that defaults can be fully externalized into configuration, producing cleaner code along that particular axis.

Patch the framework to call mapped setters unconditioanlly

Not for the faint of heart. This will result in an overarching maintenance commitment to a third-party library. Perhaps submitting said patch to the framework developers will yield a fruitful bounty and usher in a new utopia for other programmers around the world. Or perhaps I should get back to actually producing tangible results today.

MyBatis Polymorphic Collections with Abstract Base Class

Problem

Straight from the MyBatis manual:

<!-- Very Complex Statement --> 
<select id="selectBlogDetails" parameterType="int" resultMap="detailedBlogResultMap"> 
  select 
    B.id as blog_id,
    B.title as blog_title, 
    B.author_id as blog_author_id, 
    A.id as author_id, 
    A.username as author_username, 
    A.password as author_password, 
    A.email as author_email, 
    A.bio as author_bio, 
    A.favourite_section as author_favourite_section, 
    P.id as post_id, 
    P.blog_id as post_blog_id, 
    P.author_id as post_author_id, 
    P.created_on as post_created_on, 
    P.section as post_section, 
    P.subject as post_subject, 
    P.draft as draft, 
    P.body as post_body, 
    C.id as comment_id, 
    C.post_id as comment_post_id, 
    C.name as comment_name, 
    C.comment as comment_text, 
    T.id as tag_id, 
    T.name as tag_name 
  from Blog B 
    left outer join Author A on B.author_id = A.id 
    left outer join Post P on B.id = P.blog_id 
    left outer join Comment C on P.id = C.post_id 
    left outer join Post_Tag PT on PT.post_id = P.id 
    left outer join Tag T on PT.tag_id = T.id 
  where B.id = #{id} 
</select>

<!-- Very Complex Result Map --> 
<resultmap id="detailedBlogResultMap" type="Blog">
<constructor> 
    <idarg column="blog_id" javaType="int"/>  
  </constructor><result property="title" column="blog_title"/> 
  <association property="author" column="blog_author_id" javaType=" Author"> 
    <id property="id" column="author_id"/> 
    <result property="username" column="author_username"/> 
    <result property="password" column="author_password"/> 
    <result property="email" column="author_email"/> 
    <result property="bio" column="author_bio"/> 
    <result property="favouriteSection" column="author_favourite_section"/> 
  </association> 
  <collection property="posts" ofType="Post"> 
    <id property="id" column="post_id"/> 
    <result property="subject" column="post_subject"/> 
    <association property="author" column="post_author_id" javaType="Author"/> 
    <collection property="comments" column="post_id" ofType=" Comment"> 
      <id property="id" column="comment_id"/> 
    </collection> 
    <collection property="tags" column="post_id" ofType=" Tag" > 
      <id property="id" column="tag_id"/> 
    </collection>
    <discriminator javaType="int" column="draft"> 
      <case value="1" resultType="DraftPost"/> 
    </discriminator> 
  </collection> 
</resultMap>

Unfortunately, if Post is abstract, using such a result map would cause exceptions to be thrown during object construction when a left join to the Post table yields missing records in the resultset.

The problem appears to be rooted in the usage of the null object pattern during construction from nested results, particularly an invocation of newInstance() on the type specified in the ofType attribute to produce a temporary placeholder. Of course, if that type happens to be abstract, you'll be seeing a strack trace sooner rather than later.

Solution

Given that the placeholder object is discarded when a more suitable match is available, what better object than an actual Object to fill this gap:

  <collection property="posts" ofType="object">

Problem solved.