Skip to content

Commit

Permalink
Merge pull request #243 from michalkurka/michalk_fix-j11-race
Browse files Browse the repository at this point in the history
JAVASSIST-242: Demonstrates a race condition in DefineClassHelper + proposed fix
  • Loading branch information
chibash committed Jan 27, 2019
2 parents 88a9d9b + 1b84304 commit 023f755
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
3 changes: 0 additions & 3 deletions src/main/javassist/util/proxy/DefineClassHelper.java
Expand Up @@ -219,9 +219,6 @@ Class<?> defineClass(String name, byte[] b, int off, int len, Class<?> neighbor,
if (e instanceof RuntimeException) throw (RuntimeException) e;
throw new CannotCompileException(e);
}
finally {
SecurityActions.setAccessible(defineClass, false);
}
}
}

Expand Down
3 changes: 0 additions & 3 deletions src/main/javassist/util/proxy/DefinePackageHelper.java
Expand Up @@ -128,9 +128,6 @@ Package definePackage(ClassLoader loader, String name, String specTitle,
}
if (e instanceof RuntimeException) throw (RuntimeException) e;
}
finally {
definePackage.setAccessible(false);
}
return null;
}
};
Expand Down
75 changes: 75 additions & 0 deletions src/test/javassist/ConcurrentClassDefinitionTest.java
@@ -0,0 +1,75 @@
package javassist;

import javassist.bytecode.ClassFile;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class ConcurrentClassDefinitionTest {

@Parameterized.Parameter
public int N;

@Parameterized.Parameters
public static Object[] data() {
return new Object[] {
1, // single threaded - should pass
Runtime.getRuntime().availableProcessors() * 2
};
}

@Test
public void showDefineClassRaceCondition() throws Exception{
Worker[] workers = new Worker[N];
for (int i = 0; i < N; i++) {
workers[i] = new Worker(N + "_ " + i, 100);
workers[i].start();
}
for (Worker w : workers) {
w.join();
}
for (Worker w : workers) {
if (w.e != null) {
throw w.e;
}
}
}

private static class Worker extends Thread {
String id;
int count;
Exception e;

Worker(String id, int count) {
this.id = id;
this.count = count;
}

@Override
public void run() {
try {
for (int i = 0; i < count; i++) {
Class c = makeClass(id + "_" + i);
assert c != null;
}
} catch (Exception e) {
this.e = e;
}
}

@Override
public void interrupt() {
super.interrupt();
}
}

private static Class makeClass(String id) throws Exception {
ClassFile cf = new ClassFile(
false, "com.example.JavassistGeneratedClass_" + id, null);
ClassPool classPool = ClassPool.getDefault();
return classPool.makeClass(cf).toClass();
}


}

0 comments on commit 023f755

Please sign in to comment.