[JAVA-279] ObjectId could generate duplicate ids if used in different classloader Created: 22/Feb/11  Updated: 17/Mar/11  Resolved: 22/Feb/11

Status: Closed
Project: Java Driver
Component/s: None
Affects Version/s: 2.4
Fix Version/s: 2.5

Type: Bug Priority: Minor - P4
Reporter: Simone Gianni Assignee: Antoine Girbal
Resolution: Fixed Votes: 0
Labels: None
Environment:

Any JVM, Any OS


# Replies: 3
Participants:
Days since reply: 7 years, 17 weeks, 5 days ago
Date of 1st Reply:
Last commenter: Rathi Gnanasekaran
Last comment by Customer: true

 Description   

ObjectId currently uses timestamp and a machine id obtained using network stuff and a third part obtained trying to get the "name" of the currently running JVM.

These three elements will always return the same tuple, in the same second, for the same virtual machine (as long as the RuntimeMXBean is available).

Unfortunately, it will return the same tuple if two different classloaders (say, two different webapps) are active in the same JVM.

The fourth element, the progressive counter, is taken from a static variable, so it's relative to the single classloader, not the entire JVM.

This means that ObjectId could create two identical IDs if called from two different webapps, when both webapps try to write during the same second. If this happens on the same collection, this will cause errors.

It seems like a very rare situation, but unfortunately it seems like this happened to me a couple of times, cause I was experimenting on using MongoDB to collect informations from different webapps, some of them running on the same Tomcat instance, and all writing more or less at the same time a log message on the same collection of the same db. The log message was to log that they were starting.

The collision happened while the counter was rather low (below 100), probably on the long run the different counters in different classloaders will tend to diverge, but it's still a matter of randomness.

A simple solution could be to add (xor or whatever) the System.identitiyHashCode of the current classloader to the processPiece, considering that in the progressive counter is relative to the classloader and that in a multiple classloader setup (like a web server) the closest match for "process context" is actually the classloader.



 Comments   
Comment by Antoine Girbal [ 22/Feb/11 ]

thanks for report, that is important to fix.
Implemented a fix where machine id is contructed as:

  • 2 byte: hardware id based on a hash of string. String is concatenation of NICs description
  • 2 byte: process id based on a hash of string. String is concatenation of process number and class loader hashcode.
Comment by auto [ 23/Feb/11 ]

Author:

{u'login': u'agirbal', u'name': u'agirbal', u'email': u'antoine@10gen.com'}

Message: JAVA-279: ObjectId could generate duplicate ids if used in different classloader
https://github.com/mongodb/mongo-java-driver/commit/de72e9cc320e1f342a21f91e425ad5c1a413c673

Comment by Simone Gianni [ 24/Feb/11 ]

Great, thanks Antoine!

Generated at Wed Jun 20 07:49:13 UTC 2018 using JIRA 7.8.2#78002-sha1:944b71ecbe2e09c23503821098ef280c785b44a8.