Friday, February 5, 2010

Method calls through interface references are slower (on Android)

In the 2009 Google I/O talk about writing real-time games for Android http://developer.android.com/videos/index.html#v=U4Bk5rmIpic it is recommended that for performance we don't use interfaces. Supposedly the calls through an interface reference are about 30% slower. It is also mentioned that calls to static methods are faster.

In these circumstances, i asked myself if all calls to a non-direct reference are slower. I'm not an expert at low level stuff, but it looks to me that calling a method through a interface reference is about the same thing as calling a method through a reference to a parent class. But this would mean that we shouldn't use inheritance at all. And that, for someone like me that usually trades performance for scalability, it sounds crazy.

I decided to make a quick test to see if this is true. Here's the code I used: http://pastebin.com/m7c7c0043

First I ran it on my PC and I was stupefied to find results like these at every run:
Direct refference => 1,596,318,257
Parent refference => 1,550,725,582
Interface refference => 1,552,626,591
Static refference => 1,751,394,872

So the interface calls are about the same. Actually sometimes they were faster by a negligible amount.

Then I tested it in an Android application, using a HTC Hero Phone. (Note: I reduced the number of iterations from 1000000000L to 5000000L).
Results were something like:
Direct refference => 3,767,791,749
Parent refference => 3,477,020,264
Interface refference => 4,690,185,547
Static refference => 3,327,636,719

So the interfaces are slower. I can now confirm with my own test. I guess the virtual machine is quite different.
The good thing is that calls through parent references are not slower. Wohoo! OOP for life

Friday, November 13, 2009

Simulate bean initialization in GWT with GIN

I currently use Google-Gin in my project and I wanted a simple, clean way of calling an initialization method on some injected objects, right after all the properties have been set.
For Spring users, this would be the equivalent of afterPropertiesSet(). Up until now this hasn't been a problem as I was doing the injection in the constructor and I could call this method myself at the end of the constructor.
However, constructor injection and the GWT split points don't like each other so I need to do method injection (I like this better anyway).

After a bit of thinking, the simplest solution I've found is the following:


@Inject
public void setAll(A a, B b, C c) {
this.setA(a);
this.setB(b);
this.setC(c);
this.init();
}


You can do the same thing as in constructor. Instead of having multiple injected setters you can have a single injected method like above.

Saturday, August 8, 2009

Always read the comments

I've been using the db field identity and equals + hashCode override approach suggested in this article because the Hibernate official doc on equals seemed to have gaps.

However, I only recently read the comments on that article while doing a quick research on this subject. I seems that the Hibernate team is not happy at all with it. If you endure to read through the annoyed and dismissive responses they give (to be fair, I bed they have to repeat the same stuff to 1000 different dummy people so anyone would become dismissive), you'll find out that
you only have to override these methods if you use detached objects. And they feel there are much better alternatives to using detached objects.

This brings me in the position to reconsider if I'm using the right approach.

ALWAYS READ ALL THE COMMENTS DUMMY!

Thursday, August 6, 2009

Hibernate + Spring + TimerTask = No Hibernate Session bound to thread

I recently come across a problem in a Spring+Hibernate project when trying to execute an operation with a delay.

