<li>1.8.7 available 9-Sep-2015
</ul>
-<!--
+
<h2>Notable changes</h2>
--->
+
+<h3>ajdoc</h3>
+<p>The ajdoc tool has been fixed! It is now working again if run on a 1.7 JDK.</p>
+
+<h3>Dynamic weaver attachment</h3>
+<p>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.</p>
+
+<p>Here is a simple aspect:</p>
+<code><pre>
+public aspect Azpect {
+ before(): execution(* *(..)) {
+ System.out.println(thisJoinPointStaticPart);
+ }
+}
+</pre></code>
+
+<p>Compiled via:</p>
+
+<code><pre>ajc -1.8 Azpect.java -outxml</pre></code>
+
+<p>This produces a compiled class <tt>Azpect.class</tt> and a file <tt>META-INF/aop-ajc.xml</tt>.</p>
+
+<p>I then have this sample application (same directory):</p>
+
+<code><pre>
+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;
+ }
+}
+</pre></code>
+
+<p>And this Sample class:</p>
+<code><pre>
+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;
+ }
+}
+</pre></code>
+
+<p>Compile these with javac, <b>but you must have the aspectjweaver and the JDK tools.jar on your classpath</b>.</p>
+
+<p>Once compiled we can run it:</p>
+
+<code><pre>java -DAGENT_PATH=<path-to>/aspectjweaver.jar Application</pre></code>
+
+<p>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 <tt>VirtualMachine</tt> 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 <tt>Application</tt> class itself is not woven because it was loaded prior
+to agent attachment.</p>
+
+<p>Thanks to Alexander Kriegisch for the sample code and the patch to add this behaviour to AspectJ.</p>
+
<!-- ============================== -->
</body>
--- /dev/null
+//import com.flickbay.orientdb.OrientKey;
+
+class OrientKey<T> {
+}
+
+class SimpleOrientDBValue extends OrientDBValue {}
+class OrientDBValue<T> {}
+
+public aspect OrientDBKeyIO {
+
+ public interface IO<T> {
+ OrientDBValue<T> getOrientDBValue();
+ }
+
+ declare parents : OrientKey implements IO;
+
+ public SimpleOrientDBValue OrientKey<T>.value = null;
+
+ public OrientDBValue OrientKey<T>.getOrientDBValue() { return this.value; }
+
+}
+
--- /dev/null
+/*******************************************************************************
+ * 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");
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>
+
+<suite>
+
+<ajc-test dir="bugs188/478003" title="compile error">
+<compile files="OrientDBKeyIO.java" options="-1.8"/>
+</ajc-test>
+
+</suite>
// 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();
}