What's Ubik's License?

Ubik is distributed under the Apache 2.0 license, although it optionally uses libraries that are themselves licensed under the LGPL:

  • If you are using Avis for broadcast, you will the Avis client libraries in your classpath.
  • By default, Ubik attempts using the JBoss Serialization library if it's found in the classpath. If you do not want to use it, make sure it's not in the classpath.

Our take on the LGPL libraries is that they will have no impact on the application you are developing if you do not distribute that application with modified versions of the LGPL'd libraries.

Performance and Scalability

We've grouped in this section the questions pertaining to performance and scalability.

Is Ubik fast?

We've taken precautions to ensure that Ubik is fast: Ubik relies on JBoss Serialization by default - rather than Java's own serialization. Also, most if not all of Ubik built-in serializable objects implement the java.io.Externalizable interface.

Is Ubik scalable?

Yes. Ubik has features that allow it to scale across the board (from the system and administration standpoints): distributed JNDI tree that guarantees availabity in case one node fails; smart stubs supporting failover, load balancing and dynamic discovery; an extremely performant NIO transport that scales to thousands of concurrent connections; and support for callbacks.


This section addresses questions pertaining to Ubik networking.

My client can't seem to be able to connect to my server. What's happening?

This often is observed when you server is running on a machine with multiple network interfaces: by default, Ubik will bind to all interfaces, but then only one of these addresses will be chosen to be returned as part of stubs sent back to clients. It might be that Ubik's best attempt at picking such an address is not good enough, and that the address that's returned is one to which some clients cannot connect. In such a case, you need to configure the ubik.rmi.address-pattern JVM property, which specifies (through a regexp), which address to select. Here are a few example regexps:


See the Cookbook for more information regarding bind address selection.

Note the double backslashes: in Java the backslash is an escape character, therefore it must be doubled in order to be treated as a normal character.

Multicast does not seem to work. Any workaround?

The explanation that comes to mind is that your network is not set up to support IP multicast - or that multicast is not supported across subnets. You can set JVM properties that will configure the event channel to use the Avis BroadcastDispatcher. See the relevant documentation for more info.

Second, it may be that you're experiencing UDP packet loss. That's also network relevant and at the Ubik level, the surest way to avoid that is to avoid completely. This is done by going through the workaround suggested above, and in addition make sure you're using the TCP UnicastDispatcher - which should be the case since it's the one that's set up by default. Check out the documentation for more details.

Lastly, another cause might be that the configured packet size is not large enough. You can configure it with the ubik.rmi.naming.mcast.bufsize JVM property (3072 bytes is assumed by default).

How is the state of an EventChannel domain maintained?

The master triggers the heartbeat requests that are sent to each slave, as part of the control protocol. The master keeps track of the nodes that respond to the requests. After a given timeout (configurable through the ubik.rmi.naming.mcast.heartbeat.timeout JVM property), for the nodes that did not respond, the master will notify all slave nodes still alive about the missing nodes, so that all nodes can update their view of the domain accordingly.

In addition, upon shutting down, nodes broadcast a "shutdown event" to the domain so that the other nodes can update their state in "real time". This reduces the possibility for nodes to have an inconsistent view of the domain.

What if the master disappears?

The remaining nodes will go through the "challenge" part of the protocol, in the context of which a new master is detected. After a given amount of time during which no heartbeat request has been received, a slave node will determine if it should attempt becoming the new master (the slave node compares its identifier against the identifiers of other nodes, and will deem itself a candidate to become the master if its own identifier comes first in alphabetical order).

A master candidate will send a challenge request to the other nodes. These other nodes will then themselves determine if they "accept" the challenging node as the new master or not. The challenging node should become the master in most cases, but we can't guarantee 100% that another slave node has not determined it should be candidate. If another slave node is also currently a candidate and receives a challenge request, it will compare it's identifier against the one of the node from which the request emanates: if it comes first alphabetically, it will deny the request - else it will grant it and remain slave itself.

Since node identifiers are 128 bit UUIDs, there's a very infinitesimal probability of having two such identifiers that are the same.