Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
simonpahl opened this issue Dec 14, 2023 · 4 comments
Closed
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@simonpahl
Copy link

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.

@kriegaex kriegaex self-assigned this Dec 14, 2023
@kriegaex kriegaex added the invalid This doesn't seem right label Dec 14, 2023
@kriegaex kriegaex added this to the 1.9.22 milestone Dec 14, 2023
@kriegaex kriegaex reopened this Dec 14, 2023
@simonpahl
Copy link
Author

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
Copy link
Contributor

kriegaex commented Dec 14, 2023

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 kriegaex added the question Further information is requested label Dec 14, 2023
@kriegaex
Copy link
Contributor

kriegaex commented Dec 14, 2023

# 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
Copy link
Contributor

kriegaex commented Dec 14, 2023

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:

  • Either, we add a try-catch somewhere in the call hierarchy of the compiler, catching this exception and logging a comprehensive error without writing an ajcore.*.txt core dump file.
  • Or, we compile future versions of AspectJ JDT Core with target 17 like the upstream version, which would yield the same LinkageError, caused by UnsupportedClassVersionError, as ECJ.

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.

@kriegaex kriegaex reopened this Dec 14, 2023
@kriegaex kriegaex changed the title Building with aspectj-maven-plugin and version 1.9.21 under Java 11 fails with java.lang.NoSuchFieldError: RELEASE_17 AJC 1.9.21 on JDK < 17 writes dump file with 'java.lang.NoSuchFieldError: RELEASE_17' Dec 14, 2023
@kriegaex kriegaex added enhancement New feature or request and removed invalid This doesn't seem right question Further information is requested labels Dec 14, 2023
@eclipse-aspectj eclipse-aspectj deleted a comment from simonpahl Dec 14, 2023
kriegaex added a commit that referenced this issue Dec 14, 2023
Signed-off-by: Alexander Kriegisch <[email protected]>
@kriegaex kriegaex changed the title AJC 1.9.21 on JDK < 17 writes dump file with 'java.lang.NoSuchFieldError: RELEASE_17' AJC 1.9.21 on JDK < 17 writes dump file with 'NoSuchFieldError: RELEASE_17' Dec 14, 2023
@kriegaex kriegaex changed the title AJC 1.9.21 on JDK < 17 writes dump file with 'NoSuchFieldError: RELEASE_17' AJC 1.9.21 on JDK < 17 dumps ajcore file with 'NoSuchFieldError: RELEASE_17' Dec 14, 2023
kriegaex added a commit to eclipse-aspectj/eclipse.jdt.core that referenced this issue Dec 15, 2023
This should avoid the strange "NoSuchFieldError: RELEASE_17" error
message in AJC.

Relates to eclipse-aspectj/aspectj#269.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Dec 15, 2023
Use new constant Main.MINIMAL_JRE_VERSION (currently = 17) and
SourceVersion.latest().ordinal() to check, if the minimal JRE version
requirement for AJC is met. If not, then exit with code -1 and error
message "The AspectJ compiler needs at least Java runtime 17".

Relates to #269.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 15, 2024
When running AJC, throw an AbortException(MINIMAL_JRE_VERSION) instead
of just logging an error, if the minimal JRE version requirement is
violated. Otherwise, in-process compilation would not fail due to the
skipped System.exit(-1) that was used before. In-process compilation is,
for example, relevant for AspectJ Maven Plugin, but also for non-forked
executions of Plexus AspectJ via Maven Compiler.

I am not 100% sure that AbortException is the appropriate exception
type, because it was designed for an aborted compilation process and
here compilation has not even started yet, but it seems to work fine.

Relates to #269.
Fixes #292.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 15, 2024
When running AJC, throw an AbortException(MINIMAL_JRE_VERSION) instead
of just logging an error, if the minimal JRE version requirement is
violated. Otherwise, in-process compilation would not fail due to the
skipped System.exit(-1) that was used before. In-process compilation is,
for example, relevant for AspectJ Maven Plugin, but also for non-forked
executions of Plexus AspectJ via Maven Compiler.

I am not 100% sure that AbortException is the appropriate exception
type, because it was designed for an aborted compilation process and
here compilation has not even started yet, but it seems to work fine.

Relates to #269.
Fixes #292.

Signed-off-by: Alexander Kriegisch <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants