eclipse-aspectj / aspectj

Other
272 stars 82 forks source link

AJC 1.9.21 on JDK < 17 dumps ajcore file with 'NoSuchFieldError: RELEASE_17' #269

Closed simonpahl closed 6 months ago

simonpahl commented 6 months ago

Steps to reproduce

<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>test-project</artifactId>
    <version>1.0-SNAPSHOT</version>

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

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.21</version>
        </dependency>
    </dependencies>

   <build>
       <plugins>
           <plugin>
               <groupId>org.codehaus.mojo</groupId>
               <artifactId>aspectj-maven-plugin</artifactId>
               <version>1.15.0</version>
               <executions>
                   <execution>
                       <goals>
                           <goal>compile</goal>       <!-- use this goal to weave all your main classes -->
                           <goal>test-compile</goal>  <!-- use this goal to weave all your test classes -->
                       </goals>
                   </execution>
               </executions>
               <configuration>
                   <source>11</source>
                   <target>11</target>
                   <complianceLevel>11</complianceLevel>
               </configuration>
               <dependencies>
                   <dependency>
                       <groupId>org.aspectj</groupId>
                       <artifactId>aspectjtools</artifactId>
                       <version>1.9.21</version>
                   </dependency>
               </dependencies>
           </plugin>
       </plugins>
   </build>
</project>

Java Code (org/example/Main.java):

package org.example;

public class Main {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
}

Maven version

# mvn --version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /home/xxx/.sdkman/candidates/maven/current
Java version: 11.0.21, vendor: Eclipse Adoptium, runtime: /home/xxx/.sdkman/candidates/java/11.0.21-tem
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.5.12-200.fc38.x86_64", arch: "amd64", family: "unix"

mvn clean install causes the following Error:

[ERROR] Failed to execute goal org.codehaus.mojo:aspectj-maven-plugin:1.15.0:compile (default) on project test-project: AJC compiler errors:
[ERROR] abort ABORT -- (NoSuchFieldError) RELEASE_17
[ERROR] RELEASE_17
[ERROR] java.lang.NoSuchFieldError: RELEASE_17
[ERROR]         at org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl.<clinit>(BaseProcessingEnvImpl.java:49)
[ERROR]         at org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager.configure(BatchAnnotationProcessorManager.java:79)
[ERROR]         at org.aspectj.org.eclipse.jdt.internal.compiler.batch.Main.initializeAnnotationProcessorManager(Main.java:4677)
[ERROR]         at org.aspectj.ajdt.ajc.BuildArgParser.initializeAnnotationProcessorManager(BuildArgParser.java:314)
[ERROR]         at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:1070)
[ERROR]         at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performBuild(AjBuildManager.java:275)
[ERROR]         at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:188)
[ERROR]         at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:103)
[ERROR]         at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:47)
[ERROR]         at org.aspectj.tools.ajc.Main.run(Main.java:374)
[ERROR]         at org.aspectj.tools.ajc.Main.runMain(Main.java:253)
[ERROR]         at org.codehaus.mojo.aspectj.AbstractAjcCompiler.execute(AbstractAjcCompiler.java:568)
[ERROR]         at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:126)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2(MojoExecutor.java:328)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute(MojoExecutor.java:316)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:174)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.access$000(MojoExecutor.java:75)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor$1.run(MojoExecutor.java:162)
[ERROR]         at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute(DefaultMojosExecutionStrategy.java:39)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:159)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:105)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:73)
[ERROR]         at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:53)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:118)
[ERROR]         at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:261)
[ERROR]         at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:173)
[ERROR]         at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:101)
[ERROR]         at org.apache.maven.cli.MavenCli.execute(MavenCli.java:906)
[ERROR]         at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:283)
[ERROR]         at org.apache.maven.cli.MavenCli.main(MavenCli.java:206)
[ERROR]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:283)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:226)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:407)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:348)
[ERROR] 
[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

Changing back to AspectJ 1.9.20.1 or changing to JDK 17 resolves this issue.

simonpahl commented 6 months ago

Ok, apparently the issue comes from https://github.com/eclipse-aspectj/eclipse.jdt.core/blob/V1_9_21_RC1/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseProcessingEnvImpl.java#L49C36-L49C68 . And it seems like this version of eclipse.jdt.core is built to run only on Java 17 and higher.

kriegaex commented 6 months ago

Yes, sure. Maybe next time, you want to read the release notes before upgrading AspectJ.

It also explains the root cause. It is not an AspectJ decision, but we depend on Eclipse JDT Core. It only affects the AspectJ compiler, not the runtime.

kriegaex commented 6 months ago
# mvn --version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /home/xxx/.sdkman/candidates/maven/current
Java version: 11.0.21, vendor: Eclipse Adoptium, runtime: /home/xxx/.sdkman/candidates/java/11.0.21-tem

Here, I could have seen the problem, but standing in the middle of a crowd in the bus, scrolling on the mobile phone with one hand is not an ideal situation.

kriegaex commented 6 months ago

I looked into this a bit more. When running ECJ 3.36.0 or 3.37.0-SNAPSHOT stand-alone, the JVM throws a LinkageError, caused by UnsupportedClassVersionError, which is kind of clear to the user:

$ java -jar ~/.m2/repository/org/eclipse/jdt/ecj/3.37.0-SNAPSHOT/ecj-3.37.0-SNAPSHOT.jar -11 src/main/java/org/example/Main.java
Error: LinkageError occurred while loading main class org.eclipse.jdt.internal.compiler.batch.Main
        java.lang.UnsupportedClassVersionError: org/eclipse/jdt/internal/compiler/batch/Main has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0

With ACJ 1.9.21 stand-alone, compilation can even pass for simple cases, but in many cases we will see the error you posted here. The difference is due to the fact that the Eclipse JDT Core is compiled to with source and target level 17, while the forked AspectJ JDT Core is compiled with source 17 and target 11, which today still works (maybe no longer in the future). But in some execution paths, the class org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl (just a relocated version of the upstream class without the org.aspectj package prefix) is loaded, and that one defines

import javax.lang.model.SourceVersion;
// (...)

public static final SourceVersion MINIMAL_REQUIRED_RUNTIME_VERSION = SourceVersion.RELEASE_17;

SourceVersion is a JDK class, more exactly an enum, and that enum constant does not exist in JDKs < 17. I.e., on JDK 11 many classes of the AspectJ compiler load normally, until at some point BaseProcessingEnvImpl is loaded and tries to use a constant not present in the current JDK, which leads to the exception you have seen.

There are two ways to handle that:

An UnsupportedClassVersionError already occurs, if you run AJC 1.9.21 e.g. on JDK 8, i.e. it would be kind of consistent to yield the same effect on JDKs 11 to 16. It is already documented in the release notes and Java version compatibility matrix that AJC 1.9.21 needs JDK 17 to run, so strictly speaking neither change is necessary. But avoiding AJ core dumps one way or another would still be appropriate.