You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/01/30 15:17:37 UTC
svn commit: r501401 - in /harmony/enhanced:
classlib/trunk/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java
Author: varlax
Date: Tue Jan 30 06:17:35 2007
New Revision: 501401
URL: http://svn.apache.org/viewvc?view=rev&rev=501401
Log:
Fixed:
HARMONY-1939 [drlvm][classlib] loadClass method in ClassLoader is not synchronized
HARMONY-2736 [drlvm][kernel] j.l.ClassLoader.definePackage() is not thread-safe
Tested on SUSE10@ia32
Modified:
harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java
Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java?view=diff&rev=501401&r1=501400&r2=501401
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java Tue Jan 30 06:17:35 2007
@@ -53,6 +53,106 @@
Policy.setPolicy(back);
}
}
+
+ static class SyncTestClassLoader extends ClassLoader {
+ Object lock;
+ volatile int numFindClassCalled;
+
+ SyncTestClassLoader(Object o) {
+ this.lock = o;
+ numFindClassCalled = 0;
+ }
+
+ /*
+ * Byte array of bytecode equivalent to the following source code:
+ * public class TestClass {
+ * }
+ */
+ private byte[] classData = new byte[] {
+ -54, -2, -70, -66, 0, 0, 0, 49, 0, 13,
+ 10, 0, 3, 0, 10, 7, 0, 11, 7, 0,
+ 12, 1, 0, 6, 60, 105, 110, 105, 116, 62,
+ 1, 0, 3, 40, 41, 86, 1, 0, 4, 67,
+ 111, 100, 101, 1, 0, 15, 76, 105, 110, 101,
+ 78, 117, 109, 98, 101, 114, 84, 97, 98, 108,
+ 101, 1, 0, 10, 83, 111, 117, 114, 99, 101,
+ 70, 105, 108, 101, 1, 0, 14, 84, 101, 115,
+ 116, 67, 108, 97, 115, 115, 46, 106, 97, 118,
+ 97, 12, 0, 4, 0, 5, 1, 0, 9, 84,
+ 101, 115, 116, 67, 108, 97, 115, 115, 1, 0,
+ 16, 106, 97, 118, 97, 47, 108, 97, 110, 103,
+ 47, 79, 98, 106, 101, 99, 116, 0, 33, 0,
+ 2, 0, 3, 0, 0, 0, 0, 0, 1, 0,
+ 1, 0, 4, 0, 5, 0, 1, 0, 6, 0,
+ 0, 0, 29, 0, 1, 0, 1, 0, 0, 0,
+ 5, 42, -73, 0, 1, -79, 0, 0, 0, 1,
+ 0, 7, 0, 0, 0, 6, 0, 1, 0, 0,
+ 0, 1, 0, 1, 0, 8, 0, 0, 0, 2,
+ 0, 9 };
+
+ protected Class findClass(String name) throws ClassNotFoundException {
+ try {
+ synchronized (lock) {
+ lock.wait();
+ }
+ } catch (InterruptedException ie) {}
+
+ if (name.equals("TestClass")) {
+ numFindClassCalled++;
+ return defineClass(null, classData, 0, classData.length);
+ } else {
+ throw new ClassNotFoundException("Class " + name + " not found.");
+ }
+ }
+ }
+
+ static class SyncLoadTestThread extends Thread {
+ volatile boolean started;
+ ClassLoader cl;
+ Class cls;
+
+ SyncLoadTestThread(ClassLoader cl) {
+ this.cl = cl;
+ }
+
+ public void run() {
+ try {
+ started = true;
+ cls = Class.forName("TestClass", false, cl);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Regression test for HARMONY-1939:
+ * 2 threads simultaneously run Class.forName() method for the same classname
+ * and the same classloader. It is expected that both threads succeed but
+ * class must be defined just once.
+ */
+ public void test_loadClass_concurrentLoad() throws Exception
+ {
+ Object lock = new Object();
+ SyncTestClassLoader cl = new SyncTestClassLoader(lock);
+ SyncLoadTestThread tt1 = new SyncLoadTestThread(cl);
+ SyncLoadTestThread tt2 = new SyncLoadTestThread(cl);
+ tt1.start();
+ tt2.start();
+
+ while (!tt1.started && !tt2.started) {
+ Thread.sleep(100);
+ }
+
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ tt1.join();
+ tt2.join();
+
+ assertSame("Bad or redefined class", tt1.cls, tt2.cls);
+ assertEquals("Both threads tried to define class", 1, cl.numFindClassCalled);
+ }
/**
* @tests java.lang.ClassLoader#getResource(java.lang.String)
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java?view=diff&rev=501401&r1=501400&r2=501401
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java Tue Jan 30 06:17:35 2007
@@ -425,16 +425,16 @@
String implTitle, String implVersion,
String implVendor, URL sealBase)
throws IllegalArgumentException {
- if (getPackage(name) != null) {
- throw new IllegalArgumentException("Package " + name
- + "has been already defined.");
- }
- Package pkg = new Package(this, name, specTitle, specVersion, specVendor,
- implTitle, implVersion, implVendor, sealBase);
synchronized (definedPackages) {
+ if (getPackage(name) != null) {
+ throw new IllegalArgumentException("Package " + name
+ + "has been already defined.");
+ }
+ Package pkg = new Package(this, name, specTitle, specVersion, specVendor,
+ implTitle, implVersion, implVendor, sealBase);
definedPackages.put(name, pkg);
+ return pkg;
}
- return pkg;
}
/**
@@ -518,7 +518,7 @@
/**
* @com.intel.drl.spec_ref
*/
- protected Class<?> loadClass(String name, boolean resolve)
+ protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
checkInitialized();
Class<?> clazz = findLoadedClass(name);