I am currently building a web-application using OSGI (HTTP Service) and Hibernate. I also use DWR for all the AJAX stuff in the application. DWR uses a special DWRServlet which handles the interaction of the browser with the server side. The other part of my application uses a global dispatcher servlet for all other servlet requests. This global dispatcher servlet also does the Hibernate transaction handling using a OpenSessionInView – Pattern. This means the dispatcher servlet begins, commits and rollback the transaction in case of an exception. This works well.
My problem until today was, that this kind of transaction handling was not working in my DWRServlet, because this is a servlet not under my control. My first approach was to create a new servlet which extens DWRServlet so that I could modify the behaviour , but that didn’t work completely, because DWR does not pass Exceptions to my servlet. DWR handles all exceptions, marshals them so that the Exception can be passed back to the browser to be displayed in your calling Javascript code. That means I cannot catch the exception in my custom servlet because it is already caught and handled. Damn!
So I debugged and digged through a complete DWR call and found the @GlobalFilter annotation. That seems to be exactly what I need. This annotation can be applied to a class and this class also needs to implement the AjaxFilter interface. DWR then applies all filters to each method call made through the DWRServlet. This class needs to be registered the same way as you register your other DWR annotated classes (e.g. the classes annotated with the @RemoteProxy or @RemoteMethod annotation)
So I came up with the following class which borrowed some code of the existing org.directwebremoting.hibernate.H3SessionAjaxFilter which does almost exactly what I need, except the rollback() of my transaction in case of an error.
@GlobalFilter
public class DWRFilter implements AjaxFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(DWRFilter.class.getName());
public Object doFilter(Object obj, Method method, Object[] params,
AjaxFilterChain chain) throws Exception {
SessionFactory sessionFactory = Activator.getSessionFactory();
Transaction transaction = null;
if (sessionFactory != null)
{
Session session = sessionFactory.getCurrentSession();
transaction = session.beginTransaction();
}
else
{
LOGGER.error("SessionFactory not initialized for this web application.");
}
Object reply = null;
try {
reply = chain.doFilter(obj, method, params);
if (transaction != null)
{
transaction.commit();
}
} catch (Exception e) {
LOGGER.error("Error while committing transaction in DWRFilter. Transaction will be rolled back now...",e);
if(transaction != null){
transaction.rollback();
}
throw new InvocationTargetException(e);
}
return reply;
}
}
This basically does exactly what I want and is basically something like the Open Session In View pattern for DWR and Hibernate. For each DWR call it is the following flow:
- begin transaction
- do work
- commit transaction
- or rollback transaction in case of an exception
This way I have a central place for my DWR-Transaction handling.
This is my first solution to this problem and maybe it doesn’t catch every scenario, e.g. especially when you are using special features of DWR like batch calls etc. I haven’t used those features and for my current features using simple calls it works very well.







SVN ignores file extension .so by default – which corrupted my build
I was just working on my currently OSGI project which is build with Eclipse PDE headless for multiple platforms.
The Eclipse Deltapack contains a launcher bundle (directory) called org.eclipse.equinox.launcher.gtk.linux.x86_1.0.200.v20090520 which contains a file called eclipse_1206.so.
This launcher bundle I also committed to my SVN repository for my headless build from the build machine.
I was wondering why my build was always broken and corrupt and I found out that in my SVN repository the eclipse_1206.so file was missing…and indeed it was NOT committed.
I first thought I made a mistake, so I removed and recommitted everything. And again, the eclipse_1206.so wasn’t there.
So I started googling and I found this which directed me to this. Apparently *.so files are igored by SVN by default even though there is no svn:ignore property set.
Solution:
In order to solve this I did the following:
As you can see the .so file extension is not defined anymore and suddenly .so files also show up in my SVN Commit Dialog (I am using svnX on MaxOSX).
This also explains a bit my most recent issue I was having with a broken Eclipse build.
I am not too sure if this is a good default by SVN to ignore .so files as those are shared objects in Unix Environments which are important for Multi Platform builds in my case. Anyway I found this out and solved the problem.