0

Some project background: I am working with an application that runs on Java. My goal is to collect real-time data to send it to an API running on a local server. The application is packaged into a .jar file and I have no access to source code. (Aside from the question, I have attempted to decompile the class to add additional functionality; however, that did not end well, $access000...)

Having just learned about AOP, I ran to test my options. I spend over a week figuring out Maven Setup and AspectJ with it.

I set up a "helloworld" project in which I have been able to successfully weave aspects (from a .java file) into another .java file. My next step is to create an executable .jar file with the main class and weave the aspect .java class into it - then I would have achieved my desired outcome.

Is it possible to take a precompiled .jar file, put it into the project and write aspects for it?

I am not sure if I am misunderstanding something, I believe that should be something feasable.

From AspectJ Development Environment Guide:

In AspectJ tools, the aspectpath is where to find binary aspects. Like the classpath, it can include archives ( .jar and .zip files) and directories containing .class files in a package layout (since binary aspects are in .class files).

Some Reference information:

  • I am using Eclipse (4.23.0).
  • The project is a Maven project that I have added AspectJ support to (through conversion to an AspectJ project).
  • I have gone over a bunch of websites and StackOverflow responses figuring out AspectJ for Eclipse and found This Question. TL;DR: I used this site as AspectJ (Temporary Fix) Source for Eclipse: https://aspectj.dev/eclipse/ajdt/421

Project Structure

├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── hellomaven
    │               └── quickstart
    │                   ├── App.java
    │                   └── AppAspect.java
    └── test
        ├── java
        └── resources

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.hellomaven</groupId>
  <artifactId>quickstart</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>helloMaven</name>
  <description>test</description>

  <properties>
    <java.version>1.8</java.version>
    <junit.version>4.5</junit.version>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>

  <build>
    <pluginManagement>
      <plugins>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>aspectj-maven-plugin</artifactId>
          <version>1.9</version>
          <configuration>
            <showWeaveInfo>true</showWeaveInfo>
            <source>${java.version}</source>
            <target>${java.version}</target>
            <Xlint>ignore</Xlint>
            <complianceLevel>${java.version}</complianceLevel>
            <encoding>UTF-8</encoding>
            <verbose>true</verbose>
            <weaveDependencies>
              <weaveDependency>
                <groupId>com.hellomaven.quickstart.App</groupId>
                <artifactId>hello</artifactId>
              </weaveDependency>
            </weaveDependencies>
          </configuration>
          <executions>
            <execution>
              <phase>process-sources</phase>
              <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
              </goals>
            </execution>
          </executions>
          <dependencies>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjrt</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjtools</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
          </dependencies>
        </plugin>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <version>1.3</version>
          <configuration>
            <mainClass>com.hellomaven.quickstart</mainClass>
          </configuration>
        </plugin>

      </plugins>
    </pluginManagement>
  </build>
</project>

App.java

package com.hellomaven.quickstart;

public class App {
    public static void main(String[] args) {
        hello("World");
    }
    
    public static void hello(String world) {
        System.out.println("Hello " + world);
    }
}

AppAspect.java

package com.hellomaven.quickstart;

import org.aspectj.lang.annotation.*;

@Aspect
public class AppAspect {
    
    @Before("execution(public static void hello(..))")
    public void testAspectBefore() {
        System.out.println("Before ok.");
    }
}
Seymour
  • 64
  • 8
  • 2
    Perhaps it would be best to state your actual question a little more elaborately than just in the title of the post. – David M. Karr May 24 '22 at 23:14
  • 1
    For loadtime weaving you need a java agent, looking at your pom.xml you are actually using compile timeweaving. So which is it? – M. Deinum May 25 '22 at 15:11
  • @M.Deinum I am using compile-time weaving indeed. I am new to pom.xml configuration and Maven in general, but I was able to accomplish compile-time weaving; however, I was not able to figure out load-time weaving. I have shared the code that I already got working in case that would be of any help. – Seymour May 25 '22 at 15:19

1 Answers1

1

Wherever and in whichever way you are running your code, you simply need to add -javaagent:/path/to/aspectjweaver.jar to the Java command line. Furthermore, for LTW you need an aop.xml in the right place. For Maven that means:

  • aop.xml should be located in src/main/resources.
  • If you need LTW in a JUnit test or so, you need to add the -javaagent parameter to your Surefire plugin (unit tests) or Failsafe plugin (integration tests) configuration.
  • If you want to start your compiled program using Exec Maven plugin, as seems to be the case, you need to add the -javaagent parameter to the plugin configuration there, too.

Outside of Maven, again you need to add -javaagent to the command line.

Sorry for the generic answer, but it is just a reflection of your generic question. If you have a more precise follow-up question, you can comment on this answer.

Some resources:

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • Would I have to use precompiled .aj/.java (aspect) classes into the .jar file or would I weave source-code aspects into the .jar using this method? – Seymour May 26 '22 at 15:36
  • None of the above. The JAR stays unchanged. Instead, the weaving agent transforms the byte code while it is being loaded. You may want to google the term instrumentation. – kriegaex May 26 '22 at 18:15
  • I might be asking the wrong question. How could I set up a Maven/AspectJ Project to use a .jar file as input and have aspects be editable within the project? I understand the theory behind LTW, but I am not sure where to find directions on setting up a project like that properly. I have looked inside AspectJ, ajc documentation, and AspectJ In Action (Book), but I seem to be misunderstanding/not understanding something enough. Would you be able to point me in the right direction? – Seymour May 26 '22 at 19:06
  • It hard for me to understand precisely what you want to do, but my answer depends on understanding it. Do you mean, you have a Maven project containing some aspects and some application code plus some (JAR) dependencies, and you want to be able to weave your aspects into both the application code and the JAR dependencies? If so, do you want to do that during build time, creating woven versions of those application and dependency classes, possibly re-packaging them into one or multiple additional JARs and then use those during runtime? Or do you want to use LTW (load-time weaving)? – kriegaex May 26 '22 at 19:26
  • The best thing would be to publish a project on GitHub and then explain in the read-me what you want to achieve. In principle, it is no problem to weave dependency classes, if done right. Maybe the single-project and multi-module examples described for [AspectJ Maven Plugin](https://dev-aspectj.github.io/aspectj-maven-plugin/) can give you a first impression concerning build-time scanarios (not LTW, of course). BTW, I am recommending the more feature-rich aspectj.dev fork, not the mojohaus one. – kriegaex May 26 '22 at 19:30
  • My task: There is an application running on Java (packaged as .jar). I do not have access to the source code of the application. This application collects some data from a machine that is connected and displays it in Java GUI. My goal is to send data that the app shows in the GUI over to an API. I thought that I could extract the data from the running app using AspectJ. It is a singe jar, no preexisting aspect files or other dependencies. I would have attached a GitHub project, but I have not been able to set anything meaningful up. Thank you for taking the time trying to understand me. – Seymour May 26 '22 at 20:23
  • Sounds like LTW is the way to go. Assuming that you have tried the way I described it, what is your problem with that approach? – kriegaex May 28 '22 at 07:36