Posts Tagged: Java


10
Feb 10

Avoid using nulls in Scala

Scala’s handling of null’s mixed with implicit casting is quite tricky. I learned the hard way today and it took hours to figure out what was going on. First I thought it was a bug, but then someone pointed out how implicit casting effect null method parameters.

The bottom line is: DO NOT USE NULLs unless you are utilizing java libraries and have no choice. Use Option instead, with Some() or None().

The problem is best described with code…

  def checkNullOrEmpty(v:Seq[Any]):Boolean = {
    println("Class:"+v.getClass)
    return (v != null) && !v.isEmpty
  }

  case class Race(val event:String, val protocol:String) {
    println("Event:"+event+", protocol:"+protocol)
    assert(checkNullOrEmpty(event))
    assert(checkNullOrEmpty(protocol))
  }

  val t = new Race(null, null)

Pasting the above into REPL yields the following result…

Event:null, protocol:null
Class:class scala.collection.immutable.WrappedString
java.lang.NullPointerException
    at scala.Proxy$class.toString(Proxy.scala:29)
    at scala.collection.immutable.WrappedString.toString(WrappedString.scala:22)
    at scala.collection.immutable.StringLike$class.length(StringLike.scala:48)
    at scala.collection.immutable.WrappedString.length(WrappedString.scala:22)
    at scala.collection.IndexedSeqLike$class.isEmpty(IndexedSeqLike.scala:81)
    at scala.collection.immutable.WrappedString.isEmpty(WrappedString.scala:22)
    at .checkNullOrEmpty(<console>:6)
    .....

So why is NPE thrown at this breakpoint return (v != null) && !v.isEmpty?

So let’s look further into the output. When a Race instance is created, the constructor values are initialized to null. Inside the constructor we print this out and verify that values are in fact null. When We get to checkNullOrEmpty method call, the class of v is WrappedString and though the object is no longer null. In Java the call to getClass would fail, as v would be null, in Scala it’s casted (converted) to WrappedString.

This happens through Scala’s implicit conversions. The checkNullOrempty method expects a Seq. Although Seq is not a superclass or interface of String. So when we create the Race instance and specify both event and protocol as null, they are still String types with a null reference. Using say event or protocol as an argument to checkNullOrEmpty yields an implicit conversion. Why? Well, in Java the compilation would fail, since the Seq trait is not a part of the inheritance hierarchy of String, but in Scala, it succeeds, as Scala finds an implicit conversion method to convert String to WrappedString. This method is defined in Predef object. We know the Predef is imported by default into all Scala classes. Predef extends LowPriorityImplicits class, which defines this implicit conversion implicit def wrapString(s: String): WrappedString = new WrappedString(s). So basically Scala decides that the best way to convert the String type into Seq[Any] is by using this implicit conversion. So it wraps the null value with the WrappedString.

This causes two issues… First, the not null check no longer works, as the object is not null, due to the fact that it’s an instance of WrappedString, so (v != null) is true. Since that passes, it then executes the RHS of && operator and then tries to infer on !v.isEmpty, which throws the NPE, as the underlying String value wrapped is null.

I’m not necessarily sure whether this is a bug, feature, or maybe there is no real consensus on how null should be handled, but as you see this causes issues and should either be avoided through avoiding null and using Option instead. If you are using java libs that return nulls, wrapping the return value in Option might be a good idea, before proceeding any further.


3
Feb 10

The start of the Scala journey (concurrency and idiomatic Scala rant)

I’ve been following Scala off and on for about 2 years now. Mostly in spurts, I liked the language, but due to the workload and other priorities I never had the time to take it for a full ride. Well, over the last 2 weeks, I decided to take the full plunge. Full meaning, I’m taking a highly concurrent production application which power’s a very critical component of our application, and rewriting it in Scala. I’m doing this for more than just fun. This application has grown from a very cleanly architected one, to one that is still rather nicely designed, but has accumulated a lot of technical debt. With everything I’ve learned about Scala, I think I can redesign it to be cleaner, more concise, and probably more scalable. The other big driving reason I’m looking to give Scala a shot, is due to its Actor based concurrency. I’ve worked with Java’s threading primitives for many years and have accumulated a love/hate relationship. The JSE 5 concurrency package brought some nice gems to my world, but it didn’t eliminate the fact that you’re still programming to the imperative model of shared state synchronization. Scala actors hide some of the ugliness of thread synchronization, though don’t eliminate the issue completely. Due to the nature of Scala, being a mix between imperative and functional language and the fact that actors are implemented as a library, nothing stops one from running into same issues as in more primitive thread state-sharing operations (i.e. race conditions, lock contentions, deadlocks/livelocks). Basically, if you’re using actors as just an abstraction layer over old practices, you’ll be in the same boat as you started with Java. With all of that said, unlike Java, Scala provides you the facilities for designing cleaner and more thread safe systems due to its functional programming facilities. Mutable shared state is the leading cause of non-determinism in Java concurrent applications, so immutability and message passing is a way into a more deterministic world.

