Posts Tagged: java


12
Nov 09

When JBoss Seam Fails

seamYesterday I wrote about Ruby on Rails and what happens when programmers make common (typing) mistakes in their programs. It seems to have hit a nerve.

A number of Java and C# programmers sat back and enjoyed the show. "See what happens when you don’t have static typing in your language? In your face, smug Ruby on Rails sons of guns!"

Indeed, statically typed language fans often argue that many such common mistakes, such as misspelled variable, method, type and field names are found much faster: at compile time — hell, with Eclipse almost as you type! And this is definitely true. However, errors are only found within Java code. Modern web applications are built using a number of domain-specific languages that interact with Java in various ways – JSF, regular expressions, SQL or HQL and various sorts of XML configuration files. Once Java start interacting with other languages, things start going wrong and static typing is no longer helpful.

In this article I demonstrate this problem by showing examples of code built using JBoss Seam, a modern Java framework for developing web applications. Seam is essentially glue to put a number of popular Java frameworks together in a developer-friendly manner. It relies on frameworks and technologies such as Hibernate, JSF and EJBs. Interaction between the languages are very error prone, it turns out. Other Java frameworks, such as the Spring framework have similar issues. People say the Play Framework does a better job. So play framework people, if you’re listening (and I know you are), if you’re still so confident about yourself after reading this article, let me know, I’ll have a good look at Play. But for now, let’s focus on JBoss Seam.

Like with Ruby on Rails, I will consider a number of easy to make mistakes, and see how the framework responds to it. These mistakes are exemplary of problems that Java frameworks like Seam have, even though they are based on a statically typed language. They cannot be used as a fair comparison to e.g. Ruby on Rails.

Mistake #1: Use non-existent property of a variable in a JSF page

Welcome #{user.nam}

The user object does not have a nam property, only a name property. As we compile our code, the compiler reports no errors. However, when we deploy and load the page we see:

seam-fail-1

Although the error is clear, it is left for us to figure out where this nam property is actually used. Apparently there is no compile-time checking of JSF pages against the backing Java beans they communicate with.

Mistake #2: Non-existent references to pages

