The jQuery fromTemplate plugin
We started using the Micro-Templating concept by John Resig to separate HTML markup from Javascript code in JSON based applications like our online crm solution. This concept solves the problem of outputting ugly strings of HTML very nicely, but the original code snippit was a little hard to understand for those of us who are not Javascript Ninjas (a book by John Resig). To fix this I had created a simple jQuery plugin and refactored the code a little.
This resulted in the following easy to use plugin:
$("#someElement").fromTemplate("templateId", dataset)
Where templateId is the ID of the template element and dataset is a simple Javascript object with data to expose to the template. Because this might help others understand the Micro-Templating code a bit better and might be useful to other jQuery users I have just uploaded the code to github as jQuery-fromTemplate-plugin.
Hibernate and invalid queries from empty lists
Just to keep others from searching for a “proper” way to handle this case: I just found out that Hibernate generates invalid SQL (at least in MySQL) when you pass an empty (not null) list to Restrictions.in(). The error occured in a simple query that tried to lookup a list of records by id. The code was something like this:
public List<Thing> findRecordsByIds(final List<Integer> ids) {
return (List<Thing>) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
return session.createCriteria(Thing.class).add(Restrictions.in("thingId", ids));
}
});
}
And it failed with a SQLGrammarException (which should never occur when using the Hibernate Query API). The Hibernate project knows about this as seen in their JIRA, but a fix is not yet delivered. Of course an easy fix to my example is:
public List<Thing> findRecordsByIds(final List<Integer> ids) {
if(ids.size() == 0) return Collections.emptyList();
return (List<Thing>) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
return session.createCriteria(Thing.class).add(Restrictions.in("thingId", ids));
}
});
}
Which also uses another function everybody should know about: Collections.emptyList() which in contrary to Collections.EMPTY_LIST uses a simple form of type inference to create a List<Thing> instead of a raw List and avoids a compiler warning.
Eclipse crash in CompilerThread on 64-bits Java
The title describes it all, there is a bug in the Sun JVM version 1.6 update 5 and later versions that makes the CompilerThread in Eclipse crash on 64-bits systems. Bugreports have been filed for Eclipse and the JVM, but the problem is still not resolved with the recent 1.6 update 10 release.
To save anyone with the same problem a lot of time, a workaround is to add the following line to eclipse.ini:
-XX:CompileCommand=exclude,org/eclipse/core/internal/dtree/DataTreeNode,forwardDeltaWith
That stops Java Hotspot’s JIT compiler from compiling the problem-method and avoids the crash.
Fun with initialization blocks
After Tomas posted the article Creating a Map in “Ruby-style” in Java, I wanted to tell you a little more about the { } block notation, which is used in that article to create a HashMap object. It looked like this:
new HashMap() {{
put("name", "Tomas Salfischberger");
put("phone", "123456789");
put("room", "11b");
}};
The { } notation is called an “initialization block”. We can also see this notation in action in the following class:
public class Person {
protected int age;
// Initialization block
{
age = 30;
}
public Person() {
age = 40;
}
}
And you can feel it coming, the bonus-question here is: After creating a Person object, what is the value of the age field? You can try for yourself, or I can just tell you it will be 40. From that we can conclude that the init-block is executed before the constructor. If you check the documentation from Sun, you’ll find that init-blocks are indeed prepended to every constructor.
A new question arises: How could Tomas have used the put method in an init-block before the constructor of the HashMap has actually run? A more detailed look at the HashMap example reveals that what’s actually happening there, is the creation of a subclass of HashMap. This explains why the init-block runs after the constructor of HashMap: The init-block of the subclass is prepended to the constructor of the subclass, and the constructor of a subclass always runs after the constructor of its superclass.
A practical test confirms the following execution order of init-blocks and constructors:
- superclass init block
- superclass constructor
- your init block
- your constructor
You can also define multiple init-blocks, the runtime system guarantees they execute in the order that they appear in the source code. So all in all the init-blocks are a nice (and widely unknown) language feature which can be used to add general initialization to all constructors or in special cases to replace a no-argument constructor.
Creating a Map in “Ruby-style” in Java
With Ruby on Rails gaining popularity more and more people post comments about how awkward coding in Java (or .NET for that matter) is. Someone tried to explain why Java is this bad by explaining how PHP and Ruby can instantiate a Map of string and value pairs (called array in PHP). The syntax to define a Map in Ruby would be:
{
"name" => "Tomas Salfischberger",
"phone" => "123456789",
"room" => "11b"
}
And for PHP:
array(
"name" => "Tomas Salfischberger",
"phone" => "123456789",
"room" => "11b"
)
Now the problem with a lot of these comments is that most Java-critics can’t actually write proper Java code. There is, for example, the following method to instantiate the same Map in Java:
new HashMap() {{
put("name", "Tomas Salfischberger");
put("phone", "123456789");
put("room", "11b");
}}
It is true that there is a bit more typing involved, but how many seconds does this actually cost you? And what if you look at the extra information we have provided? In Java we have actually expressed that we need a HashMap and not for example a TreeMap. That is not just more typing because Java programmers like typing, it’s actually valuable information.
Another one which might be useful (but more widely known I guess?) is this function to create a List using the Java 5 varargs feature:
Arrays.asList("value1", "value2", "something else")
These are both just simple tricks to make a programmer’s life easier, unfortunately a lot of people don’t know about them. Let’s hope the lost Ruby souls will some day find out about the simple tricks in other languages 
Simple plugins with BeanShell scripts
I was looking for a way to add a simple configurable extension-point to an application. The target was to be able to write a few lines of code or configure a few properties to be able to setup custom-filters. Luckily the task was not to be executed by a user of the system, but by a programmer. The open source product of choice here was BeanShell.
Here is an example of the code used to execute a simple script and give it access to part of the service-layer of the application:
Interpreter interpreter = new Interpreter();
interpreter.set("log", log);
interpreter.set("xxxxService", xxxxService);
interpreter.set("yyyyService", yyyyService);
interpreter.set("inputObject", someObject);
interpreter.eval(script);
After which it is possible to write scripts in the BeanShell language (which is very much like Java) to modify the object inputted, or as in my case validate some business-rules by making a few service-calls.
Security implications of the Spring DataBinder
Today I was reviewing the security of a simple business application and found the following (simplified) controller:
public class UserEditController extends CancellableFormController {
protected SecurityService securityService;
protected ModelAndView onSubmit(...) throws Exception {
User user = (User)command;
securityService.updateUser(user);
return getSuccessView();
}
@Required
public void setSecurityService(SecurityService securityService) {
this.securityService = securityService;
}
}
At first sight this seems a very common form-controller to edit a User object. The problem lies here in the fact that the User object has a few properties like “expireDate” and “accessLevel”. Experienced Spring users might see the security-problem now, others should check out the documentation for a hint:
Note that there are potential security implications in failing to set an array of allowed fields. In the case of HTTP form POST data for example, malicious clients can attempt to subvert an application by supplying values for fields or properties that do not exist on the form.
If you don’t set the allowedFields or disallowedFields property the DataBinder will bind all HTTP-parameters to the domainobject so a malicious user could post an accessLevel property changing their own accessLevel. Of course setting allowedFields everywhere seems like a lot of work, but Spring has made this quite easy. From the documentation:
Register fields that should be allowed for binding. Default is all fields. Restrict this for example to avoid unwanted modifications by malicious users when binding HTTP request parameters.Supports “xxx*”, “*xxx” and “*xxx*” patterns. More sophisticated matching can be implemented by overriding the isAllowed method.
So with these patterns there is no excuse to not restrict the properties to be bound.
Maven tomcat:run and context.xml
I ran into a problem today: When using the command mvn tomcat:run (the maven tomcat plugin) to quickly run a Tomcat instance and edit some JSPs on the fly I noticed my application was unable to find it’s JNDI defined DataSource:
javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
But this DataSource is defined in the src/main/webapp/META-INF/context.xml default context file:
<Context>
<Resource name="jdbc/dbname" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="username" password="pass" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/dbname?autoReconnect=true"/>
</Context>
So I searched the web for other people with these kind of issues and found a few mailinglist questions (all unanswered) here and here. And finally found out that it is just not possible to use a context.xml with the tomcat:run goal as it is still an open issue in the codehaus JIRA: #MOJO-594. So I hope this might save someone some time searching for how to get tomcat to pickup the context.