Version-Based Optimistic Concurrency Control in JPA/Hibernate

This article is an introduction to version-based optimistic concurrency control in Hibernate and JPA. The concept is fairly old and much has been written on it, but anyway I have seen it reinvented, misunderstood and misused. I’m writing it just to spread knowledge and hopefully spark interest in the subject of concurrency control and locking.

Use Cases

Let’s say we have a system used by multiple users, where each entity can be modified by more than one user. We want to prevent situations where two persons load some information, make some decision based on what they see, and update the state at the same time. We don’t want to lose changes made by the user who first clicked “save” by overwriting them in the following transaction.

It can also happen in server environment – multiple transactions can modify a shared entity, and we want to prevent scenarios like this:

  1. Transaction 1 loads data
  2. Transaction 2 updates that data and commits
  3. Using state loaded in step 1 (which is no longer current), transaction 1 performs some calculations and update the state

In some ways it’s comparable to non-repeatable reads.

Solution: Versioning

Hibernate and JPA implement the concept of version-based concurrency control for this reason. Here’s how it works.

You can mark a simple property with @Version or <version> (numeric or timestamp). It’s going to be a special column in database. Our mapping can look like:

@Entity
@Table(name = "orders")
public class Order {
	@Id
	private long id;

	@Version
	private int version;

	private String description;

	private String status;

	// ... mutators
}

When such an entity is persisted, the version property is set to a starting value.

Whenever it’s updated, Hibernate executes query like:

update orders
set description=?, status=?, version=?
where id=? and version=?

Note that in the last line, the WHERE clause now includes version. This value is always set to the “old” value, so that it only will update a row if it has the expected version.

Let’s say two users load an order at version 1 and take a while looking at it in the GUI.

Anne decides to approve the order and executes such action. Status is updated in database, everything works as expected. Versions passed to update statement look like:

update orders
set description=?, status=?, version=2
where id=? and version=1

As you can see, while persisting that update the persistence layer increments the version counter to 2.

In her GUI, Betty still has the old version (number 1). When she decides to perform an update on the order, the statement looks like:

update orders
set description=?, status=?, version=2
where id=? and version=1

At this point, after Anne’s update, the row’s version in database is 2. So this second update affects 0 rows (nothing matches the WHERE clause). Hibernate detects that and an org.hibernate.StaleObjectStateException (wrapped in a javax.persistence.OptimisticLockException).

As a result, the second user cannot perform any updates unless he refreshes the view. For proper user experience we need some clean exception handling, but I’ll leave that out.

Configuration

There is little to customize here. The @Version property can be a number or a timestamp. Number is artificial, but typically occupies fewer bytes in memory and database. Timestamp is larger, but it always is updated to “current timestamp”, so you can actually use it to determine when the entity was updated.

Why?

So why would we use it?

  • It provides a convenient and automated way to maintain consistency in scenarios like those described above. It means that each action can only be performed once, and it guarantees that the user or server process saw up-to-date state while making a business decision.
  • It takes very little work to set up.
  • Thanks to its optimistic nature, it’s fast. There is no locking anywhere, only one more field added to the same queries.
  • In a way it guarantees repeatable reads even with read committed transaction isolation level. It would end with an exception, but at least it’s not possible to create inconsistent state.
  • It works well with very long conversations, including those that span multiple transactions.
  • It’s perfectly consistent in all possible scenarios and race conditions on ACID databases. The updates must be sequential, an update involves a row lock and the “second” one will always affect 0 rows and fail.

Demo

To demonstrate this, I created a very simple web application. It wires together Spring and Hibernate (behind JPA API), but it would work in other settings as well: Pure Hibernate (no JPA), JPA with different implementation, non-webapp, non-Spring etc.

The application keeps one Order with schema similar to above and shows it in a web form where you can update description and status. To experiment with concurrency control, open the page in two tabs, do different modifications and save. Try the same thing without @Version.

It uses an embedded database, so it needs minimal setup (only a web container) and only takes a restart to start with a fresh database.

It’s pretty simplistic – accesses EntityManager in a @Transactional @Controller and backs the form directly with JPA-mapped entity. May not be the best way to do things for less trivial projects, but at least it gathers all code in one place and is very easy to grasp.

Full source code as Eclipse project can be found at my GitHub repository.

Spring: @EnableWebMvc and JSR-303

I’ve been happily using XML-free Spring with Web MVC, right until the moment when I wanted to plug in JSR-303 validation.

Failure

I imported validation-api and hibernate-validator to my project. I annotated code for my command:

public class SpendingCommand {
@Size(min=3)
private String category;
// ...
}

… and controller:

@Controller
public class SpendingEditionController {

@RequestMapping(value = "/spending_insert", method = RequestMethod.POST)
public String addSpending(@Valid SpendingCommand spending,
		BindingResult result, ModelMap model) {
	return "my_view";
}

// ...
}

I plugged it in to form:

#springBind("command.$field")
<label for="$field" class="control-label">${label}:</label>
<div class="controls">
	<input type="text" name="${status.expression}" value="$!{status.value}" />
	$!{status.errorMessage}
</div>

… and nothing happened.

I looked for errors in BindingResult in my controller, and nothing was there. Clearly validation was not working at all.

Almost There: @Valid Working

I read a ton of tutorials, and they did not mention any specific black magic. After a long while of doc reading, random trying and debugging, I found this StackOverflow answer. Skaffman said that <mvc:annotation-driven /> was “rather pointless” so “don’t bother”. Luckily I read comments to that answer as well and discovered that this is actually crucial for all the new goodies in Spring Web MVC, including conversions and validation.

I added annotation equivalent of mvc:annotation-driven to my view configuration:

@Configuration
@ComponentScan(basePackages = "pl.squirrel.money.web")
@EnableWebMvc
public class ViewConfig

When I tested my code again, I did see errors in BindingResult in my controller, so finally validation was working. Unfortunately, the web page still did not show the message. Do you know why?

Bindings and Naming Conventions

It took me even longer to figure this one out. I even began to suspect my custom view for Velocity Tools & Tiles.

Finally in debug I noticed I had my command bound twice in page context: as command and as spendingCommand. I had two bindings for BindingResult as well, but with two different instances! One was org.springframework.validation.BindingResult.command, with zero errors, and another was org.springframework.validation.BindingResult.spendingCommand, containing all errors as expected.

In a word, mess. To clean this up, I had to explicitly name my command like this:

@RequestMapping(value = "/spending_insert", method = RequestMethod.POST)
public String addSpending(@ModelAttribute("command") @Valid SpendingCommand spending,
		BindingResult result, ModelMap model) {
	return "my_view";
}

Now I only have one instance of everything, and everything is working as expected. And they lived happily ever after.

Quirks

In the end, I find it interesting (in a bad sense) that it works like this. I think it’s a bug that the same command is bound under two different names, but it’s quite the opposite for BindingResult.

To test it, I attempted to edit this SpendingCommand in controller by overwriting value of a field. At this point I knew what would happen: My web page showed overwritten value in form (because Spring was still able to match the command with different name), but no validation errors (because there are two different instances of BindingResult.

Spring & Velocity Tools (No XML)

A few months ago I wrote about integrating Spring, Velocity and Tiles. I discovered that one bit was missing from there: Velocity Tools. Two hours of yak shaving, frantic googling and source reading later, I figured out how to add support for Velocity Tools to such project with no XML configuration. Here’s how.

For starters, let’s say I want to use some tools in my Velocity and Tiles pages. Let’s add the LinkTool.

template.vm:

<html>
	<head><title>#tiles_insertAttribute({"name":"title"})#end</title></head>
	<body>
		#tiles_insertAttribute({"name":"body"})#end
		<p>Spring macros work in tiles template, too: #springUrl("/myUrl")</p>
		<p>Do Velocity tools work in template? $link.contextPath</p>
	</body>
</html>

body.vm:

<p>Here's a demonstration that Spring macros work with Tiles: #springUrl("/myUrl")</p>
<p>Do Velocity tools work in Tile? $link.contextPath</p>

When I render the code from previous post, I get this:

Here's a demonstration that Spring macros work with Tiles: /SpringVelocityTiles/myUrl

Do Velocity tools work in Tile? $link.contextPath

Spring macros work in tiles template, too: /SpringVelocityTiles/myUrl

Do Velocity tools work in template? $link.contextPath

Not good.

After some googling, I found a similar question on StackOverflow. It had two helpful answers – one from serg, delegating to this blog post, and another from Scott.

None of them worked out of the box, though. I’m tired of XML configs, and apparently it’s too easy to get weird exceptions related to some Struts tools. No wonder I get them, I don’t use Struts and don’t want any of its tools!

Apparently the issue is that Spring support for Velocity Tools is rubbish. One way out is to write your own ViewResolver or View, and that’s what I did in the end.

For starters, I’ll configure my ViewResolver to use a new view class:

@Bean
public ViewResolver viewResolver() {
	VelocityViewResolver resolver = new VelocityViewResolver();
	resolver.setViewClass(MyVelocityToolboxView.class);
	resolver.setSuffix(".vm");
	return resolver;
}

MyVelocityToolboxView is below. This time I’m pasting it with imports to avoid ambiguity on names like Context or VelocityView.

package pl.squirrel.svt;

import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.context.Context;
import org.apache.velocity.tools.Scope;
import org.apache.velocity.tools.ToolboxFactory;
import org.apache.velocity.tools.config.ConfigurationUtils;
import org.apache.velocity.tools.view.ViewToolContext;
import org.springframework.web.servlet.view.velocity.VelocityView;

public class MyVelocityToolboxView extends VelocityView {
	@Override
	protected Context createVelocityContext(Map<String, Object> model,
			HttpServletRequest request, HttpServletResponse response) {
		ViewToolContext context = new ViewToolContext(getVelocityEngine(),
				request, response, getServletContext());

		ToolboxFactory factory = new ToolboxFactory();
		factory.configure(ConfigurationUtils.getVelocityView());

		for (String scope : Scope.values()) {
			context.addToolbox(factory.createToolbox(scope));
		}

		if (model != null) {
			for (Map.Entry<String, Object> entry : (Set<Map.Entry<String, Object>>) model
					.entrySet()) {
				context.put(entry.getKey(), entry.getValue());
			}
		}
		return context;
	}
}

It’s important that we only use ConfigurationUtils.getVelocityView() – it includes generic tools and view tools, but not Struts tools.

That’s it, now we have a project which uses Tiles for high-level templating, Velocity for individual pages and details, with (hopefully) full support for Spring macros and Velocity tools in all areas. Even if you don’t like Tiles, it may still serve as a good example of how to integrate Spring and Velocity Tools.

I pushed updated code for the demo application to my GitHub repository.

In the irregular habit of posting a sermon on Friday… Less than a week ago I saw an excellent presentation on using Clojure for Spring views. Compared to all this mess and yak shaving here, that Clojure solution is infinitely simpler, more elegant and more powerful at the same time. Too bad it does not have the market share of Spring & Velocity yet.

Testing Spring & Hibernate Without XML

I’m very keen on the improvements in Spring 3 that eventually let you move away from XML into plain Java configuration with proper support from IDE and compiler. It doesn’t change the fact that Spring is a huge suite and it sometimes finding the thing you need can take a while.

XML-free unit tests around Hibernate are one such thing. I knew it was possible, but it took me more than 5 minutes to find all the pieces, so here I am writing it down.

I am going to initialize all my beans in a @Configuration class like this:

@Configuration
@EnableTransactionManagement
public class TestRepositoryConfig {
	@Bean
	public DataSource dataSource() {
		return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
				.setName("Nuts").build();
	}

	@Bean
	public LocalSessionFactoryBean sessionFactoryBean() {
		LocalSessionFactoryBean result = new LocalSessionFactoryBean();
		result.setDataSource(dataSource());
		result.setPackagesToScan(new String[] { "pl.squirrel.testnoxml.entity" });

		Properties properties = new Properties();
		properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
		result.setHibernateProperties(properties);
		return result;
	}

	@Bean
	public SessionFactory sessionFactory() {
		return sessionFactoryBean().getObject();
	}

	@Bean
	public HibernateTransactionManager transactionManager() {
		HibernateTransactionManager man = new HibernateTransactionManager();
		man.setSessionFactory(sessionFactory());
		return man;
	}

	@Bean
	public OrderRepository orderRepo() {
		return new OrderRepository();
	}
}

… and my test can look like this:

@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(defaultRollback = true)
@ContextConfiguration(classes = { TestRepositoryConfig.class })
@Transactional
public class OrderRepositoryTest {
	@Autowired
	private OrderRepository repo;

	@Autowired
	private SessionFactory sessionFactory;

	@Test
	public void testPersistOrderWithItems() {
		Session s = sessionFactory.getCurrentSession();

		Product chestnut = new Product("Chestnut", "2.50");
		s.save(chestnut);
		Product hazelnut = new Product("Hazelnut", "5.59");
		s.save(hazelnut);

		Order order = new Order();
		order.addLine(chestnut, 20);
		order.addLine(hazelnut, 150);

		repo.saveOrder(order);
		s.flush();

		Order persistent = (Order) s.createCriteria(Order.class).uniqueResult();
		Assert.assertNotSame(0, persistent.getId());
		Assert.assertEquals(new OrderLine(chestnut, 20), persistent
				.getOrderLines().get(0));
		Assert.assertEquals(new OrderLine(hazelnut, 150), persistent
				.getOrderLines().get(1));
	}
}

There are a few details worth noting here, though:

  1. I marked the test @Transactional, so that I can access Session directly. In this scenario, @EnableTransactionManagement on @Configuration seems to have no effect as the test is wrapped in transaction anyway.
  2. If the test is not marked as @Transactional (sensible when it only uses @Transactional components), the transaction seems to always be committed regardless of @TransactionConfiguration settings.
  3. If the test is marked as @Transactional, @TransactionConfiguration seems to be applied by default. Even if it’s omitted the transaction will be rolled back at the end of the test, and if you want it committed you need @TransactionConfiguration(defaultRollback=false).
  4. This probably goes without saying, but the @Configuration for tests is probably different from production. Here it uses embedded H2 database, for real application I would use a test database on the same engine as production.

That’s it, just those two Java classes. No XML or twisted depedencies. Take a look at my github repository for complete code.

IO vs. NIO – Interruptions, Timeouts and Buffers

Let’s imagine a system that sometimes needs to copy a file to a few locations, but in a way where responsiveness is critical. In other words, if for some reason a file system is overloaded and we are unable to write our file in less than a second, it should give up.

ExecutorService is a very convenient tool for the job. You can easily use it for executing several tasks in parallel (each writing to a different file system). Yuo also can tell it to give up after some timeout, and it will interrupt them for you. Perfect, just what we need.

The scaffolding looks like this:

void testCopy() throws Exception {
	ThreadPoolExecutor exec = (ThreadPoolExecutor) Executors
			.newCachedThreadPool();
	final long start = System.currentTimeMillis();
	Callable<Object> task = new Callable<Object>() {
		@Override
		public Object call() throws Exception {
			try {
				copy("a.bin", "b.bin");
			} catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("Call really finished after: "
					+ (System.currentTimeMillis() - start));
			return null;
		}
	};
	Collection<Callable<Object>> taskWrapper = Arrays.asList(task);
	List<Future<Object>> futures = exec.invokeAll(taskWrapper, 50,
			TimeUnit.MILLISECONDS);
	System.out.println("invokeAll finished after: "
			+ (System.currentTimeMillis() - start));
	System.out.println("Future.isCancelled? "
			+ futures.get(0).isCancelled());
	Thread.sleep(20);
	System.out.println("Threads still active: " + exec.getActiveCount());
}

To simulate response to timeouts on a healthy system with low load, I use a 100 MB file and very short timeout. The task always times out, there is no way my system can copy 100 MB in 50 ms.

I expect the following results:

  1. invokeAll finished after about 50 ms.
  2. Future.isCancelled? is true.
  3. Active thread count is 0. The sleep is there to eliminate some edge cases. Long story short, it gives the copy function some time to detect the interruption.
  4. Call really finishes after about 50 ms. This is very important, I definitely do not want the IO operations to continue after the task is cancelled. Under higher load that would breed way too many threads stuck in bogus IO.

Just in case, those tests were run on the 1.6 JVM from Oracle on 64-bit Windows 7.

Solution 1: Stream Copy

The first attempt is probably the straightforward – use a loop with a buffer and classic IO, like this:

private void copy(String in, String out) throws Exception {
	FileInputStream fin = new FileInputStream(in);
	FileOutputStream fout = new FileOutputStream(out);

	byte[] buf = new byte[4096];
	int read;
	while ((read = fin.read(buf)) > -1) {
		fout.write(buf, 0, read);
	}

	fin.close();
	fout.close();
}

That’s what all popular stream copying libraries do, including IOUtils from Apache Commons and ByteStreams from Guava.

It also fails miserably:

invokeAll finished after: 53
Future.isCancelled? true
Threads still active: 1
Call really finished after: 338

The reason is fairly obvious: there is no check for thread interrupted status in the loop or anywhere, so the thread continues normally.

Solution 2: Stream Copy with Check for Interruption

Let’s fix that! One way to do it is:

while ((read = fin.read(buf)) > -1) {
	fout.write(buf, 0, read);
	if (Thread.interrupted()) {
		throw new IOException("Thread interrupted, cancelling");
	}
}

Now that works as expected, printing:

invokeAll finished after: 52
java.io.IOException: Thread interrupted, cancelling
	at TransferTest.copyInterruptingStream(TransferTest.java:75)
	at TransferTest.access$0(TransferTest.java:66)
	at TransferTest$1.call(TransferTest.java:25)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)Future.isCancelled? true
	at java.lang.Thread.run(Thread.java:662)

Call really finished after: 53
Threads still active: 0

Nice, but I find it unsatisfactory. It looks dirty and I’m not particularly happy with having this code around my IO lib. There must be a better way, which brings us to…

Solution 3: NIO with transfer

NIO has this nice feature that it actually respects thread interruptions. If you try to read from or write to a channel after the thread has been interrupted, you get a ClosedByInterruptException.

That’s just what I need. For some reason I also read this answer at StackOverflow, saying:

“Don’t use a buffer if you don’t need to. Why copy to memory if your target is another disk or a NIC? With larger files, the latency incured is non-trivial. (…) Use FileChannel.transferTo() or FileChannel.transferFrom(). The key advantage here is that the JVM uses the OS’s access to DMA (Direct Memory Access), if present. (This is implementation dependent, but modern Sun and IBM versions on general purpose CPUs are good to go.) What happens is the data goes straight to/from disc, to the bus, and then to the destination…by passing any circuit through RAM or the CPU.”

Great, let’s do it!

private void copy(String in, String out) throws Exception {
	FileChannel fin = new FileInputStream(in).getChannel();
	FileChannel fout = new FileOutputStream(out).getChannel();

	fout.transferFrom(fin, 0, new File(in).length());

	fin.close();
	fout.close();
}

Output:

invokeAll finished after: 52
Future.isCancelled? true
Threads still active: 1
java.nio.channels.ClosedByInterruptException
	at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:184)
	at sun.nio.ch.FileChannelImpl.size(FileChannelImpl.java:304)
	at sun.nio.ch.FileChannelImpl.transferFrom(FileChannelImpl.java:587)
	at TransferTest.copyNioTransfer(TransferTest.java:91)
	at TransferTest.access$0(TransferTest.java:87)
	at TransferTest$1.call(TransferTest.java:27)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Call really finished after: 146

All I do is a trivial call to transferFrom. It’s very concise, and promises so much support from hardware and OS… But wait a moment, why did it take 146 ms? I mean, 146 milliseconds is much faster than 338 ms in the first test, but I expected it to terminate after around 50 ms.

Let’s repeat the test on a bigger file, something around 1.5 GB:

invokeAll finished after: 9012
Future.isCancelled? true
Threads still active: 1
java.nio.channels.ClosedByInterruptException
	at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:184)
	(...)
Call really finished after: 9170

How awful is that? This is probably the worst thing that could happen:

  • The task was not interrupted in a timely manner. 9 seconds is way too long, I expected around 50 millis.
  • invokeAll was blocked for the entire time of the operation – 9 seconds. What the hell?

Solution 4 – NIO with Buffering

It turns out I do need some buffering. Let’s try with this one:

private void copyNioBuffered(String in, String out) throws Exception {
	FileChannel fin = new FileInputStream(in).getChannel();
	FileChannel fout = new FileOutputStream(out).getChannel();

	ByteBuffer buff = ByteBuffer.allocate(4096);
	while (fin.read(buff) != -1 || buff.position() > 0) {
		buff.flip();
		fout.write(buff);
		buff.compact();
	}

	fin.close();
	fout.close();
}

Output:

invokeAll finished after: 52
Future.isCancelled? true
java.nio.channels.ClosedByInterruptException
	at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:184)
	at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:203)
	at TransferTest.copyNioBuffered(TransferTest.java:105)
	at TransferTest.access$0(TransferTest.java:98)
	at TransferTest$1.call(TransferTest.java:29)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Call really finished after: 55