I’ve also looked at other concurrent programming models, like STM/MVCC. STM is the basis of concurrent programming in Clojure and it’s a different paradigm than Actors. STM is a simpler model if you’re used to programming the old imperative threading, as they abstract you from concurrency primitives by forcing state modifications to occur in a transactional context. When this occurs, the STM system takes care of ensuring the state modifications occur atomically and in isolation. In my opinion this system suites the multi-core paradigm very well and allows smoother transition, the problem with it, at least in the context of MVCC, is that for each transaction and data structure being modified, a copy is made for the purposes of isolation (implementation of copying is system dependent, some might be more efficient than others), but you can already see an issue. For a system that has to handle numerous concurrent transactions involving many objects, this can become a bottleneck and the creation of copies can overburden system’s memory and performance. There are some debates about that in the STM world, mostly involving finding the sweet spot for such systems, where the cost of MVCC is less relevant the the cost of constant synchronization through locking.

Actors model is different, it works in terms of isolated objects (actors), all working in isolation by message passing. None can modify or query the state of another, short of requesting such an operation by sending a message to that particular object (actor). In Scala, you can break that model, as you can send around mutable objects, but if you are to really benefit from the Actor model, one should probably avoid doing that. Actors lend themselves better to concurrent applications, that not only span multiple-cores, but also can easily be scaled to multiple physical nodes. Because messages being passed are immutable data structures that can be easily synchronized and shared, the underlying Actor system can share these message across physically dispersed actors just as it can for the actors within the same physical memory space.

So the world of concurrency is getting more exciting with these awesome paradigms. One thing to remember is that there is no one size fits all concurrency model and I don’t see any one of the above becoming the de-facto standard any time soon. There is a sweet spot for each, so one should learn the ins and outs of each model.

Now that I got the concurrency out of the way, let’s get back to the actual syntax of Scala. Scala is very powerful (at least compared to Java). This power comes with responsibility. You can use Scala to write beautiful/concise programs, or you can use it to write obscure/illegible programs that no one, including the original author, will be able to comprehend. Personally, I prefer and can responsible handle this responsibility. I’m a long time Perl programmer (way before I started programming Java), and I’ve seen (and even written at times), programs that Larry Wall himself wouldn’t be able to comprehend.

Scala comes with operator overloading, but when not judiciously used, that power alone can be responsible for ineligibility of any system. This is one of the major reasons why languages like Java decided to not include it. Personally, I think operator overloading can be a beautiful addition to any API. It can make writing DSLs easier and using them more natural. Again, this power is great in the use of experienced and responsible programmers.

After having experience great power (Perl) and great restraint (Java), I’m leaning more towards power (who wouldn’t :-) . One one hand, it’s nice to be able to read and comprehend anyone’s Java program, even when it’s not nicely written, on the other hand, it’s a pain trying to write a program and jumping through all the hoops and limitations because of the various constraints. In a perfect AI world, the compiler would infer the capabilities of the programmer and restrict its facilities based on those, in some way as to not offend anyone:-) So if a novice is inferred, ah, there goes the operator overloading and implicit conversions, etc… But for now, I’d rather have a powerful tool to use when I write software and Scala seems to push the right buttons for me at this point.

I’m going to start of a list of posts, starting with this one, about my experiences with Scala.

