public class GUIDGenerator
- extends java.lang.Object
This GUID generator can be safely pooled on a single machine and deployed in a cluster to
provide completely scalable performance.
The problem of generating unique IDs can essentially be broken down
as uniqueness over space and uniqueness over time which, when combined,
produces a globally unique sequence.
Taking the UUID and GUID Internet standards draft for the Network Working
Group by Paul J. Leach, Microsoft, and Rich Salz, Certco, as a starting
point we assume that the GUID be represented as a 36-digit alphanumeric
(including hyphens) of the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
The first 20 characters represent the uniqueness over time
(the low 32-bits of the time stamp as the first 8, the next 4 as the
mid 16 bits of the time stamp, the next 4 as the high value of the time
stamp multiplexed with the version, and the next 4 a combination of the
lock sequence high -multiplexed with the variant field - and the low bits)
Note: The internet guidelines suggest the timestamp as a 60-bit value to
a precision of 100ns since 00:00:00.00, 15 October 1582
(the date of Gregorian reform to the Christian calendar)
The last 12 characters are a 48-bit node identifier usually implemented
as the IEEE 802 address, which gives uniqueness over space.
These are combined to produce a unique sequence.
Some of the main problems in an EJB implementation of this technique are: -
- 1) there is no access to the traditional IEEE 802 address.
- 2) more than one object can exist at the same time and so
generate the same time stamp at a granularity of a millisecond
(Java's timestamp granularity).
- 3) a clock sequence or equivalent is used as a way of reading/writing
a value to storage (e.g. a database or system file) that can be used in case
the clock is set backwards and as a seed for the number sequence.
This is even more of a problem when a cluster of machines do not use the
- 4) Singletons are not portable and not recommended in the EJB specs.
The GUID is constucted by.
1) (1-8 hex characters) use the low 32 bits of System.currentTimeMillis().
Note: could use the recommended date format by adding 12219292800000L to the
system time long before grabbing the low 32 bits.
This gives us a uniqueness of a millisecond -
therefore any clashing object will have to be generated within the same
2) (9-16 hex characters) the IP address of the machine as a hex
representation of the 32 bit integer underlying IP -
gives us a spatial uniqueness to a single machine -
guarantees that these characters will be different for machines in a
cluster or on a LAN. Note: This is not appropriate for a global addressing scheme
to distinguish java objects in any JVM on the Internet.
3) (17-24 hex characters) the hex value of the Stateless Session bean
object's hashCode (a 32 bit int) - in the Java language spec -
the hashcode value of Object is defined as -
As much as is reasonably practical, the hashCode method defined by class
object does return distinct integers for distinct objects.
(This is typically implemented by converting the internal address of the
object into an integer, but this implementation technique is not required by
the Java programming language.)**
4) (25-32 hex characters) a random 32 bit integer generated for each method
invocation from the SecureRandom java class using SecureRandom.nextInt().
This method produces a cryptographically strong pseudo-random integer.
The Java lang defines this as -
Returns a pseudo-random, uniformly distributed int value drawn from this
random number generator's sequence. The general contract of nextInt is that
one int value in the specified range is pseudorandomly generated and
returned. All n possible int values are produced with (approximately)
This gives us a value that is a combination of
1) is unique to the millisecond
- 2) is unique to the machine
- 3) is unique to the object creating it
- 4) is unique to the method call for the same object
Note: the potential theoretical conflicts are:
- 1) that two objects on the same machine are assigned the exact same hashCode
(I do not know of any implementations that do this but there may be some out
there) and at the same millisecond must also get the same integer value from
the SecureRandom implementation.
- 2) The same int value is returned from the SecureRandom object in subsequent
method calls for the same object in the same millisecond.
- 3) A reset clock (which would require a redeployment of the bean) will
produce an identical hashcode for the new deployment as a previous one
AND the random values will have to be the same in the same repeated
millisecond value as in a previous sequence.
- Steve Woodcock
Used to provide a UUID that does not conform to the GUID RFC.
Returns a UUID formated according to the draft internet standard.
|Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
- Creates new GUIDGenerator
public java.lang.String getUnformatedUUID()
Used to provide a UUID that does not conform to the GUID RFC. The String
returned does not have the xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format
instead it is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. This is to provide a shorter
version of the UUID for easier database manipulation.
However, it is recommended that th full format be used.
- A String representing a UUID in the format xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Each character in the string is a hexadecimal.
java.rmi.RemoteException - Required to be thrown by the EJB specification.
public java.lang.String getUUID()
Returns a UUID formated according to the draft internet standard. See
the class level documentation for more details.
- A String representing a UUID in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Copyright © 2002-2006 Grape Design Limited. All Rights Reserved.