aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2022-01-10 08:06:56 -0800
committerGitHub <noreply@github.com>2022-01-10 08:06:56 -0800
commit254ba9e8bb201a912a326277b29a602b0054a826 (patch)
treedc32d2132386d3c73f1fc56065631e46d6d20dd9
parent92779d0829d41d55cae300d4d4d5a67cff72916d (diff)
parent250aa63cb28f3915d32ad67b881bd1dad8222320 (diff)
downloadaspectj-254ba9e8bb201a912a326277b29a602b0054a826.tar.gz
aspectj-254ba9e8bb201a912a326277b29a602b0054a826.zip
Merge pull request #111 from kriegaex/release-198
Add test for Java 11 constant-dynamic
-rw-r--r--docs/dist/doc/README-198.html22
-rw-r--r--tests/bugs198/github_68/Application.java20
-rw-r--r--tests/bugs198/github_68/Generator.java67
-rw-r--r--tests/bugs198/github_68/MyAspect.aj5
-rw-r--r--tests/bugs198/github_68/condy.jarbin0 -> 515 bytes
-rw-r--r--tests/src/test/java/org/aspectj/systemtest/ajc198/AllTestsAspectJ198.java3
-rw-r--r--tests/src/test/java/org/aspectj/systemtest/ajc198/Bugs198Java11Tests.java32
-rw-r--r--tests/src/test/resources/org/aspectj/systemtest/ajc198/ajc198.xml13
8 files changed, 156 insertions, 6 deletions
diff --git a/docs/dist/doc/README-198.html b/docs/dist/doc/README-198.html
index 57165e5c0..7e30661da 100644
--- a/docs/dist/doc/README-198.html
+++ b/docs/dist/doc/README-198.html
@@ -89,12 +89,12 @@
<ul>
<li>
- The AspectJ compiler <tt>ajc</tt> (contained in the <tt>aspectjtools</tt> library) no longer works on JDKs 8 to 10. The minimum
- compile-time requirement is now JDK 11 due to upstream changes in the Eclipse Java Compiler (subset of JDT Core),
- which AspectJ is a fork of. You can still compile to legacy target versions as low as Java 1.3 when compiling plain
- Java code or using plain Java ITD constructs which do not require the AspectJ runtime <tt>aspectjrt</tt>, but the compiler
- itself needs JDK 11+. Just like in previous AspectJ versions, both the runtime <tt>aspectjrt</tt> and the load-time weaver
- <tt>aspectjweaver</tt> still only require JRE 8+.
+ The AspectJ compiler <tt>ajc</tt> (contained in the <tt>aspectjtools</tt> library) no longer works on JDKs 8 to 10.
+ The minimum compile-time requirement is now JDK 11 due to upstream changes in the Eclipse Java Compiler (subset of
+ JDT Core), which AspectJ is a fork of. You can still compile to legacy target versions as low as Java 1.3 when
+ compiling plain Java code or using plain Java ITD constructs which do not require the AspectJ runtime
+ <tt>aspectjrt</tt>, but the compiler itself needs JDK 11+. Just like in previous AspectJ versions, both the runtime
+ <tt>aspectjrt</tt> and the load-time weaver <tt>aspectjweaver</tt> still only require JRE 8+.
</li>
<li>Document build profiles and properties in <i>docs/developer/BUILD.md</i></li>
<li>Add a guide for setting up an AspectJ development environment in <i>docs/developer/IDE.md</i></li>
@@ -104,6 +104,16 @@
aspect library via <tt>-aspectpath</tt> in combination with introducing an annotation via ITD. This was broken since
version 1.9.5 and fixed in 1.9.8.RC3.
</li>
+ <li>
+ Fix <a href="https://github.com/eclipse/org.aspectj/issues/68">issue #68</a>: Correctly process class files
+ containing <a href="https://openjdk.java.net/jeps/309">dynamic class-file constants (JEP 309)</a>, which were
+ introduced in Java 11 and broken in AspectJ ever since their introduction in 1.9.2. Java itself currently does not
+ use "condy" and neither do other widespread JVM languages. Byte code engineering libraries like ASM or Byte Buddy
+ and some instrumentation tools like JaCoCo can however produce condy code. Therefore, in order to create a
+ regression test, we actually had to
+ <a href="https://github.com/eclipse/org.aspectj/blob/de63b63d/tests/bugs198/github_68/Generator.java#L50-L61">
+ craft a condy class with ASM</a>.
+ </li>
</ul>
<p>
diff --git a/tests/bugs198/github_68/Application.java b/tests/bugs198/github_68/Application.java
new file mode 100644
index 000000000..47eeaa4f4
--- /dev/null
+++ b/tests/bugs198/github_68/Application.java
@@ -0,0 +1,20 @@
+import java.lang.invoke.ConstantBootstraps;
+import java.util.concurrent.Callable;
+
+public class Application {
+ public static void main(String[] args) throws Exception {
+ Callable<?> first = new CondyCallable();
+ Callable<?> second = new CondyCallable();
+ if (!(first.call() == second.call()))
+ throw new RuntimeException("Non-identical ConstantDynamic values (should never happen)");
+ }
+
+ /**
+ * Class {@link CondyCallable} dispatches to this constructor via {@link ConstantBootstraps#invoke}
+ * in order to initialise a dynamic constant value. The constructor should be executed exactly once,
+ * no matter how many times {@link CondyCallable#call} is called.
+ */
+ public Application() {
+ System.out.println("Sample instance created");
+ }
+}
diff --git a/tests/bugs198/github_68/Generator.java b/tests/bugs198/github_68/Generator.java
new file mode 100644
index 000000000..ea34c5b3b
--- /dev/null
+++ b/tests/bugs198/github_68/Generator.java
@@ -0,0 +1,67 @@
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * This class was created by ASM-ifying a class generated by Byte Buddy.
+ * Its purpose it to create a class <tt>CondyCallable</tt> making use of
+ * dynamic class-file constants, a Java 11 feature introduced by JEP 309.
+ *
+ * @see https://openjdk.java.net/jeps/309
+ */
+public class Generator implements Opcodes {
+
+ private static final String CLASS_FILE = "CondyCallable.class";
+
+ public static void main(String[] args) throws IOException {
+ try (FileOutputStream fos = new FileOutputStream(CLASS_FILE)) {
+ fos.write(getClassBytes());
+ }
+ System.out.println(CLASS_FILE + " generated successfully");
+ }
+
+ private static byte[] getClassBytes() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(V11, ACC_PUBLIC | ACC_SUPER, "CondyCallable", null, "java/lang/Object", new String[] { "java/util/concurrent/Callable" });
+ createDefaultConstructor(classWriter);
+ createMethod_call(classWriter);
+ classWriter.visitEnd();
+ return classWriter.toByteArray();
+ }
+
+ private static void createDefaultConstructor(ClassWriter classWriter) {
+ MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+
+ private static void createMethod_call(ClassWriter classWriter) {
+ MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "call", "()Ljava/lang/Object;", null, new String[] { "java/lang/Exception" });
+ methodVisitor.visitCode();
+ methodVisitor.visitLdcInsn(
+ // Create constant-dynamic instruction
+ new ConstantDynamic(
+ // Dummy name
+ "_",
+ // Constant type
+ "LApplication;",
+ // Bootstrap method: ConstantBootstraps::invoke, dispatching to an existing method/constructor
+ new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/ConstantBootstraps", "invoke", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;", false),
+ // Bootstrap method arguments: here we simply dispatch to the constructor of class Application
+ new Handle(Opcodes.H_NEWINVOKESPECIAL, "Application", "<init>", "()V", false))
+ );
+ methodVisitor.visitInsn(ARETURN);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+
+}
diff --git a/tests/bugs198/github_68/MyAspect.aj b/tests/bugs198/github_68/MyAspect.aj
new file mode 100644
index 000000000..1a329dfa0
--- /dev/null
+++ b/tests/bugs198/github_68/MyAspect.aj
@@ -0,0 +1,5 @@
+public aspect MyAspect {
+ before() : execution(*.new(..)) && !within(MyAspect) {
+ System.out.println(thisJoinPoint);
+ }
+}
diff --git a/tests/bugs198/github_68/condy.jar b/tests/bugs198/github_68/condy.jar
new file mode 100644
index 000000000..75fe7e5b8
--- /dev/null
+++ b/tests/bugs198/github_68/condy.jar
Binary files differ
diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc198/AllTestsAspectJ198.java b/tests/src/test/java/org/aspectj/systemtest/ajc198/AllTestsAspectJ198.java
index 4aac84810..3cfc7a149 100644
--- a/tests/src/test/java/org/aspectj/systemtest/ajc198/AllTestsAspectJ198.java
+++ b/tests/src/test/java/org/aspectj/systemtest/ajc198/AllTestsAspectJ198.java
@@ -22,6 +22,9 @@ public class AllTestsAspectJ198 {
if (LangUtil.is9VMOrGreater()) {
suite.addTest(CompileWithReleaseTests.suite());
}
+ if (LangUtil.is11VMOrGreater()) {
+ suite.addTest(Bugs198Java11Tests.suite());
+ }
if (LangUtil.is17VMOrGreater()) {
suite.addTest(SanityTestsJava17.suite());
suite.addTest(Ajc198TestsJava.suite());
diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc198/Bugs198Java11Tests.java b/tests/src/test/java/org/aspectj/systemtest/ajc198/Bugs198Java11Tests.java
new file mode 100644
index 000000000..7e99b7d9f
--- /dev/null
+++ b/tests/src/test/java/org/aspectj/systemtest/ajc198/Bugs198Java11Tests.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ *******************************************************************************/
+package org.aspectj.systemtest.ajc198;
+
+import junit.framework.Test;
+import org.aspectj.testing.XMLBasedAjcTestCase;
+import org.aspectj.testing.XMLBasedAjcTestCaseForJava11OrLater;
+
+/**
+ * @author Alexander Kriegisch
+ */
+public class Bugs198Java11Tests extends XMLBasedAjcTestCaseForJava11OrLater {
+
+ public void testGitHub_68() {
+ runTest("correctly weave code using constant-dynamic");
+ }
+
+ public static Test suite() {
+ return XMLBasedAjcTestCase.loadSuite(Bugs198Java11Tests.class);
+ }
+
+ @Override
+ protected java.net.URL getSpecFile() {
+ return getClassResource("ajc198.xml");
+ }
+
+}
diff --git a/tests/src/test/resources/org/aspectj/systemtest/ajc198/ajc198.xml b/tests/src/test/resources/org/aspectj/systemtest/ajc198/ajc198.xml
index dfe86e2a9..202258c94 100644
--- a/tests/src/test/resources/org/aspectj/systemtest/ajc198/ajc198.xml
+++ b/tests/src/test/resources/org/aspectj/systemtest/ajc198/ajc198.xml
@@ -3,6 +3,19 @@
<suite>
+ <!-- https://github.com/eclipse/org.aspectj/issues/68 -->
+ <ajc-test dir="bugs198/github_68" vm="11" title="correctly weave code using constant-dynamic">
+ <compile files="Application.java MyAspect.aj" options="-11" inpath="condy.jar"/>
+ <run class="Application">
+ <stdout>
+ <line text="execution(CondyCallable())" />
+ <line text="execution(CondyCallable())" />
+ <line text="execution(Application())" />
+ <line text="Sample instance created" />
+ </stdout>
+ </run>
+ </ajc-test>
+
<!-- https://github.com/eclipse/org.aspectj/issues/105 -->
<ajc-test dir="bugs198/github_105" vm="8" title="ITD annotation with mandatory parameter via aspectpath">
<compile files="FooAnnotation.java BarAnnotation.java FooAspect.aj" options="-8" outjar="aspect.jar"/>