<< Previous | Home | Next >>

How to do notifications after a JTA commit

I had trouble finding the solution to this by googling my requirements, for some reason. I actually had to RTFM to figure it out :-(

The problem:

You have a @Stateless EJB that uses container-managed transactions to do stuff. When a transaction has committed you want to notify other parties to inform them that updates have been made. I used to make use of JMS for this, but that is truly overkill and JMS and I are no longer friends anyway. JMS is like the Post Office, you don't want to rely on them for important things like notifications.

Here is how it's done:
    import javax.transaction.*;

...

@Resource
TransactionManager tm;

public void doMyUpdate() {
reallyDoMyUpdate();
try {
tm.getTransaction().registerSynchronization(new Synchronization() {
public void beforeCompletion() {}
public void afterCompletion(int status) {
if (status == Status.STATUS_COMMITTED) {
notifyAllMyFriends();
}
}
});
} catch (RollbackException ignore) {
logger.fine("Not done due to setRollbackOnly");
} catch (Exception e) {
throw new RuntimeException(e);
}
}

According to the specs this feature is meant to be used by the application server, but since it's so useful I can't see why anyone would ever be so heartless as to deprive poor ordinary proletarian applications of this. Anyway it works in Apache TomEE and I hope it will keep on working...

Note: when I implement "notifyAllMyFriends" as an @Asynchronous call, the above provides all the features that I previously used JMS for, with all the unnecessary extra fat removed!

Goodbye Subversion, hello Fossil

Today I made my final commit to the Subversion repository that I have been using for my main coding work for the past 8 years. That repository was created on October 30, 2004, and it has been through two server changes, two changes of corporate ownership, and an unknown number of software upgrades since then. There was actually a prehistoric CVS repository on yet another server where everything started in the summer of 2003, but the change history from CVS was never imported to Subversion. I forget exactly why, but I think there was some problem with the conversion script, so only the final CVS revision was imported.

My reason for abandoning Subversion is much the same as for many other people: there are distributed version control systems available today that are much more powerful than a centralized system. This is useful even when working alone, if you are like me and do development work on more than one computer.

To replace Subversion I settled on Fossil, written by Richard Hipp (who is coincidentally the author of the most widely deployed database software in the world, SQLite).

Here are the things I like about Fossil:
  • It's lightweight and very easy to install, and comes with a built-in web GUI, issue tracking system, and wiki.
  • All changes are transactional, through the use of a database engine with a proven track record.
  • And of course, it's a distributed repository. Like any distributed version control system this gives us:
    • No mandatory single point of failure.
    • No round-trip to the server is needed to view the change log or for using blame/annotate features.
    • Enables new powerful features like bisect.
    • Allows offline work.
There are some things I liked about Subversion that I will probably miss:
  • Having global revision numbers is much more pleasant than those horrible UUIDs. But this is only possible due to having a centralized design, unfortunately.
  • The possibility to check out only a part of the whole source tree.
  • External modules, although the concept has some quirks.
  • WebDAV integration was cool, but I have to confess I didn't use it much.
Why not Git instead of Fossil, considering the enormous popularity of Git? Well, I have been briefly exposed to Git used for "read-only" purposes, i.e. downloading and tracking code from various open source projects, and I have only had pleasant experiences with that. But when I tried to actually host my own code with Git, I quickly got frustrated. For that kind of use, Git has a much longer learning curve than Fossil. Also when looking at the differences in design, Git seems to be more targeted towards code maintainers in huge projects with many contributors, rather than towards developers. I also found it harder to approach an understanding of the Git design. In part this is probably due to feature creep and lack of distinction between conceptual model and implementation detail. This could of course be alleviated by the use of tools like EasyGit, but why bother if Fossil already has everything I need (including web hosting, issue tracker, and GUI) from the outset, all bundled in a single executable?

Linux ptrace and jmap

This is just a note to myself, and to any others who may have run into the same issue as I did.

After switching some Java servers over from the previous Ubuntu LTS release (10.04) to the latest one (12.04), I noticed that the "jmap" command had stopped working. For example, "jmap -heap 4711" aborted with
    Attaching to process ID 4711, please wait...
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process
It turns out a new security feature has been enabled in the Linux kernel a while ago. The system call "ptrace" is now only allowed from the parent of the process. This makes things like jmap useless, since the target process is never a child of the jmap process. Fortunately the feature can be disabled. Just do the following as root:
    # echo 0 > /proc/sys/kernel/yama/ptrace_scope
Now you can use jmap as before.

If you want to disable it permanently, put the following line in /etc/sysctl.conf:
    kernel.yama.ptrace_scope=0
This will disable it every time the system boots.