Fluent Interface for Regular Expressions

Some years ago when we migrated Radeox - a wiki engine - to a new Regular Expression engine, we had to change lots of Regular Expressions. Today I would do it in a different way, with Fluent Interfaces. Joshua has a solution for building Regular expressions with a Fluent Interface, about which I wrote before.

Regex socialSecurityNumberCheck = 
  new Regex(Pattern.With.AtBeginning 
    .Digit.Repeat.Exactly(3) 
    .Literal("-").Repeat.Optional 
    .Digit.Repeat.Exactly(2) 
    .Literal("-").Repeat.Optional 
    .Digit.Repeat.Exactly(4) 
    .AtEnd);

Not only is this solution easier to understand than using a String for regular expressions, migrating from ORO Regex to JDK Regex for example would be easy with this solution. The solution we chose was to create two engine implementations for ORO and JDK regex: Compiler (JdkCompiler,OroCompiler), MatchResult (JdkMatchResult,OroMatchResult), Matcher (JdkMatcher,OroMatcher) and so on. For example:

public class OroCompiler extends Compiler {
  private Perl5Compiler internalCompiler;

  private boolean multiline;

  public OroCompiler() {
    this.internalCompiler = new Perl5Compiler();
  }

  public void setMultiline(boolean multiline) {
    this.multiline = multiline;
  }

  public Pattern compile(String regex) {
    org.apache.oro.text.regex.Pattern pattern = null;
    try {
      pattern = internalCompiler.compile(regex,
         (multiline ? Perl5Compiler.MULTILINE_MASK : Perl5Compiler.SINGLELINE_MASK) | Perl5Compiler.READ_ONLY_MASK);
    } catch (MalformedPatternException e) {
      // handle later
    }

    return new OroPattern(regex, multiline, pattern);
  }
}

The actual regular expressions are stored in Java .properties files, to make them easily exchangable. The bold expression looks like this for example:

filter.bold.match=(^|>|[\\p{Punct}\\p{Space}]+)__(.*?)__([\\p{Punct}\\p{Space}]+|<|$)

With the migration of Radeox to a new regex implementation I had to write and implement several interfaces and it wasn't very easy to both support ORO and the JDK implementation. It wan't easy either to change the slightly different pattern dialact from ORO to JDK. With a Fluent Interface, just change the Fluent Interface, no need to think about different Java Regex APIs and to think about different syntaxes.

Thanks for listening.

Java and Apple: Fallen from love

As several people have written before, there is no Java 1.6 in the new Mac OS. What a stupid move. At most developer conferences concerning Java people have been and are using Apple laptops. Now in the last release, Leopard, Apple doesn't even mention Java any more. But the page shouts "Work in a developer's dreamland." They said this some years ago about Java. Now it's Ruby on Rails. Apple not even once mentions Java on their feature page, but "Leopard is the perfect platform for Ruby on Rails development, with Rails, Mongrel, and Capistrano built in." Don't they know the Rails hype is over? Really. It is. That the enterprise will move to Grails, if they have need for a dynamic lanugage? And move to Scala, when they want to innovate? And that today most big RoR applications are into legacy land. Funny that three companies with Ruby on Rails recently offered me CTO jobs - I guess you have to bring in some maintenance talent. Companies have to deal with new problems after some years of RoR. That's another story. Back to Java. There are so many more companies buying Apple laptops for Java development than for Rails development. And as Alex said:

"But my boss has said that if Macs don’t support Java 6, moving forward it’s just not going to be an option anymore. We need to run and test with Java 6 and not having access to it is a big issue."

There is so much more interest in Java than in Rails. But I guess we should have seen this coming with a Steve Jobs quote like: "“Java’s not worth building in. Nobody uses Java anymore. It’s this big heavyweight ball and chain.”.

Our love was nice. I fear it's over. "Love takes hostages. It gets inside you. It eats you out and leaves you crying in the darkness." Together with my current burned and smoking MacBook Pro power adapter, which they didn't want to take back, my love for Apple decreased a lot (don't mention the broken batteries in several iBooks and MacBooks). Rant over.

Thanks for listening.

Update: Yes, I know about the inaccurancies of Google trends, especially when you do not hit the right search terms. So one needed to include RoR, or perhaps even Ruby. In this case though, looking at the long, declining, but flat line of Java I think the search term “Java” more reflects the language than the island, there are no big spikes which should be there when it would reflect that people search that much for the island. Of course, this is debatable. But most often people confuse the “news” section of Google trends and the “search terms” section of Google trends. The one has nothing to do with the other. When you actually do a “Java” Google search, there is no hit for Java as an island on the first several pages.

Graeme – the Grails bug buster

While testing Reposita with the Grails repository, I was amazed about Graeme who is the Grails project lead and recently became the CTO of G2One.

Scanning the Grails subversion commits and searching for bug fixes, Graeme seems to be a very very active bug buster. One in four commits is a bug fix. Perhaps this directly contributes to the Grails success story. I hope he keeps up fixing bugs, now that he's CTO.

See for yourself:

Graeme and Bugs

More Hibernate JPA troubles

When running JPA together with Grails (not tested on it's own), with a Hibernate ORM either Hibernate, or with a pool the pool (c3p0), runs out of connections. The architecture of Reposita has a Grails frontend with a (Java) JPA backend to enable switching the frontend and backend independently. The MySQL database barks about to many connections. I do some persist() calls to the database, I guess around 50. Each call gets an EntityManager, does a transaction and closes the EM. Shouldn't closing the EM close the connection and return it to the pool? Or is this a problem together with Grails, which also runs Hibernate to a MySQL database? Any ideas? I've run out of mine.

Update: I'm not sure what I'm doing wrong,

em = getEntityManager();
em.getTransaction().begin();
em.persist(entity);
em.getTransaction().commit();
...
em.close();

should work. But even when using with c3p0 as a pool, when calling this code several times, the connection count to the database increases until it reaches the limit, where the MySQL database barks about too many connections.

This might be caused by create-drop of my testing setup.

Update 2: As Dirk pointed out, of course em.close() should go into a finally block and I might add there should be some exception handling and rollback() action.