Stop bundling Ask Toolbar with the Java installer

A petition asking Oracle to stop bundling the Ask toolbar with the Java installer is currently ongoing. I have the impression that this petition should be getting more attention and this is why I am writing this blog post. Read and sign the petition here.

The disreputable practice of bundling bloatware with the Java installer is not originally Oracle’s fault, as Sun started it. However, Oracle refuses to discontinue it. The installer doesn’t force you to install the Ask toolbar, but you have to opt-out explicitly. This is an unnerving task if you have to install security updates for a large set of machines. Indeed, the practice came into wide criticsm once again when Oracle rolled out high-priority security updates earlier last month. How sensible is it to bundle high-priority security updates together with software that compromises the system?

Here is a verbatim copy of the petition text:

To:
Larry Ellison, CEO of Oracle Corporation
Editor of Oracle Magazine
Editor of Java Magazine
Stop bundling Ask Toolbar with the Java installer

Sincerely,
[Your name]

More than 13000 people (including myself) have signed the petition so far, but the target is 250000, so we still have a long way to go. Among the signatories are also highly renowned Java experts, such as Joshua Bloch, whose statement I want to repeat here:

Installing malware by default along with a patches that correct security holes is untenable. Oracle is violating the trust of the hundreds of millions of users who run Java on their machines. They are tarnishing the reputation of a once proud platform. This isn’t even close to reasonable. It has to stop.

Collections.unmodifiable revisited

Writing correct concurrent programs is notoriously hard. Concurrency bugs are extremely hard to find and might rarely manifest (and if they occur, they are frequently attributed to cosmic rays). Talking Java: just because a multi-threaded program works on your machine in your VM does not mean that it won’t come crashing down in flames (luckily, aircraft software follows a tough certification process) on another VM or another machine with a different set of cores. One thing that makes multi-threaded programming especially hard is caching. In Java, threads may cache non-volatile data and if updates on this data are not synchronized, these updates may never become visible to other threads. This typically results in non-termination of a program when the last remaining thread just does not see that another thread set its boolean stop to true.

All in all, a lot of concurrency problems have their roots in shared access to mutable data. So, an elegant solution for getting rid of these problems is to not to do that in the first place. Instead, share immutable data. In Java, the Collection classes provide ways of storing, well, collections of similar data and there are implementations for the most common data structures. So, sharing only immutable data often boils down to sharing immutable versions of the collections used internally. The utility class Collections provides methods for working with and transforming Collection objects and some of these methods of the form Collection unmodifiable = Collections.unmodifiableCollection(Collection c) provide unmodifiable access to original (maybe internal) collections. However, things are still not that easy and there is a subtle problem in using these methods for sharing data. To make this more clear, consider the following code:

Set origin = new HashSet();
origin.add("one");
origin.add("two");
Set unmodifiable = Collections.unmodifiableSet(origin);
someMultiThreadedContext.process(unmodifiable); // async processing, returns immediately
origin.add("three");

You could expect that someMultiThreadContext would get the set containing two elements and then do whatever with it. In the meantime, you would be able to just go on updating the internal state (aka origin) as you like without affecting someMultiThreadContext. It really pays off to read the Javadocs more thoroughly sometimes. What Collections.unmodifiableSet() provides is an unmodifiable wrapper and not an unmodifiable copy. If someMultiThreadContext would attempt to alter the set, it would receive an UnsupportedOperationException. This does NOT mean that the contents of unmodifiable are actually unmodifiable. It is just a wrapper collection. In its core, it still holds a reference to origin. This means that if origin is updated, someMultiThreadContext might still see this update.
To make the thing entirely clear, consider this main method:

	public static void main(String[] args) {
		Set origin = new HashSet();
		origin.add("one");
		origin.add("two");
		Set unmodifiable = Collections.unmodifiableSet(origin);
		System.out.println("Size: " + unmodifiable.size());
		origin.add("three");
		System.out.println("Size: " + unmodifiable.size());
	}

which prints:

Size: 2
Size: 3

And here the visibility problems begin: You cannot use Collections.unmodifiableCollection() for implementing a view of a thread-unsafe collection in a multi-threaded context, because of the visibility guarantees. After all, it just produces a wrapper where state-changing methods are overwritten to throw exceptions. There is no synchronization or volatile involved. Because of this, threads may locally cache the content of the sets and never see an update of origin. This means that Collections.unmodifiableCollection() cannot be used to propagate state to other concurrent parts of the program in this manner. You need synchronization on behalf of origin, either by synchronizing it yourself or by using a thread-safe implementation of Set. The fact that immutability does not necessarily provide visibility is just too easily forgotten (“No problem, my collection is immutable, nothing can go wrong!“).

Please note that Collection.unmodifiableCollection() still is a way for sharing immutable data, as long as the data is fire and forget and not a view of internal state where updates have to be seen. For instance, if the data is some message sent to another subsystem and then forgotten or never touched again by the sender.

bpel-g 5.3 released

I would like to draw attention to the bpel-g 5.3 release version that is available for download since December 25, 2012. This version comes with some major improvements, such as:

  • Replacing the Axis stack with CXF
  • Including Esper’s complex event processing engine
  • Better integration with Apache Camel
  • Quite some bugfixes

We have already benchmarked the engine with betsy, so I can confirm the last point. Bpel-g is now among the best ranking engines out there, and shares the first place in BPEL support together with ActiveBPEL. In combination with the integration with other useful libraries (especially CXF and Camel), I think bpel-g really is a good engine to use today. If you are looking for a simple tutorial on how to use it, you can find that here.