From 12d0a8268abb5100d7982e5be13c6cb0f8cdbf83 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Wed, 18 Nov 2015 14:43:41 -0800 Subject: [PATCH] Fix 478003: declare parents with generic itd npe --- docs/dist/doc/README-187.html | 101 +++++++++++++++++- tests/bugs188/478003/OrientDBKeyIO.java | 22 ++++ .../systemtest/ajc188/Ajc188Tests.java | 42 ++++++++ .../systemtest/ajc188/AllTestsAspectJ188.java | 26 +++++ .../org/aspectj/systemtest/ajc188/ajc188.xml | 9 ++ .../aspectj/weaver/bcel/BcelTypeMunger.java | 7 +- 6 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 tests/bugs188/478003/OrientDBKeyIO.java create mode 100644 tests/src/org/aspectj/systemtest/ajc188/Ajc188Tests.java create mode 100644 tests/src/org/aspectj/systemtest/ajc188/AllTestsAspectJ188.java create mode 100644 tests/src/org/aspectj/systemtest/ajc188/ajc188.xml diff --git a/docs/dist/doc/README-187.html b/docs/dist/doc/README-187.html index cde9934e3..1d9b28c24 100644 --- a/docs/dist/doc/README-187.html +++ b/docs/dist/doc/README-187.html @@ -27,9 +27,106 @@ All rights reserved.
  • 1.8.7 available 9-Sep-2015 - + +

    ajdoc

    +

    The ajdoc tool has been fixed! It is now working again if run on a 1.7 JDK.

    + +

    Dynamic weaver attachment

    +

    The AspectJ loadtime weaving agent can now be dynamically attached to a JVM after it has started +(you don't need to use -javaagent). This offers extra flexibility but obviously any +classes loaded before attachment will not be woven.

    + +

    Here is a simple aspect:

    +
    +public aspect Azpect {
    +  before(): execution(* *(..)) {
    +    System.out.println(thisJoinPointStaticPart);
    +  }
    +}
    +
    + +

    Compiled via:

    + +
    ajc -1.8 Azpect.java -outxml
    + +

    This produces a compiled class Azpect.class and a file META-INF/aop-ajc.xml.

    + +

    I then have this sample application (same directory):

    + +
    +import java.lang.management.ManagementFactory;
    +import org.aspectj.weaver.loadtime.Agent;
    +import com.sun.tools.attach.VirtualMachine;
    +
    +public class Application {
    +
    +  public static void main(String[] args) {
    +    if (!isAspectJAgentLoaded())
    +      System.err.println("WARNING: AspectJ weaving agent not loaded");
    +    new Sample().doSomething();
    +  }
    +
    +  public static boolean isAspectJAgentLoaded() {
    +    try {
    +      Agent.getInstrumentation();
    +    } catch (NoClassDefFoundError e) {
    +      System.out.println(e);
    +      return false;
    +    } catch (UnsupportedOperationException e) {
    +      System.out.println(e);
    +      return dynamicallyLoadAspectJAgent();
    +    }
    +    return true;
    +  }
    +
    +  public static boolean dynamicallyLoadAspectJAgent() {
    +    String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
    +    int p = nameOfRunningVM.indexOf('@');
    +    String pid = nameOfRunningVM.substring(0, p);
    +    try {
    +      VirtualMachine vm = VirtualMachine.attach(pid);
    +      String jarFilePath = System.getProperty("AGENT_PATH");
    +      vm.loadAgent(jarFilePath);
    +      vm.detach();
    +    } catch (Exception e) {
    +      System.out.println(e);
    +      return false;
    +    }
    +    return true;
    +  }
    +}
    +
    + +

    And this Sample class:

    +
    +public class Sample {
    +	public void doSomething() {
    +		System.out.println("Do something");
    +		System.out.println("Square of 7 = " + square(7));
    +	}
    +
    +	private int square(int i) {
    +		return i * i;
    +	}
    +}
    +
    + +

    Compile these with javac, but you must have the aspectjweaver and the JDK tools.jar on your classpath.

    + +

    Once compiled we can run it:

    + +
    java -DAGENT_PATH=<path-to>/aspectjweaver.jar Application
    + +

    What does it do? The main method calls the function that detects whether the agent is attached, if it is not then +it programmatically attaches it using the VirtualMachine class. Then the main method accesses the +Sample class. At this point in program execution the Sample class is loaded and because the agent has been +attached it gets woven. Notice that the Application class itself is not woven because it was loaded prior +to agent attachment.

    + +

    Thanks to Alexander Kriegisch for the sample code and the patch to add this behaviour to AspectJ.

    + diff --git a/tests/bugs188/478003/OrientDBKeyIO.java b/tests/bugs188/478003/OrientDBKeyIO.java new file mode 100644 index 000000000..2397ae8d2 --- /dev/null +++ b/tests/bugs188/478003/OrientDBKeyIO.java @@ -0,0 +1,22 @@ +//import com.flickbay.orientdb.OrientKey; + +class OrientKey { +} + +class SimpleOrientDBValue extends OrientDBValue {} +class OrientDBValue {} + +public aspect OrientDBKeyIO { + + public interface IO { + OrientDBValue getOrientDBValue(); + } + + declare parents : OrientKey implements IO; + + public SimpleOrientDBValue OrientKey.value = null; + + public OrientDBValue OrientKey.getOrientDBValue() { return this.value; } + +} + diff --git a/tests/src/org/aspectj/systemtest/ajc188/Ajc188Tests.java b/tests/src/org/aspectj/systemtest/ajc188/Ajc188Tests.java new file mode 100644 index 000000000..11c503a89 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc188/Ajc188Tests.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2014 Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +package org.aspectj.systemtest.ajc188; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +import junit.framework.Test; + +import org.aspectj.testing.XMLBasedAjcTestCase; + +/** + * @author Andy Clement + */ +public class Ajc188Tests extends org.aspectj.testing.XMLBasedAjcTestCase { + + public void testCompileError_478003() throws Exception { + runTest("compile error"); + } + + // --- + + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(Ajc188Tests.class); + } + + @Override + protected File getSpecFile() { + return getClassResource("ajc188.xml"); + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc188/AllTestsAspectJ188.java b/tests/src/org/aspectj/systemtest/ajc188/AllTestsAspectJ188.java new file mode 100644 index 000000000..8867d9174 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc188/AllTestsAspectJ188.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2014 Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +package org.aspectj.systemtest.ajc188; + +import junit.framework.Test; +import junit.framework.TestSuite; +import org.aspectj.systemtest.apt.AptTests; + +public class AllTestsAspectJ188 { + + public static Test suite() { + TestSuite suite = new TestSuite("AspectJ 1.8.8 tests"); + // $JUnit-BEGIN$ + suite.addTest(Ajc188Tests.suite()); + // $JUnit-END$ + return suite; + } +} diff --git a/tests/src/org/aspectj/systemtest/ajc188/ajc188.xml b/tests/src/org/aspectj/systemtest/ajc188/ajc188.xml new file mode 100644 index 000000000..cc1214c18 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc188/ajc188.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 7a637bb2d..8d5d26499 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -375,7 +375,12 @@ public class BcelTypeMunger extends ConcreteTypeMunger { // for that type if (m.isTargetTypeParameterized()) { ResolvedType genericOnType = getWorld().resolve(sig.getDeclaringType()).getGenericType(); - m = m.parameterizedFor(newParent.discoverActualOccurrenceOfTypeInHierarchy(genericOnType)); + ResolvedType actualOccurrence = newParent.discoverActualOccurrenceOfTypeInHierarchy(genericOnType); + if (actualOccurrence == null) { + // Handle the case where the ITD is onto the type targeted by the declare parents (PR478003) + actualOccurrence = newParentTarget.getType().discoverActualOccurrenceOfTypeInHierarchy(genericOnType); + } + m = m.parameterizedFor(actualOccurrence); // possible sig change when type parameters filled in sig = m.getSignature(); } -- 2.39.5