* Time text set by build script using SIMPLE_DATE_FORMAT.
* (if DEVELOPMENT version, invalid)
*/
- public static final String time_text = "";
+ public static final String time_text = "mardi juil. 5, 2005 at 09:56:18 GMT";
/**
* time in seconds-since-... format, used by programmatic clients.
public static final long time;
/** format used by build script to set time_text */
- public static final String SIMPLE_DATE_FORMAT = "MM/dd/yy 'at' hh:mm:ss z";
+ public static final String SIMPLE_DATE_FORMAT = "EEEE MMM d, yyyy 'at' HH:mm:ss z";
// if not DEVELOPMENT version, read time text using format used to set time
static {
long foundTime = NOTIME;
- if (!DEVELOPMENT.equals(text)) {
- try {
- SimpleDateFormat format = new SimpleDateFormat(SIMPLE_DATE_FORMAT);
- ParsePosition pos = new ParsePosition(0);
- Date date = format.parse(time_text, pos);
- foundTime = date.getTime();
- } catch (Throwable t) {
- }
- }
+ try {
+ SimpleDateFormat format = new SimpleDateFormat(SIMPLE_DATE_FORMAT);
+ ParsePosition pos = new ParsePosition(0);
+ Date date = format.parse(time_text, pos);
+ foundTime = date.getTime();
+ } catch (Throwable t) {
+ }
time = foundTime;
}
</informaltable>
</sect2>
</sect1>
+
+ <sect1 id="ltw-specialcases">
+ <title>Special cases</title>
+ <para>
+ Those classes are not exposed to the LTW infrastructure, no matter
+ the configuration of the <literal>aop.xml</literal> file(s):
+ <itemizedlist>
+ <listitem>All <literal>org.aspectj.*</literal> classes (and subpackages) - as those are needed by the infrastructure itself</listitem>
+ <listitem>All <literal>java.*</literal> and <literal>javax.*</literal> classes (and subpackages)</listitem>
+ <listitem>All <literal>sun.reflect.*</literal> classes - as those are JDK specific classes used when reflective calls occurs</listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Despite those special cases, it is perfectly possible to have call pointcut on those classes members providing the callee
+ class is not itself a speciall case, as well as execution pointcut on subclasses of those providing subclasses are not themselves
+ a special case.
+ </para>
+ <para>
+ It is also worth understanding that dynamic proxy representations are exposed to the LTW infrastructure and are not considered
+ a special case.
+ </para>
+ </sect1>
<sect1 id="ltw-packaging">
<title>Runtime Requirements for Load-time Weaving</title>
value="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"/>
<target name="compile:javac">
- <!-- compile only javac compilable stuff -->
+ <!-- compile only javac compilable stuff, exclude the one that needs other dependencies -->
<javac destdir="${aj.sandbox}" classpathref="aj.path"
srcdir="${basedir}"
includes="ataspectj/*"
+ excludes="ataspectj/UnweavableTest.java"
debug="true">
</javac>
</target>
<jvmarg value="-Daj5.def=ataspectj/ltwlog/aop-verboseandshow.xml"/>
</java>
</target>
+
+ <target name="ltw.Unweavable">
+ <javac destdir="${aj.sandbox}"
+ srcdir="${basedir}"
+ includes="ataspectj/UnweavableTest.java, ataspectj/TestHelper.java"
+ debug="true">
+ <classpath>
+ <path refid="aj.path"/>
+ <pathelement path="${aj.root}/lib/asm/asm-2.0.jar"/>
+ </classpath>
+ </javac>
+ <java fork="yes" classname="ataspectj.UnweavableTest" failonerror="yes">
+ <classpath>
+ <path refid="aj.path"/>
+ <pathelement path="${aj.root}/lib/asm/asm-2.0.jar"/>
+ </classpath>
+ <jvmarg value="-javaagent:${aj.root}/lib/test/loadtime5.jar"/>
+ <jvmarg value="-Daj5.def=ataspectj/aop-unweavabletest.xml"/>
+ </java>
+ </target>
</project>
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Vasseur initial implementation
+ *******************************************************************************/
+package ataspectj;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.security.ProtectionDomain;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class UnweavableTest extends TestCase {
+
+ public void testUnweavableProxy() {
+ TestAspect.I = 0;
+ ISome some = getProxy();
+ some.giveOne();
+ assertEquals(1, TestAspect.I);
+ }
+
+ static interface ISome {
+ public int giveOne();
+ }
+
+ ISome getProxy() {
+ return (ISome) Proxy.newProxyInstance(
+ ISome.class.getClassLoader(),
+ new Class[]{ISome.class},
+ new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ return new Integer(1);
+ }
+ }
+ );
+ }
+
+ @Aspect
+ public static class TestAspect {
+
+ static int I = 0;
+
+ @Before("execution(* ataspectj.UnweavableTest.ISome+.giveOne())")
+ public void before() {
+ I++;
+ }
+ }
+
+ public void testJit() {
+ TestAspect.I = 0;
+ TestAspect2.I = 0;
+ ISome some = getJit();
+ assertNotNull(some.getClass().getAnnotation(ASome.class));
+ assertEquals(2, some.giveOne());
+ assertEquals(1, TestAspect.I);
+ assertEquals(1, TestAspect2.I);
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ static @interface ASome {}
+
+ ISome getJit() {
+ ClassWriter cw = new ClassWriter(true, true);
+ cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "ataspectj/ISomeGen", null, "java/lang/Object", new String[]{"ataspectj/UnweavableTest$ISome"});
+ AnnotationVisitor av = cw.visitAnnotation("Lataspectj/UnweavableTest$ASome;", true);
+ av.visitEnd();
+
+ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, new String[0]);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitMaxs(0, 0);
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "giveOne", "()I", null, new String[0]);
+ mv.visitInsn(Opcodes.ICONST_2);
+ mv.visitInsn(Opcodes.IRETURN);
+ mv.visitMaxs(0, 0);
+ cw.visitEnd();
+
+ try {
+ ClassLoader loader = this.getClass().getClassLoader();
+ Method def = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class});
+ def.setAccessible(true);
+ Class gen = (Class) def.invoke(loader, "ataspectj.ISomeGen", cw.toByteArray(), 0, cw.toByteArray().length);
+ return (ISome) gen.newInstance();
+ } catch (Throwable t) {
+ fail(t.toString());
+ return null;
+ }
+ }
+
+ @Aspect
+ public static class TestAspect2 {
+ static int I = 0;
+ @Before("execution(* @ataspectj.UnweavableTest$ASome ataspectj..*.giveOne())")
+ public void before() {
+ I++;
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ TestHelper.runAndThrowOnFailure(suite());
+ }
+
+ public static junit.framework.Test suite() {
+ return new junit.framework.TestSuite(UnweavableTest.class);
+ }
+
+}