Here is a little something I came up with a few hours ago. Our software has some limited interoperability with a SQL database and requires a light abstraction. We chose not to use any 3rd party ORM or SQL abstraction, mostly due to the fact that the dependency on these abstractions don’t really provide any benefit for our limited use of SQL. So I developed a simple SQL variant abstraction layer, which allows us to execute SQL queries which are defined in the SQLVariant implementation. Moving from one database to another, just requires one to implement a SQLVariant interface to provide the proper abstraction. I initially wrote this in java and although it was decent, it required quite a bit more code and didn’t look as concise as I wanted it. One issue was PreparedStatement and it’s interface for placeholder bindings. How would one bind java’s primitive and wrapper types as placeholders and how would the SQLVariant know which PreparedStatement.bind* method to call? I resorted to using an enumeration which defines these operations and reflection for the purpose of invoking these operations. I’m basically sidestepping static typing in a place I’m not sure I really want or have to. Here is the java implementation.

I got rid of a few methods, specifically dealing with resultset, statement, and connection cleanup, as they don’t really emphasize my point here.

  import java.lang.reflect.Method;
  import java.sql.*;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;

  public abstract class SqlVariant {

    public abstract SqlSelectStatement getResultsNotYetNotifiedForStatement(NotificationType... types);

    public abstract SqlSelectStatement getResultsNotYetNotifiedForStatement(int limit, NotificationType... types);

    public abstract SqlUpdateStatement getUpdateWithNotificationsForStatement(Result result);

    private abstract static class SqlStatement<T> {

      protected String sql;
      protected List<BindParameter> bindParams = new ArrayList<BindParameter>();
      protected PreparedStatement stmt;

      public SqlStatement(String sql) {
        this.sql = sql;
      }

      public SqlStatement addBindParam(BindParameter param) {
        bindParams.add(param);
        return this;
      }

      public String getSql() {
        return sql;
      }

      public List<BindParameter> getBindParams() {
        return Collections.unmodifiableList(bindParams);
      }

      protected PreparedStatement prepareStatement(Connection conn) throws SQLException {
        PreparedStatement stmt = conn.prepareStatement(sql);
        for (int bindIdx = 0; bindIdx < bindParams.size(); bindIdx++) {
          BindParameter p = bindParams.get(bindIdx);
          try {
            Method m = stmt.getClass().getMethod(p.type.method, Integer.TYPE, p.type.clazz);
            m.invoke(stmt, bindIdx + 1, p.value);
          }
          catch (Exception e) {
            throw new RuntimeException("Couldn't execute method: " + p.type.method + " on " + stmt.getClass(), e);
          }
        }
        return stmt;
      }

      public abstract T execute(Connection conn) throws SQLException;
    }

    public static final class SqlSelectStatement extends SqlStatement<ResultSet> {

      public SqlSelectStatement(String sql) {
        super(sql);
      }

      @Override
      public ResultSet execute(Connection conn) throws SQLException {
        return prepareStatement(conn).executeQuery();
      }
    }

    public static final class SqlUpdateStatement extends SqlStatement<Boolean> {
      public SqlUpdateStatement(String sql) {
        super(sql);
      }

      @Override
      public Boolean execute(Connection conn) throws SQLException {
        stmt = prepareStatement(conn);
        return stmt.execute();
      }
    }


    public static final class BindParameter<T> {
      private final BindParameterType type;
      private final T value;

      public BindParameter(Class<T> type, T value) {
        this.type = BindParameterType.getTypeFor(type);
        this.value = value;
      }

      public BindParameter(BindParameterType type, T value) {
        this.type = type;
        this.value = value;
      }
    }

    private static enum BindParameterType {
      STRING(String.class, "setString"),
      INT(Integer.TYPE, "setInt"),
      LONG(Long.TYPE, "setLong");

      private Class clazz;
      private String method;

      private BindParameterType(Class clazz, String method) {
        this.clazz = clazz;
        this.method = method;
      }

      private static BindParameterType getTypeFor(Class clazz) {
        for (BindParameterType t : BindParameterType.values()) {
          if (t.clazz.equals(clazz)) {
            return t;
          }
        }
        throw new IllegalArgumentException("Type: " + clazz.getClass() + " is not defined as a BindParameterType enum.");
      }
    }
  }

Now, here is how one would implement the SQLVariant interface. The below implementation is in groovy. I choose groovy when I have to do lots of string interpolation, which somehow java and scala refuse to support. The code was shortened to just demonstrate the bare minimum.

  class MySqlVariant extends SqlVariant {

    @Override
    public SqlVariant.SqlSelectStatement getResultsNotYetNotifiedForStatement(int limit, NotificationType[] types) {
      SqlVariant.SqlSelectStatement stmt = new SqlVariant.SqlSelectStatement("SELECT ...")
      for (NotificationType t : types)
        stmt.addBindParam(new SqlVariant.BindParameter(String.class, t.name().toUpperCase()))
      return stmt;
    }

    @Override
    public SqlVariant.SqlUpdateStatement getUpdateWithNotificationsForStatement(Result result) {
      SqlVariant.SqlUpdateStatement stmt = new SqlVariant.SqlUpdateStatement("INSERT INTO ....")
      result.notifications?.each { Notification n ->
        stmt.addBindParam(new SqlVariant.BindParameter(SqlVariant.BindParameterType.LONG, n.id))
        stmt.addBindParam(new SqlVariant.BindParameter(SqlVariant.BindParameterType.LONG, result.intervalId))
      }
      return stmt
    }

    ......
  }

I started reimplementing the above in Scala and I ran across a very powerful and beautiful Scala implicit conversion feature. This allowed me to truly abstract the SQLVariant implementations from any bindings specific knowledge, through an implicit casting facility that normally only dynamically typed languages provide. Scala gives us this ability, but also ensures static type safety of implicit conversions during compilation.

Another wonderful feature, is lazy vals, which allows us to cleanly implement lazy evaluation that we (java programmers) are so used to doing by instantiating a member field as null and then checking it before initializing on the initial accessor call. If you’ve seen code similar to below a lot, you’ll rejoice to find out that you no longer have to do this in Scala.

public class SomeClass {
  private SomeType type;

  public SomeType getSomeType() {
    if (type == null) type = new SomeType(); // Often more complex than that
    return type;
  }
}

The above, besides not being ideal, is also error prone if say a type is used anywhere else in SomeClass and you don’t use the accessor method to retrieve it. You must ensure the use of accessor through convention or deal with the fact that it could be non-instantiated. This is no longer the case in Scala as its runtime handles lazy instantiation for you. See below code.

Note: I still allow the client data access abstractions to work with a raw jdbc ResultSet returned from the SQLVariant. I don’t see this as an issue at this point, first since these abstractions are SQL specific and also because ResultSet is a standard interface for any JDBC SQL interaction. Here is my concise Scala implementation. I’m still learning, so this might change as I get more familiar with Scala idioms and start writing more idiomatic Scala code.

  import javax.sql.DataSource
  import java.sql.{ResultSet, Connection, PreparedStatement}
  import com.bazusports.chipreader.sql.SqlVariant.{SqlSelectStatement, BindingValue}

  abstract class SqlVariant(private val ds: DataSource) {

    def retrieveConfigurationStatementFor(eventTag: String): SqlSelectStatement;

    protected final def connection: Connection = ds.getConnection
  }

  object SqlVariant {

    trait BindingValue {def >>(stmt: PreparedStatement, idx: Int): Unit}

    // This is how implicit bindings happen.  This is beauty, we can now
    // bind standard types and have the compiler perform implicit conversions
    implicit final def bindingIntWrapper(v: Int) = new BindingValue {
      def >>(stmt: PreparedStatement, idx: Int) = {stmt.setInt(idx, v)}
    }

    implicit final def bindingLongWrapper(v: Long) = new BindingValue {
      def >>(stmt: PreparedStatement, idx: Int) {stmt.setLong(idx, v)}
    }

    implicit final def bindingStringWrapper(v: String) = new BindingValue {
      def >>(stmt: PreparedStatement, idx: Int) {stmt.setString(idx, v)}
    }

    abstract class SqlStatement[T](conn: Connection, sql: String, params: BindingValue*) {

      // Ah, another beautiful feature, lazy vals.  Basically, it's
      // evaluated on initial call.  This is great for the
      // so common lazy memoization technique, of checking for null.
      protected lazy val statement: PreparedStatement = {
        val stmt:PreparedStatement = conn.prepareStatement(sql)
        params.foreach((v) => v >> (stmt, 1))
        stmt
      }

      def execute(): T
    }

    class SqlUpdateStatement(conn: Connection, sql: String, params: BindingValue*)
            extends SqlStatement[Boolean](conn, sql, params: _*) {
      def execute() = statement.execute()
    }

    class SqlSelectStatement(conn: Connection, sql: String, params: BindingValue*)
            extends SqlStatement[ResultSet](conn, sql, params: _*) {
      def execute() = statement.executeQuery()
    }
  }

  /* Implementation of the SQLVariant */

  class MySqlVariant(private val dataSource:DataSource) extends SqlVariant(dataSource) {

    def retrieveConfigurationStatementFor(eventTag: String) =
      new SqlSelectStatement(connection,  "SELECT reader_config FROM event WHERE tag = ?", eventTag)

  }

