Blog

Hibernate and invalid queries from empty lists

January 7, 2009 14:30 in Hibernate, Java, Technology

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.

Fun with initialization blocks

November 5, 2008 10:20 in Java, Technology

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.

Author Arthur Vlug - Comments No Comments - Link Link

Creating a Map in “Ruby-style” in Java

November 3, 2008 17:21 in Java, Technology

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

May 26, 2008 17:03 in Java, Technology

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

April 17, 2008 17:14 in Java, Technology

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.

Exporting Spring beans with XML-RPC

March 28, 2008 14:57 in Java, Technology

On a recent project I had to create an XML-RPC interface to some of the services we had in the business-layer of our application. The first thing to do is of course check out the Spring manual on remoting but to my surprise Spring doesn’t support XML-RPC natively. Googling for “Spring XML-RPC” I found a lot of blogposts and articles about integrating the Apache XML-RPC library with Spring, but part of them describe methods that just don’t work and others take a rather complicated approach where I would like to be able to just map a service-name to a Spring bean.

After this rather unsatisfactory search I decided to checkout how hard it would be to integrate Apache XML-RPC with Spring in the way I just described. The target is to be able to write something like the following Spring configuration to be able to export some services:

<bean name="serviceExporter" class="...">
    <property name="services">
        <map>
            <entry key="ExampleService" value-ref="exampleServiceBean" />
        </map>
    </property>
</bean>

Perry Nguyen has written a post about integrating Apache XML-RPC 3 with Spring but he has left some open ends in my opinion. His solution is like mine based on a map of beans to be used in a ProcessorFactoryFactory. The first step in handling an XML-RPC request is mapping the request to a simple controller:

public class XmlRpcController extends AbstractController {
    private XmlRpcServletServer server = new XmlRpcServletServer();

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse res) throws Exception {
        // Delegate the request to the XmlRpcServletServer
        server.execute(req, res);
        // And stop processing of the request
        return null;
    }

    @Required
    public void setMapping(XmlRpcHandlerMapping mapping) {
        server.setHandlerMapping(mapping);
    }
}

As you can see this is just a simple wrapper around the XmlRpcServletServer to pass the request and response to the execute method. Apart from that we have a mapping property to set the handlerMapping property on the server. The next step is to create our own mapping class to be able to map service-names to a class:

public class SimpleHandlerMapping extends AbstractReflectiveHandlerMapping {
    public void setServices(Map<String, Object> services) throws XmlRpcException {
        // Check parameter
        Assert.notNull(services, “Services map should not be null.”);

        // Setup a RequestProcessorFactoryFactory
        SimpleRequestProcessorFactoryFactory factory = new SimpleRequestProcessorFactoryFactory();

        // Register all service beans with the factory
        for (Object serviceBean : services.values()) {
        	factory.registerServiceBean(serviceBean.getClass(), serviceBean);
        }

        // Set the RequestFactoryFactory to be used for mapping
        setRequestProcessorFactoryFactory(factory);

        // Loop through the set
        Iterator<Entry<String, Object>> it = services.entrySet().iterator();
        while (it.hasNext()) {
            // Fetch from the map
            Entry<String, Object> entry = it.next();
            String serviceName = entry.getKey();
            Object serviceBean = entry.getValue();

            // Register service in the handler mapping
            registerPublicMethods(serviceName, serviceBean.getClass());
        }
    }
}

The input of this mapper is a simple Map of Strings and Objects describing the service-names associated with the objects (Spring beans). First we create a RequestProcessorFactoryFactory to be able to map classnames to Spring beans the code for this SimpleRequestProcessorFactoryFactory is given below. Then we register all services in the Map with the factory and set the factory to be used by the methods from our superclass.

The last step is to register all service-names with their respective classes using the registerPublicMethods method from our superclass. This tells Apache XML-RPC to register all public methods and call our SimpleRequestProcessorFactoryFactory to get a Factory returning the servicebean. This SimpleRequestProcessorFactoryFactory is based on a Map of Class and Objects to map the Class Apache XML-RPC asks for to a Spring bean:

public class SimpleRequestProcessorFactoryFactory implements RequestProcessorFactoryFactory {
    private Map<Class, Object> serviceBeans = new HashMap<Class, Object>();

    public RequestProcessorFactory getRequestProcessorFactory(Class pClass) throws XmlRpcException {
        // Get the serviceBean from the map
        final Object serviceBean = serviceBeans.get(pClass);

        // Check if the bean is actually found
        if (serviceBean == null) {
            throw new XmlRpcException(”Handler \”" + pClass.getCanonicalName() + “\” not found.”);
        }

        // Create a factory just returning the lookedup bean
        return new RequestProcessorFactory() {
            public Object getRequestProcessor(XmlRpcRequest pRequest) throws XmlRpcException {
                return serviceBean;
            }
        };
    }

    public void registerServiceBean(Class clazz, Object serviceBean) {
    	serviceBeans.put(clazz, serviceBean);
    }
}

And then just a few lines of XML to wire it all together:

<bean id="xmlRpcHandlerMapping" class="nl.celerity.example.xmlrpc.SimpleHandlerMapping">
    <property name="services">
        <map>
            <entry key="ExampleService" value-ref="exampleService" />
        </map>
    </property>
</bean>

<bean id="xmlRpcController" class="nl.celerity.example.xmlrpc.XmlRpcController">
    <property name="mapping" ref="xmlRpcHandlerMapping" />
</bean>

Where exampleService is of course the name of a Spring bean with some public methods to be exported. With these two simple helper classes and an extremely simple controller we have the ability to export Spring beans as XML-RPC services by just adding a simple line of XML configuration.