Seam has a pages.xml file to control flow between pages under certain conditions. The page contains references to Java code (in #{…} expressions) and to views (.xhtml pages). However, neither of these are checked at compile time, so if we mistype a page name:

<page view-id="/home.xhtml" action=
"#{identity.isLoggedIn}">
    <navigation>
        <rule if="#{identity.loggedIn}">
            <redirect view-id="/man.xhtml"/>
        </rule>
    </navigation>
</page>

We are get a 404 Not found error.

seam-fail-2

Mistake #3: Faulty validation regular expression

Validation of data model properties based on regular expression can be defined using the @Pattern annotation. But what happens when the programmer puts in a syntactically invalid regular expression?

@Pattern(regex="^[\\w*$", message="not a valid username")
public String getUsername() {
   return username;
}

There is a ‘[‘ too many there. When the code is compiled, no error is found. However, when it is deployed to the application server, an exception with an enormous stack trace appears:

seam-fail-3

It’s clear there is a regex mistake here. Somewhere. But where exactly is very hard to pinpoint drowning in the trace.

Mistake #4: Making a mistake in a HQL query

The Java Hibernate framework uses its own variant of SQL, that is slightly higher-level than SQL. Queries are represented as strings, and only checked at runtime.

List existing = em.createQuery("select u.username from User like u where u.username=#{user.username}")
     .getResultList();

There is a mistake here because there should not have been a "like" there in that query. When the action is invoked, an exception is thrown with an even longer stack trace than before:

seam-fail-4

A similar exception occurs 7 times in the stack trace, only on a few location there is actually a reference to the location in the code where the problem occurred:

at org.jboss.seam.example.booking.RegisterAction.register(RegisterAction.java:40)

Bad.

Conclusion

Compared to Ruby on Rails, the ability to type check Java code is a nice feature and lets you find a certain kind of mistake very quickly — in an IDE such as Eclipse even as you type. This support rapidly degrades when moving outside the statically typed world of Java. As soon as the programmer has to jump to using strings, as is the case when using e.g. regular expression, SQL and HQL, the safe, checked world of Java comes to an end.

The only kind of checks that are performed in languages like Java are type checks. This also means that the only mistakes are found that are related to types and can be expressed in types. This gets you only up to a certain point in finding programming errors. In order to use regular expressions in Java, programmers have to encode them in strings; SQL queries are encoded in strings — compilers do not check strings. Strings are parsed and interpreted only at runtime, meaning problems only appear at runtime typically buried in an enormous stack trace. And that’s a big shame.

Next part in this series: When Scala DSLs Fail.


27
Oct 09

On the PIL

For the past few years I’ve wanted to do what most programmers dream of doing: design my own programming language. Do everything right what others have done wrong, find the perfect mix of Java, Python and Ruby. It was going to have dynamic with optional static typing, a super flexible syntax and meta programming facilities that would make Ruby look like a toy. However, the first decision you have to make when undertaking such a project was already problematic: what language am I going to implement this in, C? I don’t C that well, and frankly, I don’t really want to spend my time managing memory and chasing down pointers. So my best bets are the JVM (Java Virtual Machine) and the CLR (.NET). I have to choose. It’s really a decision I don’t want to make. But how can I make two implementations? I don’t have the resources to do that.

Another area I’m interested is databases, specifically non-relational databases (or NoSQL databases). Many such systems start to appear: CouchDB, SimpleDB, Google’s BigTable. A few months ago, the people from FriendFeed described how they built such a system on top of MySQL. A fascinating idea, I thought. I decided to experiment with this idea and implement such a library in Python. After a while, when I got more into Java I ported it to Java. But I was not happy with it, I wanted to write a library that was language agnostic, that could be used from Java, Python, but also from PHP and Ruby.

For the past two years, me and my colleagues have been working on WebDSL, a domain-specific language for rapidly building web applications. The application written in WebDSL is compiled to Java code and can then be deployed on any Java application server. It’s a cool project, but rather uninteresting for people who do not have access to Java hosting, as is the case for many amateur programmers, a group that I care about, because I was one of them for so long. So, during the summer of last year I started to work on a Python Google AppEngine back-end for WebDSL, which generated Python code that worked with AppEngine, rather than Java code. It tooks some effort, but I got it to work. Cool! WebDSL was now much more accessible to people, because you can use a free AppEngine account to host your applications!

Sadly, maintaining a separate Python back-end for WebDSL turned out to be a tedious job. At the moment there are two people who spend much of their time making changes to the Java back-end of WebDSL, while I work on different things. This means that in addition to my usual work, I also have to replicate all changes they make to the Java back-end to the Python back-end. In practice this didn’t happen, which rapidly led the Python back-end to be out of date. Similarly, the language that we use to implement WebDSL, Stratego/XT, can now also generate two languages: C and Java. However, these back-ends also have to be maintained. The parser that we use, SGLR, also has two implementations: C and Java, that also have to be maintained.

See the pattern?

Certain types of applications, libraries and code generators are conceptually platform-independent, but since we typically choose one platform to implement them for/on, we exclude all potential users that use different platforms.

Ideally, we would abstract from software platforms such as Java, .NET, PHP, Ruby, Javascript or Objective-C. Ideally, we’d write code in only one language, and magically translate programs written in this language to any other software platform out there.

pil

This is exactly what PIL attempts to do. PIL stands for Platform Independent Language. It’s a language mainly intended to be used by DSL compilers to more easily maintain multiple platform back-ends, but can also be used as an implementation language for building portable libraries and (parts of) applications. To kick this off, let’s have a look at "Hello world!" in PIL:

void main(Array<String> args) {
  println("Hello world!");
}

As you can see, PIL is a Java-style language and that’s on purpose. Java is a well-known language and PIL’s syntax and semantics are based on Java. We made some changes, however, to simplify and improve it here and there.

The PIL compiler can currently generate programs for three platforms: Java, Python and PHP 5. Soon, more languages will be added. We plan to add at least C# and Objective-C, but also others such as Javascript. But already you can write a library in PIL and generate a Java, Python and PHP implementation from it, which is pretty cool. So let’s assume you installed the PIL compiler and you use it on the "Hello world!" program I just showed:

$ pilc -i hello.pil -d php-out --php
[ pilc | info ] Now compiling: hello.pil
[ pilc | info ] Done with hello.pil

If we look in the php-out directory now, we will see one file: main.php:

<?php
require_once "pil/builtin.php" ;
function main ( $args )
{
   pil_println ( "Hello world!" ) ;
}
?>

Now let’s invoke it with the Java back-end:

$ pilc -i hello.pil -d java-out --java
[ pilc | info ] Now compiling: hello.pil
[ pilc | info ] Done with hello.pil

Now we end up with a java-out/application/Main.java file:

package application;

public final class
Main  

  public final static void main(String[] args)
  { 
    System.out.println("Hello world!");
  }
}

And last but not least for Python:

$ pilc -i hello.pil -d python-out --python
[ pilc | info ] Now compiling: hello.pil
[ pilc | info ] Done with hello.pil

and the result: python-out/main.py

import sys
import pil.builtin
import sets
import datetime
import time

def main(args):
    print str( "Hello world!" )

Of course, this is just a trivial example, but it works on real-life applications as well. I implemented a simple parser and interpreter for my dynamic programming language in PIL and both the Java and Python versions worked (the compiler could not generate PHP code then). Similarly I ported my FriendFeed-inspired layer on top of MySQL to PIL and got it to work with Java and Python as well. For WebDSL there is an experimental PIL back-end that can generate code for any PIL-supported platform.

In practice, porting an code written in PIL to a new platform is a bit more work than simply changing the --java switch to --php. Typically you also need a certain amount of platform APIs that are not built into the PIL base library of types. You need IO functionality, or database access for instance. To accomplish this you can use external classes. Here is a sample Database, external class (in the pil::db namespace/package):

external class pil::db::Database {
  new(String hostName, String username, String password, String database);
  pil::db::Connection getConnection();
}

For each platform, e.g. PHP, Java, Python you now need to make an implementation of this class, typically wrapping an existing API on that platform. I won’t go into the details here, but you can find more information and examples on the PIL website.

I’m sure you’re all excited right now and want to start playing with this immediately. There is a simple tarball available that includes the PIL compiler running on Java (5+). It also includes a number of wrapper scripts that enable you to use the PIL compiler as if it were an interpreter. The pil-java script, for instance, generates Java code for a given .pil file, compiles and then executes it. Similar scripts are included for Python and PHP. Don’t get confused here. The compiler needs Java to run, but can generate code in 3 different languages. There is also a native C version of the PIL compiler, which is faster, but also a little bit more complicated to install. The PIL compiler will also run on windows, but the wrapper scripts that are included will not (unless you run them in cygwin), but the scripts are simple so this should not be an issue.

The PIL manual is under construction. It is not nearly complete, but already contains a lot of useful information about the language. For support you can join our IRC channel at irc.freenode.net channel #pil, or e-mail me. Of course, PIL also has a twitter account.

After refactoring our build system a little bit and improving the PHP back-end to use the __autoload feature, I am going to work on an Objective-C back-end. Yes, we want to start generating iPhone applications. Objective-C is a bit of a challenge because on the iPhone it does not support garbage collection, which PIL assumes as a feature of its target platforms. But if I get it done, PIL and the DSLs we’re going to build on top of it may be a viable alternative to the ugly Objective-C language you have to use now. I’ll keep you posted on that.