I had a service bean (let's say EntityService):
public class EntityService{
...
@Transactional(readOnly = false)
public void generateWithDelay(String id, long delay){
Entity e = new Entity();
e.setStatus("IN_CONSTRUCTION");
e.setId(id);
this.dao.save(e);
this.scheduler.addTask(id, delay, this);
}

@Transactional(readOnly = false)
public void finishGeneration(String id){
Entity e = this.dao.get(id);
e.setStatus("DONE");
this.dao.save(e);
}
....
}

I wanted to call generateWithDelay at a user action then after N seconds finishGeneration to be called.

I created a "Scheduler" an addTask method, that accepted the delay, the parameters of the call and a callback (for wich I created a SchedulerCallback interface that my service implemented).

Under the hood the scheduler would simply create a TimeTask than when the time passed it called the callback with the suplied parameters. This way the timerTask is as generic as possible and the finishGeneration is where it belongs in the entityService.

All nice and joly. generateWithDelay would work ok. It ads the entity in the DB and it starts the timer. However when the timer called the finishGeneration method I would get:

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.AbstractSession FactoryBean$TransactionAwareInvocationHandler.invo ke(AbstractSessionFactoryBean.java:300)


Obviously something is wrong with the transaction. A transaction never gets created before reaching the dao even thow finishGeneration is annotated with @Transactional. The annotation should work beacause it works just fine for generateWithDealy.

What to do? what to do? My first thought was that it's the source of the call that creates the problem. The hibernate transaction usually is the JPA transaction that the J2EE container provides. So if the call is not initiated by a user action the transaction might never get called. But I'm not running in a J2EE environment and I have:
<prop key="hibernate.current_session_context_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
<prop key="hibernate.transaction.factory_class">thread</prop>
so it can't be it.

As a first fix I solved this by programatically opening a transaction in the timerTask just before invoking the callback. With springs Transaction Template it's actually quite easy. After this little trick it works just fine.

Lucky for me I remained curious about why it won't work with declarative transaction. In the end I found the problem.

When I provide the callback to the scheduler I do:
this.scheduler.addTask(id, delay, this); 


As you know, in Spring the transaction is started by the proxy that wraps the entityService. However, because I use JDK proxies, this won't be the proxy, but the proxy target (the original service). So when the callback is invoked it bypasses the transaction mechanism completely. The trick is to provide the actual proxy to the scheduler. I did this by letting EntityService implement ApplicationContextAware and BeanNameAware and fetching the proxy from the applicationContext at initialization:

public class EntityService implements ApplicationContextAware, BeanNameAware, InitializingBean{
...
public void setApplicationContext(ApplicationContext ac){
this.ac = ac;
}
public void setBeanName(String beanName){
this.beanName = beanName;
}
public void afterPropertiesSet(){
this.myProxy = this.ac.getBean(this.beanName);
}
...
@Transactional(readOnly = false)
public void generateWithDelay(String id, long delay){
Entity e = new Entity();
e.setStatus("IN_CONSTRUCTION");
e.setId(id);
this.dao.save(e);
this.scheduler.addTask(id, delay, this.myProxy);
}

Sunday, June 21, 2009

Spring to solve GWT - Hibernate mess

Everybody knows that GWT and Hibernate don't get together too well. At least not when you're using GWT-RPC. That's because Hibernate changes your beans when you're using collections or properties/associations with lazy fetching and GwtRpc can't serialize those beans.

For example if one of your beans has a Set of other beans, when the bean will be fetched Hibernate will use it's PersistentSet implementation of Set. This implementation contains references to other complex Hibernate objects like the SessionFactory. So the serialization will fail even if your bean implements IsSerializable and follows all the serialization rules.

The common solution is to force all your GwtRpc services to return a deep-copy of the bean, instead of the bean itself. This way you can use the standard collection implementations and de-proxyfy any lazy-loading properties.

Monday, June 15, 2009

GWT Type 'package.class' was not serializable and has no concrete serializable subtypes

Uhh, these pages saved me a lot of trouble! Juri Strumpflohner's TechBlog: Strange GWT compiler error when trying to serialize Java objects, http://tom.jteam.nl/?p=6.

Note to self! don't you ever skip-read important pages as: http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&s=google-web-toolkit-doc-1-5&t=DevGuideSerializableTypes and http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&s=google-web-toolkit-doc-1-5&t=FAQ_RPCSerializationSupport

So basically in order to make a class gwt-serializable (the red lines were what caused my problems):
#1. It must implement com.google.gwt.user.client.rpc.IsSerializable. After GWT 1.5 you can also use java.io.Serializable.
#2. All non-final, non-transient instance fields are themselves serializable
#3. Prior to GWT 1.5, it must have a public default (zero argument) constructor or no constructor at all.
#4. As of GWT 1.5, it must have a default (zero argument) constructor (with any access modifier) or no constructor at all.
#5. Not all JRE classes that implement java.io.Serializable are gwt-serializable. In my case it was java.lang.Class