forked from eclipse-aspectj/aspectj
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test "same class woven concurrently in parallel-capable classloader" reproduces eclipse-aspectj#279. Originally taken and modified from: https://gitlab.com/urisimchoni/aspectj-parallel-issue Co-authored-by: Uri Simchoni <urisimchoni@gmail.com> Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
- Loading branch information
1 parent
37bee45
commit cd8e8a1
Showing
9 changed files
with
151 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
/** | ||
* https://github.com/eclipse-aspectj/aspectj/issues/279 | ||
*/ | ||
public class Application { | ||
public static AtomicInteger HELLO_COUNT = new AtomicInteger(0); | ||
public static AtomicInteger ASPECT_COUNT = new AtomicInteger(0); | ||
|
||
private static final int ROUNDS = 25; | ||
private static final int THREAD_COUNT = 2; | ||
private static final int TOTAL_COUNT = ROUNDS * THREAD_COUNT; | ||
private static final String CLASS_TO_LOAD = "GreeterImpl"; | ||
|
||
public static void main(String[] args) throws Exception { | ||
for (int round = 0; round < ROUNDS; round++) { | ||
ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT); | ||
ParallelCapableClassLoader cl = new ParallelCapableClassLoader(Application.class.getClassLoader(), CLASS_TO_LOAD); | ||
for (int i = 0; i < THREAD_COUNT; i++) { | ||
executor.submit(() -> { | ||
try { | ||
Class<?> myClass = Class.forName(CLASS_TO_LOAD, true, cl); | ||
Greeter greeter = (Greeter) myClass.getConstructor(new Class<?>[] {}).newInstance(); | ||
greeter.hello(); | ||
HELLO_COUNT.incrementAndGet(); | ||
} | ||
catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
}); | ||
} | ||
executor.shutdown(); | ||
executor.awaitTermination(60, TimeUnit.SECONDS); | ||
} | ||
|
||
assert HELLO_COUNT.get() == TOTAL_COUNT | ||
: String.format("Hello count should be %s, but is %s", TOTAL_COUNT, HELLO_COUNT.get()); | ||
assert ASPECT_COUNT.get() == TOTAL_COUNT | ||
: String.format("Aspect count should be %s, but is %s", TOTAL_COUNT, ASPECT_COUNT.get()); | ||
} | ||
} |
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,3 @@ | ||
public interface Greeter { | ||
String hello(); | ||
} |
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,6 @@ | ||
public class GreeterImpl implements Greeter { | ||
@Override | ||
public String hello() { | ||
return "World!"; | ||
} | ||
} |
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,12 @@ | ||
import org.aspectj.lang.ProceedingJoinPoint; | ||
import org.aspectj.lang.annotation.Around; | ||
import org.aspectj.lang.annotation.Aspect; | ||
|
||
@Aspect | ||
public class HelloInterceptor { | ||
@Around("execution(public String Greeter.hello())") | ||
public Object interceptHello(ProceedingJoinPoint pjp) throws Throwable { | ||
Application.ASPECT_COUNT.incrementAndGet(); | ||
return pjp.proceed(); | ||
} | ||
} |
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,56 @@ | ||
import java.io.ByteArrayOutputStream; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
|
||
public class ParallelCapableClassLoader extends ClassLoader { | ||
private final ClassLoader delegate; | ||
private final String classNameToHandle; | ||
|
||
static { | ||
if (!ClassLoader.registerAsParallelCapable()) | ||
throw new RuntimeException("Failed to register " + ParallelCapableClassLoader.class.getName() + " as parallel-capable"); | ||
} | ||
|
||
public ParallelCapableClassLoader(ClassLoader delegate, String classNameToHandle) { | ||
this.delegate = delegate; | ||
this.classNameToHandle = classNameToHandle; | ||
} | ||
|
||
@Override | ||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { | ||
Class<?> c = this.findLoadedClass(name); | ||
if (c == null && name.equals(classNameToHandle)) { | ||
byte[] bytes = getClassBytes(name); | ||
try { | ||
c = defineClass(name, bytes, 0, bytes.length); | ||
} | ||
catch (LinkageError e) { | ||
c = findLoadedClass(name); | ||
if (c == null) | ||
throw e; | ||
} | ||
} | ||
if (c == null) | ||
c = delegate.loadClass(name); | ||
if (resolve) | ||
this.resolveClass(c); | ||
return c; | ||
} | ||
|
||
private byte[] getClassBytes(String name) { | ||
String classFilePath = name.replace('.', File.separatorChar) + ".class"; | ||
try (InputStream inputStream = delegate.getResourceAsStream(classFilePath)) { | ||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | ||
int bytesRead; | ||
byte[] buffer = new byte[4096]; | ||
while ((bytesRead = inputStream.read(buffer)) != -1) { | ||
outputStream.write(buffer, 0, bytesRead); | ||
} | ||
return outputStream.toByteArray(); | ||
} | ||
catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
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,15 @@ | ||
<!-- ajc-ant script, not to be used from Ant commant line - see AntSpec --> | ||
<project name="ltw"> | ||
<target name="same class woven concurrently in parallel-capable classloader"> | ||
<copy file="${aj.root}/tests/bugs1921/github_279/aop.xml" tofile="${aj.sandbox}/META-INF/aop.xml"/> | ||
<java fork="yes" classname="Application" failonerror="yes"> | ||
<classpath refid="aj.path"/> | ||
<jvmarg value="-ea"/> | ||
<!-- use META-INF/aop.xml style --> | ||
<jvmarg value="-javaagent:${aj.root}/lib/test/loadtime5.jar"/> | ||
<!--<jvmarg value="${aj.addOpensKey}"/>--> | ||
<!--<jvmarg value="${aj.addOpensValue}"/>--> | ||
</java> | ||
</target> | ||
|
||
</project> |
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,5 @@ | ||
<aspectj> | ||
<aspects> | ||
<aspect name="HelloInterceptor"/> | ||
</aspects> | ||
</aspectj> |
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