And the obligatory unit test using the o’ so awesome Scala Specs framework.

  object MySqlVariantSpec extends Specification {
    val ds = getDataSource();

    "Requesting a configuration statement for a specific event" should {
      "return a SqlSelectStatement with properly bound parameters" in {
        val sqlVariant:SqlVariant = new MySqlVariant(ds)
        val stmt:SqlSelectStatement = sqlVariant.retrieveConfigurationStatementFor("abc")
        stmt must notBeNull
        // .... Other assertions go here
      }
    }
  }

Although I barely scraped the tip of the iceberg, I hope this helps you see some of what Scala has to offer. More to come as I progress.


5
Jan 10

Annoying javax.net.ssl.SSLHandshakeException exception

This exception has to be the most annoying one I’ve faced over the years with Java. I’m not sure which moron’s wrote the SSL library, but did they think about providing an option to disable ssl certificate validation? I wasn’t sure it was a requirement to have a valid certificate. I mean sure, it’s nice and provides that worm fuzzy security feeling, but when I’m developing and/or testing, can you please provide some way to disable this annoying thing? Either way, I dug into this today and figured it out. It’s actually as anything else in standard JDK, 100+ lines of code which they could of provided out of the box a simple boolean switch, instead your have to implement factories, interfaces, etc… WTF? Just to turn off certificate validation? Talk about over-engineering stuff.

So here is the code, which you can copy and paste into your project, instructions on how to use it are below…

import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;

import javax.net.SocketFactory;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public static class TrustAllSSLProtocolSocketFactory implements ProtocolSocketFactory {

    public static void initialize() {
        Protocol.registerProtocol("https", new Protocol("https", new TrustAllSSLProtocolSocketFactory(), 443));
    }

    private SSLContext sslcontext = null;

    private static TrustManager trustAllCerts =
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
                public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
            };

    /**
     * Constructor for TrustAllSSLProtocolSocketFactory.
     */
    private TrustAllSSLProtocolSocketFactory() {
        super();
    }

    private static SSLContext createSSLContext() {
        try {
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(null, new TrustManager[]{trustAllCerts}, null);
            return context;
        } catch (Exception e) {
            throw new HttpClientError(e.toString());
        }
    }

    private SSLContext getSSLContext() {
        if (this.sslcontext == null) {
            this.sslcontext = createSSLContext();
        }
        return this.sslcontext;
    }

    public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
            throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
    }


    public Socket createSocket(final String host, final int port, final InetAddress localAddress,
                               final int localPort, final HttpConnectionParams params
    ) throws IOException, UnknownHostException, ConnectTimeoutException {
        if (params == null) throw new IllegalArgumentException("Parameters may not be null");
        int timeout = params.getConnectionTimeout();
        SocketFactory socketfactory = getSSLContext().getSocketFactory();
        if (timeout == 0) return socketfactory.createSocket(host, port, localAddress, localPort);
        else {
            Socket socket = socketfactory.createSocket();
            SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
            SocketAddress remoteaddr = new InetSocketAddress(host, port);
            socket.bind(localaddr);
            socket.connect(remoteaddr, timeout);
            return socket;
        }
    }

    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(host, port);
    }

    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
            throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    public boolean equals(Object obj) {
        return ((obj != null) && obj.getClass().equals(TrustAllSSLProtocolSocketFactory.class));
    }

    public int hashCode() {
        return TrustAllSSLProtocolSocketFactory.class.hashCode();
    }
}

Now all you have to do is call TrustAllSSLProtocolSocketFactory.initialize() anywhere in your application initialization code or right before you access any https resources, either through the URL class or through any other library, like HttpClient.

Hope this helps, though it’s still a pretty ugly hack IMO.


26
Oct 09

Java multiple class loaders issue

