]> source.dussan.org Git - aspectj.git/commitdiff
Add test for Java 11 constant-dynamic
authorAlexander Kriegisch <Alexander@Kriegisch.name>
Sat, 8 Jan 2022 09:06:51 +0000 (16:06 +0700)
committerAlexander Kriegisch <Alexander@Kriegisch.name>
Sat, 8 Jan 2022 09:06:51 +0000 (16:06 +0700)
Relates to #68.

Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
tests/bugs198/github_68/Application.java [new file with mode: 0644]
tests/bugs198/github_68/Generator.java [new file with mode: 0644]
tests/bugs198/github_68/MyAspect.aj [new file with mode: 0644]
tests/bugs198/github_68/condy.jar [new file with mode: 0644]
tests/src/test/java/org/aspectj/systemtest/ajc198/AllTestsAspectJ198.java
tests/src/test/java/org/aspectj/systemtest/ajc198/Bugs198Java11Tests.java [new file with mode: 0644]
tests/src/test/resources/org/aspectj/systemtest/ajc198/ajc198.xml

diff --git a/tests/bugs198/github_68/Application.java b/tests/bugs198/github_68/Application.java
new file mode 100644 (file)
index 0000000..47eeaa4
--- /dev/null
@@ -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 (file)
index 0000000..ea34c5b
--- /dev/null
@@ -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 (file)
index 0000000..1a329df
--- /dev/null
@@ -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 (file)
index 0000000..75fe7e5
Binary files /dev/null and b/tests/bugs198/github_68/condy.jar differ
index 4aac8481041a4e9b6f9554959c883fa84a23e250..3cfc7a149e9028779d93a0f88af5798ace631967 100644 (file)
@@ -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 (file)
index 0000000..7e99b7d
--- /dev/null
@@ -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");
+  }
+
+}
index dfe86e2a91decbac70e4174002fff850e1b8b43a..202258c94c9684c71648415b5fd151673dd4c3d7 100644 (file)
@@ -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"/>