Java modules not working with aspectj-maven-plugin

Viewed 787

I am trying to migrate my java project to 11 and using modules, but it seems that the aspectj compiler does not recognise modules from my maven dependencies?

Error:

mvn clean compile
[INFO] Scanning for projects...
[INFO] 
[INFO] ---------------------------< com.test:test >----------------------------
[INFO] Building test 1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ test ---
[INFO] Deleting /Users/piotr/Documents/mvntest/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ test ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/piotr/Documents/mvntest/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ test ---
[INFO] Required filename-based automodules detected: [passay-1.6.0.jar]. Please don't publish this project to a public artifact repository!
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/piotr/Documents/mvntest/target/classes
[INFO] 
[INFO] --- aspectj-maven-plugin:1.12.6:compile (default) @ test ---
[INFO] Showing AJC message detail for messages of types: [error, warning, fail]
[ERROR] passay cannot be resolved to a module
    /Users/piotr/Documents/mvntest/src/main/java/module-info.java:2
requires passay;
         ^

[ERROR] Must declare a named package because this compilation unit is associated to the named module 'test'
    /Users/piotr/Documents/mvntest/src/main/java/main.java:1
(no source information available)

[ERROR] The type org.passay.PasswordValidator is not accessible
    /Users/piotr/Documents/mvntest/src/main/java/main.java:1
import org.passay.PasswordValidator;
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^

[ERROR] PasswordValidator cannot be resolved to a type
    /Users/piotr/Documents/mvntest/src/main/java/main.java:5
System.out.println(new PasswordValidator());
                       ^^^^^^^^

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.169 s
[INFO] Finished at: 2020-12-14T10:22:00+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.nickwongdev:aspectj-maven-plugin:1.12.6:compile (default) on project test: AJC compiler errors:
[ERROR] error at requires passay;
[ERROR]          ^
[ERROR] /Users/piotr/Documents/mvntest/src/main/java/module-info.java:2:0::0 passay cannot be resolved to a module
[ERROR] error at (no source information available)
[ERROR] /Users/piotr/Documents/mvntest/src/main/java/main.java:1:0::0 Must declare a named package because this compilation unit is associated to the named module 'test'
[ERROR] error at import org.passay.PasswordValidator;
[ERROR]        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ERROR] /Users/piotr/Documents/mvntest/src/main/java/main.java:1:0::0 The type org.passay.PasswordValidator is not accessible
[ERROR] error at System.out.println(new PasswordValidator());
[ERROR]                        ^^^^^^^^
[ERROR] /Users/piotr/Documents/mvntest/src/main/java/main.java:5:0::0 PasswordValidator cannot be resolved to a type
[ERROR] 
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

pom.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<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/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.test</groupId>
    <artifactId>test</artifactId>
    <packaging>jar</packaging>
    <version>1</version>

    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <aspectj.version>1.9.6</aspectj.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.passay</groupId>
            <artifactId>passay</artifactId>
            <version>1.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>${java.version}</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.nickwongdev</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.12.6</version>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <complianceLevel>${java.version}</complianceLevel>
                    <weaveMainSourceFolder>true</weaveMainSourceFolder>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

src/main/java/module-info.java:

module test {
    requires passay;
}

src/main/java/main.java:

import org.passay.PasswordValidator;

public class main {
    public static void main() {
        System.out.println(new PasswordValidator());
    }
}
1 Answers

In order for this to work the AspectJ Maven plugin would have to support at least the command line parameter --module-info for the AspectJ compiler ajc, analogous to javac. That the parameter exists is not documented in the ajc command line help but indirectly in the AspectJ 1.9.0 release notes.

I have never worked with Java 9+ modules before, even though I use recent Java versions for other reasons. I had to experiment a bit in order to find out how to compile and run your project from the command line, and basically it was something like this:

ajc -11 --module-path "C:\Users\alexa\.m2\repository\org\passay\passay\1.6.0\passay-1.6.0.jar" -cp "C:\Users\alexa\.m2\repository\org\aspectj\aspectjrt\1.9.6\aspectjrt-1.9.6.jar" -sourceroots src\main\java -outjar target\test-1.jar

java --module-path target\test-1.jar;C:\Users\alexa\.m2\repository\org\passay\passay\1.6.0\passay-1.6.0.jar;C:\Users\alexa\.m2\repository\org\aspectj\aspectjrt\1.9.6\aspectjrt-1.9.6.jar --module test/de.scrum_master.stackoverflow.q65286736.Application

Sorry, but I have moved your main class outside the default package like this (the main method was also pseudo code without any parameters):

module test {
  requires passay;
}
package de.scrum_master.stackoverflow.q65286736;

import org.passay.PasswordValidator;

public class Application {
  public static void main(String[] args) {
    System.out.println(new PasswordValidator());
  }
}

Then I experimentally added a parameter javaModules to the plugin, as you can see here in my pull request. Feel free to build it yourself by cloning my repository fork.

Then modify your POM like this:

<?xml version="1.0" encoding="UTF-8" ?>
<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/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test</groupId>
  <artifactId>test</artifactId>
  <packaging>jar</packaging>
  <version>1</version>

  <properties>
    <java.version>11</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <aspectj.version>1.9.6</aspectj.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.passay</groupId>
      <artifactId>passay</artifactId>
      <version>1.6.0</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${aspectj.version}</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <release>${java.version}</release>
          <useIncrementalCompilation>false</useIncrementalCompilation>
        </configuration>
      </plugin>
      <plugin>
        <groupId>com.nickwongdev</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.12.7-SNAPSHOT</version>
        <dependencies>
          <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>${aspectj.version}</version>
          </dependency>
        </dependencies>
        <configuration>
          <complianceLevel>${java.version}</complianceLevel>
          <encoding>${project.build.sourceEncoding}</encoding>
          <!--<weaveMainSourceFolder>true</weaveMainSourceFolder>-->
          <showWeaveInfo>true</showWeaveInfo>
          <Xlint>ignore</Xlint>
          <!--<verbose>true</verbose>-->
          <!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn>-->
          <!--<argumentFileName>argumentFileName.txt</argumentFileName>-->
          <javaModules>
            <javaModule>
              <groupId>org.passay</groupId>
              <artifactId>passay</artifactId>
            </javaModule>
          </javaModules>
        </configuration>
        <executions>
          <execution>
            <phase>process-sources</phase>
            <goals>
              <goal>compile</goal>
              <goal>test-compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

The decisive difference is of course the usage of the new parameter:

          <javaModules>
            <javaModule>
              <groupId>org.passay</groupId>
              <artifactId>passay</artifactId>
            </javaModule>
          </javaModules>

Now the project compiles and you can also run the application with the second command I posted above, i.e. java --module-path target\test-1.jar;.... For me IntelliJ IDEA recognised the new parameter in its POM syntax highlighting and also runs the application without any problems.

This is not full support for all Java module related parameters you can think of, but I think it is a starting point. Feedback welcome.

Related