I was facing a rather subtle bug building a decision engine using Drools. Not to get into details of drools here, but the following mostly applies to many rules engines. The basic architecture of the decisions engine is that rules are written using a drools-based rule DSL. These rules are then applied to “facts”, which in the context of java, are just POJOs. These POJOs can be defined using standard java classes, or using Drools declare facilities which allow you to declare fact types in the actual rules file and then query it using JavaBean like helper utilities in the java application. In our decisions engine, we allow to define types either using drools declare and/or using groovy to define the fact object, which is then parsed, defined, and linked by GroovyClassLoader at runtime, making it available to the working memory of the drools engine as well as its rule parser.

Everything seemed like it was working using Drools defined facts using declare. I was able to dynamically create and query the fact types using reflection. This was great, as we can inject different rules and deploy functionality on the fly. I then created a groovy class, parsed it and injected into the drools package builder as well as its working memory.

Code I used to test the rule inference on the fact type.

def domainClass = '''
  package com.buycentives.types
  import com.buycentives.incengine.*
  class Input {
    String name
    int age
    boolean valid
  }
'''
Class inputClass = new GroovyClassLoader().parseClass(domainClass)
def input = inputClass.newInstance()
input.name = "Ilya"
input.age = 25

/// Here we inject the fact and fire the rules, see the following java code snippet

// This code was originally failing
assertEquals input.valid, true

Here is the code I used to assemble the working memory. This code is more modularized in my code and I tried to compile it into a snippet, though I might of missed something and some object instantiations are not shown.

ClassLoader loader = new GroovyClassLoader()
PackageBuilderConfiguration config = new PackageBuilderConfiguration();
config.setClassLoader(loader);

KnowledgeBuilder kBldr = KnowledgeBuilderFactory.newKnowledgeBuilder(config);
kBldr.add(ruleResource, ResourceType.DRL);

if (kBldr.hasErrors())
  throw new RuntimeException("Unable to compile rules. " + kBldr.getErrors().toString());

KnowledgeBase kb = KnowledgeBaseFactory.newKnowledgeBase(new RuleBaseConfiguration(loader));
kb.addKnowledgePackages(kBldr.getKnowledgePackages());
StatelessKnowledgeSession kSession = kBase.newStatelessKnowledgeSession();
kSession.execute(factObject);

The rule that was being asserted

package com.buycentives.incengine.rules

import java.util.Date
import com.buycentives.types.Input

rule "Assert for age"
  when
    $input: Input( age >= 20, age < 30 )
  then
    $input.setValid(true);
end

To make the story short, the rule never fired, although I verified that the Input object instance was injected into the working memory, though never changing the fact’s valid property. I beat my head against the wall over and over and over and finally I realized what was going on. It’s java’s class loader caveat. It’s not really a bug, rather a feature I guess. It’s not really documented in the javadocs, but I’ve seen references to this caveat before.

When you load the same class using two different class loaders, inside the jvm, they are considered two different classes, although logically they are the same, therefore failing the Class.isAssignableFrom and instanceof conditional test.

So the following test would fail…

def domain = "class Test {}"

GroovyClassLoader loader1 = new GroovyClassLoader()
Class clazz1 = loader1.parseClass(domain)

GroovyClassLoader loader2 = new GroovyClassLoader()
Class clazz2 = loader2.parseClass(domain)

assertTrue clazz1.isAssignableFrom(clazz2)

So the lesson here, beware of injecting class loaders, especially when you’re comparing classes that were loaded with a different class loader than the class loader of the thread that’s inferring equality.

Also, beware of GroovyClassLoader.parseClass method. It parses, defines, and links the class, but if you then use it again on the same class, the resulting classes are different.

The following test fails…

GroovyClassLoader loader = new GroovyClassLoader()
Class clazz1 = loader.parseClass(domain)
Class clazz2 = loader.parseClass(domain)

assertTrue clazz1.isAssignableFrom(clazz2)

Also, this link from “Java Specialist Newsletter” is a good source of some interesting class loader information.


7
Sep 09

Grails multi-control property editor implementation

Data binding using current frameworks, Spring, Grails, etc… usually provide a way to marshal/unmarshal input control data into data types. The frameworks usually transparently handle the most common datatypes and allow you to configure/implement others. That process is pretty straightforward and in many cases trivial. When using Spring MVC, for example, one would extend java.beans.PropertyEditorSupport and implement the setAsText and maybe getAsText methods.

