Relocating AspectJ packages in a Java agent

aspectj java 11
what is aspectj
package org aspectj lang does not exist
aspectj-maven-plugin java 8
aspectj annotation
how aspectj works
aspectj logging
aspectj advice

I'm using AspectJ to monitor field access and field modify. I have a gradle project that compiles the two aspects and package that jar together with the aspectjrt and aspectjweaver in a shaded jar using gradle shadow plugin. the agent is still org.aspectj.weaver.loadtime.Agent. everything works fine, but when i try to relocate the aspectj packages I get an error.

The shadow plugin configuration is:

shadowJar {
    relocate 'org.aspectj', 'shadow.org.aspectj'
    relocate 'aj.org.objectweb.asm', 'shadow.aj.org.objectweb.asm'
}

The manifest :

jar {
    manifest {
        attributes("Premain-Class": "shadow.org.aspectj.weaver.loadtime.Agent",
                "Can-Redefine-Classes": true,
                "Can-Retransform-Classes":true)
    }
}

This is the decompiled aspect class so it seems correct:

package com.vfunction.singletonanalysis;

import shadow.org.aspectj.lang.JoinPoint;
import shadow.org.aspectj.lang.NoAspectBoundException;
import shadow.org.aspectj.lang.annotation.Aspect;
import shadow.org.aspectj.lang.annotation.Before;

@Aspect
public class StaticFieldBeforeAccessAspect extends AbstractFieldAccessAspect {
    public StaticFieldBeforeAccessAspect() {
    }

    @Before("callAt()")
    public void before(JoinPoint joinPoint) throws Throwable {
        this.printJoinPoint(joinPoint);
    }

    public static StaticFieldBeforeAccessAspect aspectOf() {
        if (ajc$perSingletonInstance == null) {
            throw new NoAspectBoundException("com.vfunction.singletonanalysis.StaticFieldBeforeAccessAspect", ajc$initFailureCause);
        } else {
            return ajc$perSingletonInstance;
        }
    }

    public static boolean hasAspect() {
        return ajc$perSingletonInstance != null;
    }

    static {
        try {
            ajc$postClinit();
        } catch (Throwable var1) {
            ajc$initFailureCause = var1;
        }

    }
}

But I still get an error when trying to run a test program saying the the type found is not an aspect:

[AppClassLoader@18b4aac2] info AspectJ Weaver Version 1.8.12 built on Friday Oct 20, 2017 at 21:58:11 GMT
[AppClassLoader@18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader@18b4aac2
[AppClassLoader@18b4aac2] info using configuration file:***/workspace/singleton-analysis/agent/build/libs/agent-1.0.0-SNAPSHOT-all.jar!/META-INF/aop.xml
[AppClassLoader@18b4aac2] info register aspect com.vfunction.singletonanalysis.StaticFieldModifyAspect
[AppClassLoader@18b4aac2] error The specified aspect 'com.vfunction.singletonanalysis.StaticFieldModifyAspect' cannot be found
[AppClassLoader@18b4aac2] info register aspect com.vfunction.singletonanalysis.StaticFieldAccessAspect
[AppClassLoader@18b4aac2] error The specified aspect 'com.vfunction.singletonanalysis.StaticFieldAccessAspect' cannot be found
[AppClassLoader@18b4aac2] info register aspect com.vfunction.singletonanalysis.StaticFieldBeforeAccessAspect
[AppClassLoader@18b4aac2] error Cannot register 'com.vfunction.singletonanalysis.StaticFieldBeforeAccessAspect' because the type found with that name is not an aspect

Check contents of aop.xml inside the shaded jar. Is the aspect class name shadowed? I would suspect that it's not given the error message.

As mentioned in documentation, you can make Shadow plugin transform XML files like this:

shadowJar {
    tranform(XmlAppendingTransformer.class) {
        resource = 'aop.xml'
    }
}

[aspectj-users] relocation of aspectj classes in a java agent, We use gradle to package our tool and wanted to relocate the aspectj classes but it looks impossible. I think its because aspectjweaver uses  We use gradle to package our tool and wanted to relocate the aspectj classes but it looks impossible. I think its because aspectjweaver uses string constants to test if a class is an aspect, something like that:


I don't think that's the issue. I do not relocate my aspect classes, only the dependencies like aspectj library. so my aspect class looks like that:

import com.vfunction.jni.Callbacks;
import java.lang.reflect.Field;
import vshadow.org.aspectj.lang.JoinPoint;
import vshadow.org.aspectj.lang.annotation.Aspect;
import vshadow.org.aspectj.lang.annotation.Before;
import vshadow.org.aspectj.lang.annotation.Pointcut;

@Aspect
public class StaticFieldBeforeModifyAspect extends AbstractFieldAccessAspect

as you see it imports vshadow.org.aspectj.lang.annotation.Aspect , that class exists. the issue is that the aspectjweaver code checks if a class is a valid aspect by inspecting if the class has an org.aspectj.lang.annotation.Aspect annotation, but it doesn't ,it has a vshadow.org.aspectj.lang.annotation.Aspect annotation. the aspectjweaver checks for the annotation using a string constant. it happens in org.aspectj.weaver.bcel.BcelWeaver#addLibraryAspect and the constant is used like that for example:

public final static UnresolvedType ASPECT_ANNOTATION = UnresolvedType.forSignature("Lorg/aspectj/lang/annotation/Aspect;")

and the shadow plugin does not relocate that.

I'm pretty sure that's the issue.

relocating aspectj packages, Shadow Version 2.0.2 Gradle Version 4.3 In a java agent we are developing we are trying to relocate the aspectjrt and aspectjweaver  In a java agent we are developing we are trying to relocate the aspectjrt and aspectjweaver packages but it looks impossible because aspectj weaver uses string constants to test if a class is an aspect.


You can try excluding Aspect annotation from shadowing:

shadowJar {
   relocate('org.aspectj', 'shadow.org.aspectj') {
       exclude 'org.aspectj.lang.annotation.Aspect'
   }
}

see http://imperceptiblethoughts.com/shadow/#relocating_packages

Another hacky option is to write your own Transformer that will search and replace "Lorg/aspectj/lang/annotation/Aspect;" with shadowed version.

see http://imperceptiblethoughts.com/shadow/#controlling_jar_content_merging

Aspect-Oriented Programming in Spring Boot Part 3: Setting up , I'm using AspectJ to monitor field access and field modify. I have a gradle project that compiles the two aspects and package that jar together  relocation of aspectj classes in a java agent. Hi All We are developing a kind of jvm profiler and we want to use aspectj load time weaving. we're going to use this tool for various application which


How to shoot yourself in the foot building a Java Agent, Only weave classes in our application-specific packages. This should -​javaagent:path/to/spring-aop-aspectj-ltw/spring-instrument-4.2.5. [aspectj-users] relocation of aspectj classes in a java agent. From: Shalom Ben-Zvii Kazaz; Prev by Date: Re: [aspectj-users] The constructor DeprecatedMethodLogger() is not visible when testing my aspect; Next by Date: Re: [aspectj-users] Java 8 type annotations; Previous by thread: [aspectj-users] relocation of aspectj classes in a java agent


5.10.4. Load-time Weaving with AspectJ in the Spring Framework , Among others, making the Plumbr Java Agent perform reliably without endangering Naturally, our real java agent would not do such a thing to your We solved that by moving the aspectjweaver jar to the /lib of the tomcat  Modified code that didn't work correctly after relocating aspectj to another base package. This is in most cases about the hard-coded check of the package first character to 'o' which would fail if relocating aspectj to a package starting with a different character.


Including Java Agent in Standalone Spring Boot Application, 'Vanilla' AspectJ LTW is effected by using a Java (5+) agent, which is switched on only weave classes in our application-specific packages --> <include within="​foo. Now we can move on to the Spring-specific portion of the configuration. New in AspectJ 5 are a number of mechanisms to make load-time weaving easy to use. The load-time weaving mechanism is chosen through JVM startup options. Configuration files determine the set of aspects to be used for weaving and which types will be woven.