You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by mi...@apache.org on 2009/07/09 18:01:49 UTC

svn commit: r792592 - in /openjpa/trunk/openjpa-lib/src: main/java/org/apache/openjpa/lib/util/UUIDGenerator.java test/java/org/apache/openjpa/lib/util/TestUUIDGenerator.java

Author: mikedd
Date: Thu Jul  9 16:01:48 2009
New Revision: 792592

URL: http://svn.apache.org/viewvc?rev=792592&view=rev
Log:
OPENJPA-1168:
Improved checking for type1 UUID generator is initialized. Reducing
timing window which could result in a NPE.
Submitted by: Rick Curtis
	modified:   openjpa-lib/src/main/java/org/apache/openjpa/lib/util/UUIDGenerator.java
	modified:   openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestUUIDGenerator.java

Modified:
    openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/UUIDGenerator.java
    openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestUUIDGenerator.java

Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/UUIDGenerator.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/UUIDGenerator.java?rev=792592&r1=792591&r2=792592&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/UUIDGenerator.java (original)
+++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/UUIDGenerator.java Thu Jul  9 16:01:48 2009
@@ -94,15 +94,16 @@
     private static long _lastMillis = 0L;
     private static final int MAX_14BIT = 0x3FFF;
     private static short _seq = 0;
-        
+
+    private static boolean type1Initialized = false;
     /*
      * Initializer for type 1 UUIDs.  Creates random generator and genenerates
      * the node portion of the UUID using the IP address.
      */
-    private static synchronized void initializeForType1()
-    {
-        if (RANDOM != null)
+    private static synchronized void initializeForType1() {
+        if (type1Initialized == true) {
             return;
+        }
         // note that secure random is very slow the first time
         // it is used; consider switching to a standard random
         RANDOM = new SecureRandom();
@@ -118,6 +119,7 @@
         IP = new byte[6];
         RANDOM.nextBytes(IP);
         System.arraycopy(ip, 0, IP, 2, ip.length);        
+        type1Initialized = true;
     }
 
     /**
@@ -134,8 +136,9 @@
      * Creates a type 1 UUID 
      */
     public static byte[] createType1() {
-        if (RANDOM == null)
+        if (type1Initialized == false) {
             initializeForType1();
+        }
         // set ip addr
         byte[] uuid = new byte[16];
         System.arraycopy(IP, 0, uuid, 10, IP.length);

Modified: openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestUUIDGenerator.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestUUIDGenerator.java?rev=792592&r1=792591&r2=792592&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestUUIDGenerator.java (original)
+++ openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestUUIDGenerator.java Thu Jul  9 16:01:48 2009
@@ -18,6 +18,10 @@
  */
 package org.apache.openjpa.lib.util;
 
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -76,4 +80,35 @@
             time = newTime;
         }
     }
+    
+    public void testInitType1MultiThreaded() throws Exception {
+        // This test method depends IP and RANDOM in UUIDGenerator to be null
+        // and type1Initialized to be false. Using reflection to ensure that
+        // those fields are null. Wrap this  method in doPrivledgedAction so it
+        // doesn't fail when running with security.
+        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+            public Object run() throws Exception {
+                Class uuid = UUIDGenerator.class;
+                Field[] fields = uuid.getDeclaredFields();
+                for (Field f : fields) {
+                    if (f.getName().equals("type1Initialized")) {
+                        f.setAccessible(true);
+                        f.set(null, false);
+                    } else if (f.getName().equals("IP") || f.getName().equals("RANDOM")) {
+                        f.setAccessible(true);
+                        f.set(null, null);
+                    }
+                }
+                Thread t = new Thread() {
+                    public void run() {
+                        UUIDGenerator.createType1();
+                    }
+                };
+
+                t.start();
+                UUIDGenerator.createType1();
+                return null;
+            }
+        });
+    }// end testInitType1MultiThreaded
 }