Library / SDK
cowtowncoder/java-uuid-generator avatar
cowtowncoder/java-uuid-generator

JUG: a Java library for every UUID version from 1 to 7

Java Uuid Generator (JUG) is a Java library for generating all standard UUID versions (v1 - v7)

944 stars119 forksJavaApache-2.0

At a glance

What is it?
Java Uuid Generator (JUG) is a long-running Apache-2.0 library that generates time-based, random, name-hash and new epoch-based UUIDs, converts them to and from byte arrays, and ships a command line entry point.
Who is it for?
JUG is a good fit for Java services that need more than java.util.UUID.randomUUID, especially for version 7 identifiers, byte array serialization, or name-based hashes with a stable namespace. It is a poor fit for a project that wants one static helper with no dependency, or for a non-JVM stack.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • cowtowncoder/java-uuid-generator944 ★ · -3
Star history
Repository2026-10-222026-11-07
cowtowncoder/java-uuid-generator947944

-3 Stars in the last 16 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

JUG covers the UUID versions the JDK still leaves out

The JDK ships java.util.UUID, and it ships a random generator for it. What it does not ship is a family of generators covering the versions a distributed system actually needs: time and location based identifiers, name hash based identifiers, and the two newer variants added by RFC-9562. Java Uuid Generator, usually called JUG, exists to fill that gap. It is described as a set of Java classes for working with UUIDs: generating them with the standard methods, outputting them efficiently, sorting and so on.

The supported range is versions 1, 3, 4, 5, 6 and 7. Versions 1, 3, 4 and 5 are the classic set from RFC 4122: version 1 is time and location based, versions 3 and 5 are name hash based, and version 4 is random. Versions 6 and 7 came later, in 2022, as the RFC-9562 successors to version 1, and both are defined in terms of lexicographic ordering so that identifiers sort in creation order.

That last property is the reason to care. A system that wants monotonically increasing keys without a database sequence can sort by a UUID column, and a v7 value gives that for free because the timestamp sits in the high bits. JUG was written by Tatu Saloranta in 2002 and has been revised over the years, with contributions credited in `release-notes/CREDITS`. It targets the RFC-9562 specification rather than the older draft.

Generator choice happens once, then generate() does the work

The original use case for JUG was generation, and the API reflects a deliberate separation: you pick a generator, then call `generate()` on it. The entry point is the `Generators` class, and the factory methods encode the version in the name.

java
UUID uuid = Generators.timeBasedGenerator().generate(); // Version 1
UUID uuid = Generators.randomBasedGenerator().generate(); // Version 4
UUID uuid = Generators.nameBasedGenerator().generate("string to hash"); // Version 5
// With JUG 4.1+: support for https://github.com/uuid6/uuid6-ietf-draft versions 6 and 7:
UUID uuid = Generators.timeBasedReorderedGenerator().generate(); // Version 6
UUID uuid = Generators.timeBasedEpochGenerator().generate(); // Version 7
// With JUG 5.0 added variation:
UUID uuid = Generators.timeBasedEpochRandomGenerator().generate(); // Version 7 with per-call random values

A version 1 generator needs a node identity, and that is where the API asks you to think. You can construct it explicitly against a specific network interface:

java
TimeBasedGenerator gen = Generators.timeBasedGenerator(EthernetAddress.fromInterface());
UUID uuid = gen.generate();
UUID anotherUuid = gen.generate();

Or you can let the library guess. The `Generators.defaultTimeBasedGenerator` factory method, added in JUG 4.2, tries to determine which network interface corresponds to the default route for all outgoing network traffic and uses that. The documentation calls it "likely a good choice for common usage scenarios". Generators are documented as fully thread-safe, so one instance can be shared across threads rather than created per request.

Two version 7 generators, two different random strategies