I think this handles a large portion of data bindings in web applications, but there wasn’t (at least in frameworks I worked with), a straightforward/reusable way of binding multiple html fields to one data type. I’ve always either had to roll my own custom solution and/or rely on a command (transfer) objects to have a one to one representation of form fields, which I would then bind to the domain object inside a controller action. Some use cases can really benefit from command objects and its decoupling from the domain, but I try to bind directly to domain objects as much as I can, reducing the amount of noise that transfer objects generate. Another solution which I’ve personally never implemented because I thought it was too ugly and leaked too much domain binding implementation into the view layer, was to use a hidden field and then format the multi-field controls into a single text value representation during a submit event, though allowing you to still have a one to one binding between the hidden control and the domain object field.

Today I discovered Grails StructuredPropertyEditor, and after figuring out how to implement it, I was on my way to reducing a bunch of binding boilerplate. This solution is not documented, as many other grails related intricacies, though it does seem like a stable/supported API. After digging through the source code, I figured it out and wanted to share it. So here it is…

I have a form which collects date and time information. The date uses a custom datepicker control and the time uses a custom time control. So two controls, that I need to marshal into one DateTime field in my domain class.

We start off by implementing a custom property editor, which extends PropertyEditorSupport and implements a grails specific StructuredPropertyEditor interface. I decided to use an excellent DateTime implementation class which comes with Joda Time library to store the date/time information. You can easily use any other type of your liking, including the java.lang.Date class.

  public class DateTimePropertyEditor extends PropertyEditorSupport implements StructuredPropertyEditor {

    DateTimeFormatter dateTimeFormat;

    public DateTimePropertyEditor(String format) {
      this.dateTimeFormat = DateTimeFormat.forPattern(format);
    }

    public List getRequiredFields() {
      List requiredFields = new ArrayList();
      requiredFields.add("date");
      return requiredFields;
    }

    public List getOptionalFields() {
      List optionalFields = new ArrayList();
      optionalFields.add("time");
      return optionalFields;
    }

    public Object assemble(Class type, Map fieldValues) throws IllegalArgumentException {
      if (!fieldValues.containsKey("date")) {
        throw new IllegalArgumentException("Can't populate a date without a year");
      }

      String date = (String) fieldValues.get("date");

      try {
        if (StringUtils.isBlank(date)) {
          throw new IllegalArgumentException("Can't populate date/time without a date");
        }
        String time = (String) fieldValues.get("time");
        if (StringUtils.isBlank(time)) time = "00:00 AM";
        String dateTime = date + " " + time;

        return dateTimeFormat.parseDateTime(dateTime);
      }
      catch (Exception nfe) {
        throw new IllegalArgumentException("Unable to parse structured DateTime from request for date.");
      }
    }

  }

Now that we have the property editor defined, we should create a registrar to register it with the application.

  public class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {

      public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(DateTime.class, new DateTimePropertyEditor("MM/dd/yyyy hh:mm a"));
      }
  }

Now that we have both the property editor and its registrar, we have to declare the registrar bean in the spring beans resources file /grails-app/conf/spring/resources.groovy

  beans = {
    propertyEditorRegistrar(CustomPropertyEditorRegistrar)

    // .... other beans ....
  }

That’s it, we’re done. The only thing left to do is actually create the html controls. There are a few conventions that must be followed in order for the StructuredPropertyEditor to grab the right fields.

  1. You must have a hidden field that’s there pretty much to declare the name of the field you’re binding to and also to state that it’s a ‘struct’ field, which means it’s a structured control made up of various other controls.
  2. The second rule, is that the names of the sub-fields that you are using in StructuredPropertyEditor, in our case ‘date’ and ‘time’, have to be prepended with the field name. So if the field name is ‘myField’, the sub-fields would be prepended with ‘myField_’. In our case, the html inputs should be named ‘myField_date’ and ‘myField_time’.

Here is a GSP snippet…

  <g:hiddenField name="startTime" value="struct" />
  <g:textField name="startTime_date"/>
  <g:textField name="startTime_time"/>

Notice how the field we’re binding is ‘startTime’ and the sub-fields that make up the whole, are ‘startTime_date’ and ‘startTime_time’ linked to ‘date’ and ‘time’ fields used in the assembly of the final field.

Now, all you have to do in the controller, is bind as you usually would, in my case…

bindData(domainObj, params)

That’s it, quick and simple and you have reusable marshaling of multi-control data types.