0

I'm trying to use AspectJ in a simple java app, without using of Spring. project is controlled by maven.

Here is the project code, you can see it also on a GitHub

App.java

package ge.jibo.aspectj;

public class App {
    public static void main(String[] args) {
        App app = new App();
        app.print("Message from App object...");
    }

    public void print(String value) {
        System.out.println(value);
    }
}

LoggerAspect.java

package ge.jibo.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class LoggerAspect {

    @Around("execution(!static * *(..))")
    public Object dontLogDuplicates(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        System.out.println("Message from LoggerAspect object");
        return thisJoinPoint.proceed();
    }
}

aop.xml in a resources\META-INF directory

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <aspect name="ge.jibo.aspectj.LoggerAspect"/>
    </aspects>
    <weaver options="-verbose -showWeaveInfo">
        <include within="ge.jibo.aspectj..*"/>
    </weaver>
</aspectj>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ge.jibo.aspectj</groupId>
    <artifactId>aspectj-demo</artifactId>
    <version>1.0</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.6</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>${maven.compiler.source}</source>
                        <target>${maven.compiler.target}</target>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                    <configuration>
                        <archive>
                            <index>true</index>
                            <manifest>
                                <mainClass>ge.jibo.aspectj.App</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

after mvn install JAR file is generated, than I'm trying to execute JAR using the java -jar aspectj-demo.jar command, but only App object is executed, LoggerAspect does not prints anything.

java -jar aspectj-demo.jar

If I pass -javaagent argument with aspectjweaver-1.9.6.jar to JVM, then Aspect object is executed. enter image description here

  • How to avoid of passing this -javaagent argument on each time?
  • Should I add some plugin in pom.xml to execute aspect directly?
JiboOne
  • 1,438
  • 4
  • 22
  • 55
  • 1
    Use compile-time weaving instead, if you do not like load-time weaving. You can use AspectJ Maven plugin for that. You can find plenty of examples online, among them many I have written myself here. – kriegaex Apr 15 '21 at 09:54
  • 1
    @kriegaex Thanks for reply, can you give me a link of one of the example which fits to this question? – JiboOne Apr 15 '21 at 12:23
  • 1
    Did you try a search here or on the web? First, you should read about the [plugin](https://www.mojohaus.org/aspectj-maven-plugin/). There are usage examples in its documentation, too. As for my answers about AspectJ Maven here on SO, you can search for them like [this](https://stackoverflow.com/search?q=%5Baspectj-maven-plugin%5D+user%3A1082681+is%3Aanswer). Simpler ones containing POM examples are [this one](https://stackoverflow.com/a/25480409/1082681) and [that one](https://stackoverflow.com/a/41650046/1082681). – kriegaex Apr 15 '21 at 12:59
  • 1
    @kriegaex I tried but none of them works without passing "aspectjweaver.jar" argument while executing. – JiboOne Apr 15 '21 at 19:32
  • Then you are doing it wrong. Sorry, "tried, doesn't work" does not qualify as a debuggable problem description. I need an [MCVE](https://stackoverflow.com/help/mcve), either in your updated question or on GitHub. – kriegaex Apr 16 '21 at 01:07
  • 1
    BTW, as you can clearly see in the POMs, `aspectjrt` (AspectJ runtime) is a dependency. Of course that one (size 119 K) needs to be on the classpath, but not `aspectjweaver` (1.9 M). The latter is a superset of the former and only needed for LTW. If you like it easy, package everything into an executable JAR. – kriegaex Apr 16 '21 at 01:13

1 Answers1

1

A simple solution/workaround was to add aspectj-maven-plugin for compile-time weaving(in this case aop.xml file is not needed anymore)

and package projects with its dependencies in to executable jar using maven-assembly-plugin (there are other ways also to package executable jars with libs/dependencies)

pom.xml

<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.11</version>
            <configuration>
                <verbose>true</verbose>
                <complianceLevel>1.8</complianceLevel>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                    <configuration>
                        <source>${maven.compiler.source}</source>
                        <target>${maven.compiler.target}</target>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>
                                    ge.jibo.aspectj.App
                                </mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

execution of mvn install generates additional jar file aspectj-demo-jar-with-dependencies.jar

java -jar aspectj-demo-jar-with-dependencies.jar enter image description here

kriegaex
  • 63,017
  • 15
  • 111
  • 202
JiboOne
  • 1,438
  • 4
  • 22
  • 55
  • 1
    Great that I could help you solve your problem. Because you mentioned other uber JAR solutions: One would be One-JAR, see [my answer here](https://stackoverflow.com/a/62707083/1082681). It also contains a link to other answers in which I mentioned it. But of course Maven Assembly is also fine and probably more popular because it is actively maintained. I am just used to using One-JAR for stand-alone AspectJ apps. – kriegaex Apr 17 '21 at 05:00
  • Yes, you are right. your comments was very helpful to solve this issue. Thanks! One-JAR is good, but if you rename generated JAR it wont be execute properly anymore. in case of Assembly you can change name without any problem. – JiboOne Apr 18 '21 at 06:04
  • What do you mean, you cannot rename the JAR? If you are talking about the uber JAR generated by One-JAR, of course you can rename it to your heart's content. The JRE does not care about the JAR name. Please be more specific about your problem. Are you trying to rename anything inside the uber JAR? If so, how and when? – kriegaex Apr 18 '21 at 07:44
  • you are right, you can rename it manually and it will work (Tested). problem occurs when changing name of JAR in pom.xml. if you add ${project.build.finalName}.${project.packaging} within one-jar plugin, execution of JAR will throw "java.io.EOFException: Unexpected end of ZLIB input stream" exception. – JiboOne Apr 19 '21 at 09:11
  • I never do that, but you can. You must not use the exact same file name for both original and one-jar artifact, though, which is what you tried to do. That is a mistake. So first, you tell maven-jar-plugin to use something like `${project.build.finalName}.orig` (without the extension!), resulting in `my_artifact-1.2.orig.jar`. Then you add a corresponding `${project.build.finalName}.orig.${project.packaging}` plus `${project.build.finalName}.${project.packaging}` to the One-JAR plugin configuration and you are fine. – kriegaex Apr 19 '21 at 12:35