The version 7 line is where the library has a real opinion, and it is worth reading the API closely before you pick one. Both `timeBasedEpochGenerator()` and `timeBasedEpochRandomGenerator()` produce version 7 values, which the project describes as Unix-timestamp plus random based variants with lexicographic ordering.

The distinction is per-call randomness. The epoch generator is the plain Unix-timestamp plus random form, and JUG 5.0 added the variation that produces version 7 values with per-call random values. Why that matters is collision behaviour: if the random component is fixed for a generator instance, then two values generated in the same millisecond share those random bits and rely on counter or timestamp resolution to stay distinct. If the random component is redrawn per call, uniqueness inside a millisecond comes from a much larger space.

The documentation does not spell out the internal mechanics of either generator, and it gives no throughput figures or latency numbers. So the honest position is this: the naming tells you the two differ in how random values are obtained, and the choice between them is a decision about how you want per-millisecond uniqueness handled. Anyone with strict collision requirements in a high-rate service should read the generator source rather than assume the safer-sounding name covers their case.

Version 6 sits in the same family as `timeBasedReorderedGenerator()`, described as a reordered variant of version 1 with lexicographic ordering. It is the older of the two new formats, and it exists mainly for compatibility with the uuid6 draft line of discussion.

Maven and Gradle coordinates, plus a module name for JDK 9+

JUG is published to Maven Central under the group `com.fasterxml.uuid` and the artifact `java-uuid-generator`. The README gives the dependency block for Maven:

xml
<dependency>
  <groupId>com.fasterxml.uuid</groupId>
  <artifactId>java-uuid-generator</artifactId>
  <version>5.1.0</version>
</dependency>

And the equivalent line for Gradle:

groovy
implementation 'com.fasterxml.uuid:java-uuid-generator:5.1.0'

Dependency footprint is the part to notice. The only dependency is a logging library, and which one depends on the major version. Up to 3.x, `log4j` is used, optionally, as a runtime dependency. From 4.x onward, the `slf4j` API is used, and the documentation is explicit that the logging implementation must be provided by the calling application. In other words, adding JUG to a modern project does not add a logging backend, but it also means an application with no slf4j binding will not get JUG's diagnostics.

Since version 3.2.0, JUG also defines a JDK9+ compatible `module-info.class` with the module name `com.fasterxml.uuid`, so a modular application can resolve it as a named module rather than on the classpath. Direct downloads for people who want the jar without a build tool are pointed at the project wiki.

UUIDUtil handles the byte array conversions the JDK omits

JDK's UUID class converts to `String` with `toString()`, but it has no equivalent for turning a UUID into raw bytes, and parsing a UUID from a string is comparatively slow. JUG fills that gap with the `UUIDUtil` class in the package `com.fasterxml.uuid.impl`.

Writing bytes is the clearest case, because you can append into an existing buffer at an offset rather than allocate a new array:

java
byte[] asBytes = UUIDUtil.asByteArray(uuid);
// or if you have longer buffer already
byte[] outputBuffer = new byte[1000];
// append at position #100
UUIDUtil.toByteArray(uuid, outputBuffer, 100);

Reading works in both directions, from a string and from sixteen raw bytes:

java
UUID uuidFromStr = UUIDUtil.uuid("ebb8e8fe-b1b1-11d7-8adb-00b0d078fa18");
byte[] rawUuidBytes = ...; // byte array with 16 bytes
UUID uuidFromBytes = UUIDUtil.uuid(rawUuidBytes)

The documentation is direct about the comparison, saying the JDK's own `UUID.fromString("ebb8e8fe-b1b1-11d7-8adb-00b0d078fa18")` is "rather slower than JUG version", and pointing to a write-up on measuring the performance of `UUID.fromString()`. Note that this is the project's own claim, not an independent measurement. Still, the API shape is the point: if your system stores identifiers as binary, a library that treats byte conversion as a first class operation saves a layer of hand-rolled code.

The same jar also runs as a command line tool