Threads still active: 0

Now that’s exactly what I needed. It respects interruptions by itself, so I don’t need those tedious checks all over my IO utility.

Quirks: Different types of channels

If my IO utility is only used for copying files that it gets by name, like this:

static public void copy(String source, String destination)

… then it’s fairly easy to rewrite the method for NIO.

But what if it’s a more generic signature that operates on streams?

static public void copy(InputStream source, OutputStream destination)

NIO has a little Channels utility with very useful methods like:

public static ReadableByteChannel newChannel(InputStream in)
public static WritableByteChannel newChannel(OutputStream out)

So it almost seems like we could wrap our streams using this helper and benefit from interruptible NIO API. Until we look at the source:

public static WritableByteChannel newChannel(final OutputStream out) {
	if (out == null) {
	    throw new NullPointerException();
	}

	if (out instanceof FileOutputStream &&
		FileOutputStream.class.equals(out.getClass())) {
		return ((FileOutputStream)out).getChannel();
	}

	return new WritableByteChannelImpl(out);
}

private static class WritableByteChannelImpl
	extends AbstractInterruptibleChannel	// Not really interruptible
	implements WritableByteChannel
{
// ... Ignores interrupts completely

Watch out! If your streams are file streams, they will be interruptible. Otherwise you’re out of luck – it’s just a dumb wrapper, more like an adapter for API compatibility. Assumptions kill, always check the source.

“Programming Concurrency on the JVM”

A few years ago when I took concurrency classes pretty much everything I was told was that in java synchronized is key. That’s the way to go, whenever you have multithreading you have to do it this way, period. I also spent quite a while solving many classic and less classic concurrency problems using only this construct, reimplementing more fancy locks using only this construct, preventing deadlocks, starvation and everything.

Later in my career I learned that is not the only way to go, or at least there are those fancy java.util.concurrent classes that take care of some stuff for you. That was nice, but apparently I never took enough time to actually stop and think how those things work, what they solve and why.

The light dawned when I started reading Programming Concurrency on the JVM: Mastering Synchronization, STM, and Actors by Venkat Subramaniam.

The book starts with a brief introduction on why concurrency is important today with its powers and perils. It quickly moves on to a few examples of different problems: IO-intensive task like calculating size of a large directory, and computationally intensive task of calculating prime numbers. Once the ground is set, it introduces three approaches to concurrent programming.

The first way to do it is what I summed up in the first paragraph, and what Venkat calls the “synchronize and suffer” model. Been there, done that, we know how bad it can get. This approach is called shared mutability, where different threads mutate shared state concurrently. It may be tamed (and a few ways to do it are shown in the book), but is a lot harder than it seems.

Another approach is isolated mutability, where each mutable part of state is only accessed by one thread. Usually this is the actor based concurrency model. The third way is pure immutability where there simply is no mutable state. That is typical for functional programming.

In the following chapters the book explores each of those areas in depth. It briefly explains the Java memory model nad shows what options for dealing with shared mutability and coordinating threads exist in core Java. It clearly states why the features from Java 5 are superior to the classic “synchronize and suffer” and describes locks, concurrent collections, executors, atomic references etc. in more detail. This is what most of us typically deal with in our daily Java programming, and the book is a great introduction to those modern (if old, in a way) APIs.

That’s about one third of the book. The rest is devoted to much more interesting, intriguing and powerful tools: software transactional memory and actors.

Sometimes we have to deal with shared mutability, and very often we need to coordinate many threads accessing many variables. The classic synchronization tools don’t have proper support for it: Rolling back changes and preventing one thread from seeing uncommited changes of another is difficult, and most likely they lead to coarse-grained locks which basically lock everything while a thread is mutating something.

We know how relational databases deal with it with their ACID transactional model. Software transactional memory is just that but applied to memory, with proper atomicity, consistency and isolation of transactions. If one thread mutates a transactional reference in transaction, another will not see it until that transaction is committed. There is no need for any explicit locks as the libraries (like Akka or Clojure) monitor what variables you access and mutate in transaction and apply locking automatically. They even can rollback and retry the transaction for you.

Another approach is isolated mutability, a.k.a. actors, best demonstated on Akka. Each actor runs in a single thread and all it can do is receive or pass messages. This is probably closest to the original concept of object-oriented programming (recommended reading by Michael Feathers). You have isolated cells that pass messages to each other, and that’s it. When you have a task to execute, you spawn actors and dispatch it to them as immutable messages. When they’re done, they can call you back by passing another message (if the coordinator is also an actor), or if you’re not that pure you can wait for the result. Either way, eveything is neatly isolated in scope of a single thread.

Lengthy as this summary/review is, it really does not do justice to the book. The book itself is dense with valuable information and practical examples, which are as close to perfection as possible: There are a few recurring problems which are fairly simple and easy to grasp, solved over and over again with different techniques and different languages. There are many examples in Java, Scala, Groovy, Clojure and JRuby, dealing with libraries such as the core Java API, Clojure, Akka, GPars… In a few words, a ton of useful stuff.

Last but not the least, it’s excellently written. If anyone has seen Venkat in real life, this book is all like him – entertaining, but also thought-provoking, challenging and inspiring. It reads like a novel (if not better than some of them) and is very hard to put down until you’re done.

Highly recommended.

Java Puzzlers: Number.MIN_VALUE

If I asked you what the largest possible Integer in Java is, you would easily answer 2^31-1, or Integer.MAX_VALUE. Smallest possible Integer? Integer.MIN_VALUE, -2^31.

How about a Long? It’s also a Number, and each Number has MIN_VALUE and MAX_VALUE, and you would be right to refer to them.

Obvious and boring, right?

How about a Double then?

It’s also a Number, and so it has Double.MAX_VALUE, and yes that is the maximum. Minimum? Let me go already, obviously Double.MIN_VALUE!

Nope.

I only learned it today even though I’ve been programming Java for years. Double.MIN_VALUE is actually a positive number. Quick look at docs says it all: It is the smallest positive nonzero value of type double. If you’re really looking for the smallest value of Double, you need to refer to Double.MIN_NORMAL.

Yes, docs are very clear about it. Yes, it is a static constant, so LSP does not really apply (as if Java didn’t violate it all the time). Yet I still think it looks like a duck, it quacks like a duck, but needs batteries. It has different semantics for no good reason, does not follow the principle of least surprise and is plain unintuitive. I add it to my shelf of quirks along with half of Swing, everything around Dates and Calendars, equals and… what am I still doing here by the way?

Integrating Spring, Velocity and Tiles

I like Tiles and I heard a lot about Velocity. They seem to serve different purpose and reportedly are easily married together, so I decided to give it a shot and use them both in Spring web app. The integration actually took many hours and was a real rollercoaster during which I learned a lot about all three technologies. Hopefully this post can spare someone this fun and let them focus on business.

Goals

When I use tiles, I don’t like the default (?) approach of tiles.xml. I don’t want to put imports of JS & CSS, page title, navigation, body etc. each in its own file like in the snippet below, because that makes me switch between editor windows.

<definition name="hello" template="/WEB-INF/templates/main.jsp">
	<put-attribute name="title" value="Hello" type="string" />
	<put-attribute name="head" value="/WEB-INF/templates/hello-js-and-css.jsp" />
	<put-attribute name="nav" value="/WEB-INF/templates/hello-nav.jsp" />
	<put-attribute name="body" value="/WEB-INF/templates/hello.jsp" />
</definition>

Obviously I don’t want to put too much detail in tiles.xml, either.

What I really like is having one file per page, assembling the template in one place, such as this piece of JSP:

<tiles:insertTemplate template="template.jsp">
	<tiles:putAttribute name="title" value="Hello" />
	<tiles:putAttribute name="head">
		<script type="text/javascript" src="/js/jQuery.js" />
		<script type="text/javascript" src="/js/hello.js" />
	</tiles:putAttribute>
	<tiles:putAttribute name="body">
		<div>Hello, world!</div>
	</tiles:putAttribute>
</tiles:insertTemplate>

In Velocity, it’s supposed to look like this:

#tiles_insertTemplate({"template": "template.vm"})
	#tiles_putAttribute({"name":"title", "value": "Hello"})#end
	#tiles_putAttribute({"name":"head"})
		<script type="text/javascript" src="/js/jQuery.js" />
		<script type="text/javascript" src="/js/hello.js" />
	#end
	#tiles_putAttribute({"name":"body"})
		<div>Hello, world!</div>
	#end
#end

However, the docs on integration are really intended for adding some Velocity support to your Tiles-based app, while I wanted quite the opposite: Use Tiles in my rich Velocity app, with full support for spring context, macros etc.

Solution

In short, what we’re going to do is:

  1. Use VelocityViewResolver to resolve and render pages
  2. Add support for Tiles macros to this Velocity rendering engine
  3. Extend the Tiles renderer with full support for Velocity, including Spring context, macros etc. Ultimately we’re going to make it use the original Velocity engine created by Spring.

Full source code in form of a minimal, complete web app are at github. For details see below.

Spring & Velocity -> Tiles

For the first step, we define viewResolver and velocityConfig like this:

@Bean
public VelocityConfig velocityConfig() {
	VelocityConfigurer cfg = new VelocityConfigurer();
	cfg.setResourceLoaderPath("/WEB-INF/velocity/");
	cfg.setConfigLocation(context
			.getResource("/WEB-INF/velocity.properties"));
	return cfg;
}

@Bean
public ViewResolver viewResolver() {
	VelocityViewResolver resolver = new VelocityViewResolver();
	resolver.setViewClass(VelocityToolboxView.class);
	resolver.setSuffix(".vm");
	return resolver;
}

It’s important that we use VelocityToolboxView there, otherwise the tiles directives won’t work.

We also need to put the following in velocity.properties:

userdirective=org.apache.tiles.velocity.template.AddAttributeDirective,\
  org.apache.tiles.velocity.template.AddListAttributeDirective,\
  org.apache.tiles.velocity.template.DefinitionDirective,\
  org.apache.tiles.velocity.template.GetAsStringDirective,\
  org.apache.tiles.velocity.template.ImportAttributeDirective,\
  org.apache.tiles.velocity.template.InsertAttributeDirective,\
  org.apache.tiles.velocity.template.InsertDefinitionDirective,\
  org.apache.tiles.velocity.template.InsertTemplateDirective,\
  org.apache.tiles.velocity.template.PutAttributeDirective,\
  org.apache.tiles.velocity.template.PutListAttributeDirective

This adds basic support for Tiles directives to Velocity, but it’s still useless because once Velocity hands rendering over to Tiles, Tiles is unable to render Velocity and would simply ignore it (rendering syntax of #directives to browser.

Tiles -> Velocity

We need to teach Tiles to use Velocity. For this we’re going to need a custom TilesInitializer:

@Bean
public TilesConfigurer tilesConfigurer() {
	TilesConfigurer cfg = new TilesConfigurer();
	cfg.setTilesInitializer(new VelocityTilesInitializer(velocityConfig()));
	return cfg;
}
public class VelocityTilesInitializer extends DefaultTilesInitializer {
	private VelocityConfig velocityConfig;

	public VelocityTilesInitializer(VelocityConfig velocityConfig) {
		this.velocityConfig = velocityConfig;
	}

	@Override
	protected AbstractTilesContainerFactory createContainerFactory(
			TilesApplicationContext context) {
		return new BasicTilesContainerFactory() {

			@Override
			protected List<TilesRequestContextFactory> getTilesRequestContextFactoriesToBeChained(
					ChainedTilesRequestContextFactory parent) {
				List<TilesRequestContextFactory> factories = super
						.getTilesRequestContextFactoriesToBeChained(parent);
				registerRequestContextFactory(
						VelocityTilesRequestContextFactory.class.getName(),
						factories, parent);
				return factories;
			}

			@Override
			protected AttributeRenderer createTemplateAttributeRenderer(
					BasicRendererFactory rendererFactory,
					TilesApplicationContext applicationContext,
					TilesRequestContextFactory contextFactory,
					TilesContainer container,
					AttributeEvaluatorFactory attributeEvaluatorFactory) {
				ContextPassingVelocityAttributeRenderer var = new ContextPassingVelocityAttributeRenderer(
						velocityConfig.getVelocityEngine());
				var.setApplicationContext(applicationContext);
				var.setRequestContextFactory(contextFactory);
				var.setAttributeEvaluatorFactory(attributeEvaluatorFactory);
				var.commit();
				return var;
			}
		};
	}
}

We’re almost there, but here’s a tricky bit. Normally in lines 31-32 you would put velocityAttributeRenderer. However, this renderer completely ignores the Spring-augmented Velocity context & engine that Tiles received from Velocity. It creates its own VelocityEngine and lets it do the rendering, throwing away all the Spring and tiles directives and context objects.

There is no way to change this behavior in Tiles (which otherwise seems to be an interesting study in design patterns and extensibility). I even created two JIRA issues for it: 541 for forwarding context and 542 for injecting VelocityEngine.

Meanwhile, we have to make do with this workaround (see github for full source):

public class ContextPassingVelocityAttributeRenderer extends
		AbstractTypeDetectingAttributeRenderer {
	// ...

	private VelocityEngine engine;

	public ContextPassingVelocityAttributeRenderer(VelocityEngine engine) {
		this.engine = engine;
	}

	// ...

	public void commit() {
		velocityView = new VelocityView(new TilesApplicationContextJeeConfig());
		velocityView.setVelocityEngine(engine);
	}

	@Override
	public void write(Object value, Attribute attribute,
			TilesRequestContext request) throws IOException {
		if (value != null) {
			if (value instanceof String) {
				InternalContextAdapter adapter = (InternalContextAdapter) ((VelocityTilesRequestContext) request)
						.getRequestObjects()[0];
				Context context = adapter.getInternalUserContext();
				Template template = velocityView.getTemplate((String) value);
				velocityView.merge(template, context, request.getWriter());
			} else {
				throw new InvalidTemplateException(
						"Cannot render a template that is not a string: "
								+ value.toString());
			}
		} else {
			throw new InvalidTemplateException("Cannot render a null template");
		}
	}

	// ...

It works arounds both of the JIRA issues and lets us accomplish the ultimate goal:

  1. The VelocityEngine injected to VelocityView here is the original VelocityEngine from Spring. Among other things, it supports Spring directives and context-dependent tools.
  2. The TilesRequestContext in write method still contains the original Velocity context created from Spring scaffolding. Standard implementation of VelocityAttributeRenderer simply throws it away. This workaround above extracts the original context and uses it for rendering.

Conclusion

This journey took much more time than I thought. Documentation on such cases is nonexistent, so I spent hours debugging, reading source code, experimenting, praying and cursing. It was even more fun as I had close to zero knowledge of internals of Spring view resolution and rendering engine, as well as Tiles and Velocity.

It’s quite satisfying since I learned a ton about all those technologies and eventually was able to resolve it in a fairly elegant way. But it was also a frustrating and time-consuming riddle and I hope this post spares someone some trouble.

Update – Velocity Tools

A while later I discovered this solution does not support Velocity Tools property. Here’s how to add it: Spring & Velocity Tools.

Careful with that PrintWriter

Let’s assume we have a nice abstraction over email messages simply called Email. Something that can write itself to Writer and provide some other functionality (e.g. operating on the inbox).

Now, take this piece of code:

public void saveEmail(Email email) {
	FileOutputStream fos = null;
	try {
		fos = new FileOutputStream("file.txt");
		PrintWriter pw = new PrintWriter(fos);
		email.writeContentTo(pw);
		pw.flush();
		email.deleteMessageFromInbox();
	} catch (IOException e) {
		log.error("Saving email", e);
	} finally {
		IOUtils.closeQuietly(fos);
	}
}

Question: What happens if for whatever reason the PrintWriter cannot write to disk? Say, your drive just filled up and you can’t squeeze a byte in there?

To my surprise, nothing got logged, and the messages were removed from inbox.

Unfortunately, I learned it the hard way. This code is only a piece of a larger subsystem and it took me quite a while to figure out. Used to dealing mostly with streams, I skipped this area and checked everything else first. If PrintWriter was like a stream, it would throw an exception, skipping deleteMessageFromInbox.

All streams around files work like that, why would this one be different? Well, PrintWriter is completely different. Eventually I checked its Javadoc and saw this:

“Methods in this class never throw I/O exceptions, although some of its constructors may. The client may inquire as to whether any errors have occurred by invoking checkError().”

At first I was furious about finding that’s all due to yet another inconsistency in core Java. Now I’m only puzzled and a bit angry. Most things in Java work like this – they throw exceptions on every occasion and force you to explicitly deal with them. And it’s not unusual to see 3 or 4 of them in a signature.

One could say, it’s all right there in the Javadoc. Correct. But still, it can be confusing to have two fundamentally different approaches to error handling in one corner of the library. If one gets used to dealing with one side of it, he may expect the same from the other. Instead, it turns out you always have to carefully look at signatures and docs, because even in core Java there is no single convention.

Related: try/catch/throw is an antipattern – interesting read, even if a bit too zealous.

Java Web Start Bugs: Offline Edition

Java Web Start is full of bugs that never get resolved and make it next to unusable, and very costly, in business environment. If you have thousands of users who tend to cancel update prompts, or whose connections get interrupted, or who are simply unlucky, you are actually scared of releases. And if you try to release often? Yup, you guessed it.

Rant aside.

Recently I was trying to move away from web-based JWS to one that delivers jars and jnlp to the client and installs locally. I found several interesting bugs or quirks that I think are worth posting here.

Shortcut for all users

My first attempt was installing the application for all users from the Internet. To silently install shortcut on desktop for all users, you can add <shortcut> to your jnlp and execute:


javaws -import -system -silent http://example.com/myapp.jnlp

It does place shortcut on desktop for all users. But it doesn’t work!

Unfortunately, by default Java 6 on my Windows 7 has web start cache in C:\Users\Konrad\.... When you try to launch the app from John’s desktop, you get an ugly error because John cannot access that folder. It doesn’t matter that I run the command with -system switch from Administrator’s console. It lands in user-specific, protected directory.

Workaround: Force JWS to use another, accessible to everyone folder for cache.

Place this in C:\Windows\Sun\Java\Deployment\deployment.config:


deployment.system.config=file\:C\:/WINDOWS/Sun/Java/Deployment/deployment.properties
deployment.system.config.mandatory=false

And in C:\Windows\Sun\Java\Deployment\deployment.properties:


deployment.system.cachedir=C\:\\JavaWebStart
deployment.system.cachedir.locked=true

Offline installation and updates

Specification changed a bit and I researched purely “offline” solution. Place all files in a directory and install from there. Push updates with the same mechanism. In other words, use local file system for codebase and never ask JWS to look online. Official documentation advertises it as “CD installation”.

My JNLP starts with:


<jnlp codebase="file:/c:/myapp/" href="my.jnlp">

Files reside in C:\myapp and I install the app with:


javaws -import -system -silent file:/c:/myapp/my.jnlp

What could possibly go wrong?

Bug 1: You cannot change code if application is running

With web-based JWS, you can update your codebase anytime. Web Start keeps copies of the files in local cache and safely launches the application off that copy. Obviously.

Unfortunately, with local codebase it tries to be smart and does not copy to cache. Now, if you try to update by overwriting contents of C:\myapp while the application is running, it will die with a flood of ClassNotFoundExceptions in log. Oops.

Solution: None, sadly. Don’t update if the application is running. Period.

Bug 2: Curious “do you want to go online” message

OK, so I decided to update only when the application is not running.

Suppose John is running version 3.0.1. He closes the application. Now your smart updater overwrites contents of C:\myapp with 3.0.2. When John launches the application again, he may see a message requesting going online for an update because JNLP has changed.

This will happen if your <shortcut> is set for online="false".

That is plain wrong. My codebase is local, every single thing is local, and the user is bothered with a popup about going online. Then if I accept to “go online”, it innocently informs that it’s downloading update from file:/c:/...

Solution: Use <shortcut online="true">. Then it will always assume the application is “online” and therefore skip asking for permission to go online.

Bug 3: Update reinstalls app and removes shortcut

Remember, I am trying to maintain shortcut for all users at all times.

Now, if you update the application by simply overwriting contents of codebase directory, you’re in for another curiosity. On launch JWS will remove app from system cache and remove shortcuts from all desktops, and reinstall the application into this user’s cache. Others lose the shortcut for good.

Workaround: Reinstall the application into system cache yourself.

  1. javaws -uninstall file:/c:/myapp/my.jnlp
  2. Place new files in C:\myapp
  3. javaws -import -system -silent file:/c:/myapp/my.jnlp

Final rant

Every single time I deal with web start, it bites and makes me weep and gnash my teeth. I spent hours figuring all this out and fighting JWS who fought me back. As I deal with it I find some comfort researching the web and finding other desperate developers coping with similar issues. I hope this post saves someone some pain.