Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #243 from michalkurka/michalk_fix-j11-race
JAVASSIST-242: Demonstrates a race condition in DefineClassHelper + proposed fix
- Loading branch information
Showing
3 changed files
with
75 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} | ||
|
||
|
||
} |