== Java Uuid Generator ("JUG") == === 1. Why JUG? Don't we already have "uuidgen"? === Some do, some don't. :-) Most platforms have variations of uuidgen command line tool, but not all do. Additionally, accessing uuidgen from Java may be tricky (since its location in native OS filesystem depends on OS and possibly other factors). So, portability is one benefit; JUG works if you have Java 1.2 (version 2.0) or Java 1.6 (version 3.0). Performance may be another benefit when using JUG from Java. Interfacing to native functionality (either via uuidgen or directly to libuuigen) is likely to be slower than calling JUG methods, even if generation itself was faster. === 2. Why NOT use JUG? === If you are paranoid about duplicate UUIDs (esp. when using time-based algorithm), there's no way to guarantee that multiple UUID- generators don't produce same UUID. It's still unlikely to happen (due to clock sequence field etc), but potentially a problem. Uuidgen usually solves this by having a system-wide global lock to prevent possibility of using same timestamps; but with Java the best JUG can guarantee is that there's always max. 1 JUG instance per JVM; other JVMs may have their own copies. [note: in theory it would be possible to add native support for locking, for platforms that have locking functionality... but then it might also be easy to just use native uuidgen functionality as well] Note, though, that with random- and name-based methods multiple instance of JUG are not a problem; name-based methods base the uniqueness on the name, not timing, and random-based method is based on quality of the random number generator. In latter case it all depends on how random one considers SecureRandom to be. Additionally, although generating UUIDs is straight-forward, JUG has not been extensively tested; it just seems to generate unique UUIDs as is. :-) === 3. What is the fastest method to use for generating UUIDs? === It depends on your system, random number generators used etc. etc., But here are some numbers, running on a MacBook (2.5 GHz dual CPU) Time-based: 5 million/second Random-based: 0.25 million/second (when using SecureRandom) Name-based: 1 million/second (depends on length, namespace etc; this with MD5) So with default settings, time-based algorithm is by far the fastest; usually followed by name/hash based alternative (for short/medium names at least), and random-based variant being slowest. Finally, if performance _really_ is very important for you, there is a further complication when using time-based algorithm; Java's system clock has max. resolution of 1 millisecond, instead of 100ns required by UUID specification. This is solved by using additional counter (in JUG), but the downside is that for each separate Java 'time slice' (time period when system clock returns same timestamp) can produce at most 10000 UUIDs. If JDK on the platform does advance in 1 msec ticks, this is good enough for generating up to 10 million UUIDs per second, but on some platforms resolution is coarser: on Windows granularity used to be 55 msec, meaning max. rate would be 180 kUUIDs per second. ... which all means that for generating more than, say, hundred thousand UUIDs per second, you may need to look at native implementations. But often with system like that you aren't really using Java in the first place. === 4. Which one should I use, assuming performance is not important? === If you can access the ethernet card address it might be good idea to use time-based algorithm, if you will only be generating UUIDs from single JVM (and won't be using other UUID-tools at the same time). If so, uniqueness is pretty much guaranteed and algorithm is fast as well. One potential drawback is that in case you consider giving out ethernet address a security problem (which in theory it could be, although there probably aren't any major immediate problems), this method is not for you, since ether address is stored as is in last 6 bytes of UUID (this could be partially solved by hashing the ethernet address, but the standard doesn't mention this solution so it's not implemented yet) If there will be multiple UUID generators (different JVMs, using native uuidgen), using random-based method may be the best option; although there is a file-locking base synchronizer available for time-based generation. This works with multiple JVMs, but may not be applicable to synchronize with non-Java generators. Random-number based variant should be safe to use, as long as the underlying random number generator is good (which SecureRandom by JDK should be). Finally, if it's easy to generate unique names from system (say, URL combined with a sequence number guaranteed to be unique), and especially if these 'human readable' identifiers (such as tagURIs) are otherwise used, it may be a good idea to use one of the name-based algorithms. It's easy to generate UUIDs from tag-URIs, so one-way conversions can be done on-the-fly. === 5. How can I obtain the Ethernet MAC-address of the machine JUG runs on? === Easiest way with version 3.x and above is to use EthernetAddress class, which internally uses method that JDK 1.6 introduced. Earlier versions of JUG relied on JNI-access native libraries. === 6. What if system clock/time goes backward? === In general, it is unlikely that the system clock (as observed by Java code via System.currentTimeMillis()) will go backwards (daylight savings etc. do not change this "absolute" UTC time value), it can occur. Before version 2.0, JUG only ensured that such events do not cause problem within a JVM session, but not between consequtive runs. Thus, it was theoretically possible that if time moved backwards after JVM was shutdown (or class loader create a new UUIDGenerator instance etc), timestamps could overlap. While this was unlikely to happen (due to additional randomness injected via clock sequence field eetc.), this potential problem can now be resolved in JUG 2.0 and onwards using external synchronization. UUIDGenerator can be configured with TimestampSynchronizer instances; the default implementation, FileBasedTimestampSynchronizer works by using 2 files that are used to store timestamp values used for generation. They are read when UUIDGenerator needs to initialize timestaps (when synchronization enabled), and updated when necessary. An additional benefit is that these files are also locked using NIO, which means that it is now also possible to prevent multiple JVMs (or, multiple instances of UUIDGenerator loaded using separate classloaders -- this can happen with application servers on context reloads) from running concurrently (assuming they are configured to use same files). === 7. How do I configure (or disable) logging === Starting with 2.0 release, JUG now has a simple configurable logging sub-system. You can start by looking at javadocs for: com.fasterxml.uuid.Logger class.