JUG is not only a pluggable component. The documentation states that it can be used as a command-line tool via the class `com.fasterxml.uuid.Jug`, or as a pluggable component. The jar built under `target/` is the one to use for that, named with the project version:

code
target/java-uuid-generator-5.1.0-SNAPSHOT.jar

The repository layout gives a hint at the wider shape of the project: besides `src/` and `pom.xml` there is a `jug-native/` directory, a `run.sh` script at the root, and a `release-notes/` directory holding the credits file. A separate native module and a run script suggest a build or launch path beyond the plain Maven jar.

For most teams the command line path is a convenience for generating test identifiers, not a production interface. The library entry points are the ones you will call from code, and the CLI exists so you can produce a value without writing a class.

Apache-2.0 licensing, a recent push, and no GitHub releases

The licence field on the repository says Apache-2.0, and the project links the Apache License 2.0 text. That is a permissive licence with an explicit patent grant, and it carries the usual obligation to keep the licence and notices intact when you redistribute. This is not legal advice, and if you intend to vendor the source into a closed product, read the `LICENSE` file and the `SECURITY.md` file at the repository root rather than relying on a summary.

On the state of the project: the repository is not archived, and the last push was on 2026-10-01. That is recent, so the codebase is not a relic. There is a twist worth knowing before you plan an upgrade: the repository has no GitHub releases, so there is no tag list in the usual place to check what changed. The version history lives in the `release-notes/` directory instead, and the version you get from Maven Central is whatever the project last published there.

The status table also shows a CI build badge, a Maven Central artifact badge, Javadoc hosting, a code coverage badge for the 5.x line, an OpenSSF Scorecard badge and an OSS sponsorship listing through Tidelift. The presence of an explicit `SECURITY.md` and a coverage configuration aimed at 5.x suggests a maintainer who expects the current major line to be the one under active work.

Editorial conclusion

JUG is a good fit for Java services that need more than java.util.UUID.randomUUID, especially for version 7 identifiers, byte array serialization, or name-based hashes with a stable namespace. It is a poor fit for a project that wants one static helper with no dependency, or for a non-JVM stack. Before adopting it, confirm your runtime already carries an slf4j implementation, since JUG 4.x and up need the calling application to supply the binding, and check the version 7 generator you pick, because timeBasedEpochGenerator and timeBasedEpochRandomGenerator differ in how the random bits are drawn. The last push was on 2026-10-01 and the repository publishes no GitHub releases, so the version you consume is whatever Maven Central currently serves.

Frequently asked questions

How do I add JUG to a Maven project?

Add the dependency with groupId com.fasterxml.uuid, artifactId java-uuid-generator and the version you want; the README shows version 5.1.0 in its example block.

Does JUG need a logging implementation?

For versions 4.x and up, JUG uses the slf4j API and the documentation states that the logging implementation must be provided by the calling application. Up to 3.x, log4j was used as an optional runtime dependency.

What is the difference between timeBasedEpochGenerator and timeBasedEpochRandomGenerator?

Both produce version 7 values, which are Unix-timestamp plus random based with lexicographic ordering. The variation added in JUG 5.0 is the one that produces version 7 values with per-call random values.

Which UUID versions does JUG support?

Versions 1, 3, 4, 5, 6 and 7, following RFC-9562. Versions 1, 3, 4 and 5 are the classic RFC 4122 set, and 6 and 7 are the newer reordered and epoch-based variants.

Is JUG usable outside a Java application?

The documentation describes JUG as usable as a command-line tool via the class com.fasterxml.uuid.Jug, with the jar built under target/, as well as as a pluggable Java component.

Official sources

  1. cowtowncoder/java-uuid-generator on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cowtowncoder-java-uuid-generator.svg)](https://hysenlabs.com/projects/cowtowncoder-java-uuid-generator)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/cowtowncoder-java-uuid-generator.svg)](https://hysenlabs.com/projects/cowtowncoder-java-uuid-generator)

Was this useful?