IDEA Rebuild project error: Information:java: java.lang.AssertionError: Value of x -1

Problem: java.lang.AssertionError: Value of x -1

Imitating the lombok tool, my enumgen tool is basically finished.

After the release, it was overturned when it was ready to be put into production! After the company’s project emax-rpcapi-list relies on enumgen, when IDEA Rebuild Project or when maven package/install, an error occurs → Information: java: java.lang.AssertionError: Value of x -1

Here are the details about this error:

Information:java: Exception error occurred in compiler (1.8.0_241). If the bug is not found in the Bug Database (http://bugs.java.com), please contact<br>This Java compiler bug is identified through the Java Bug Report page (http://bugreport.java.com). Please include your procedure and the following diagnostic information with your report. Thanks.
Information:java: java.lang.AssertionError: Value of x -1
Information:java: at com.sun.tools.javac.util.Assert.error(Assert.java:133)
Information:java: at com.sun.tools.javac.util.Assert.check(Assert.java:94)
Information:java: at com.sun.tools.javac.util.Bits.incl(Bits.java:186)
Information:java: at com.sun.tools.javac.comp.Flow$AssignAnalyzer.initParam(Flow.java:1858) Information:java: at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitMethodDef(Flow. java:1807) Information:java: at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778) Information:java: at com.sun.tools.javac.tree.TreeScanner.scan( TreeScanner.java:49) Information:java: at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:404) Information:java: at com.sun.tools.javac.comp.Flow$ AssignAnalyzer.scan(Flow.java:1382) Information:java: at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitClassDef(Flow.java:1749) Information:java: at com.sun.tools.javac. tree.JCTree$JCClassDecl.accept(JCTree.java:693) Information:java: at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:2446) Information:java: at com.sun. tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:2429) Information:java: at com.sun.tools.javac.comp.Flow.analyzeTree(Flow.java:211) Information:java: at com. sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1327) Information:java: at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1296) Information:java: at com. sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901) Information:java: at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860) Information:java: at com. sun.tools.javac.main.Main.compile(Main.java:523) Information:java: at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129) Information:java: at com. sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138) Information:java: at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:207) Information:java: at org.jetbrains. jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:493) Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:345) Information:java: at org.jetbrains. jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:270) Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:223) Information:java: at org.jetbrains. jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1414) Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:1092) Information:java: at org.jetbrains.jps.incremental. IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1159) Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:1053) Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks( IncProjectBuilder.java:882) Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:449) Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java: 190) Information:java: at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:138) Information:java: at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:297) Information: java: at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:130) Information:java: at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:218) Information :java: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) Information:java: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) Information:java: at java. lang.Thread.run(Thread.java:748) Information:java: Errors occurred while compiling module 'zhenghe-rpcapistyle' Information:javac 1.8.0_241 was used to compile java sources Information:2023/3/20 20:57 - Build completed with 1 error and 0 warnings in 5 s 993 ms Error:java: Compilation failed: internal java compiler error

There is little information on this issue online. Some netizens asked questions on the sun platform, but there was no result.

Temporary solution

This error has me a little confused. Because my own demo project can be used normally if it depends on enumgen.

Since emax-rpcapi-list and my demo project also rely on lombok, the intuitive analysis is that enumgen conflicts with lombok. I modified my annotation processor implementation logic and tried to solve it, but failed to fix it. The intermediate investigation process is quite tortuous. Finally, when comparing the mvn:dependency:tree of emax-rpcapi-list and my demo project, I came up with the following temporary solution.

  • The first one is to adjust the maven dependencies dependency order. Mine depends on enumgen before lombok.
  • The second one is lombok version compatibility. There is a problem with lombok version 1.18.20. Upgrade the lombok version to 1.18.24 and it will be fine.

The problem occurred again

Why is it called a temporary solution? Because my enumgen expanded some codes later. As a result, the same error appeared again→Information:java: java.lang.AssertionError: Value of x -1

I started analyzing the error stack carefully and noticed the keywords visitClassDef and visitMethodDef.

Flow:2493 —
Flow$AssignAnalyzer#visitMethodDef

@Override
public void visitMethodDef(JCMethodDecl tree) {
    if (tree.body == null) {
        return;
    }

    /* MemberEnter can generate synthetic methods ignore them
     */
    if ((tree.sym.flags() & SYNTHETIC) != 0) {
        return;
    }

    Lint lintPrev = lint;
    lint = lint.augment(tree.sym);
    try {
        super.visitMethodDef(tree); // Call super---Flow$AbstractAssignAnalyzer here
    } finally {
        lint = lintPrev;
    }
}

Flow$AbstractAssignAnalyzer#visitMethodDef(JCMethodDecl)

for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
    JCVariableDecl def = l.head;
    scan(def);
    Assert.check((def.sym.flags() & amp; PARAMETER) != 0, "Method parameter without PARAMETER flag");
    /* If we are executing the code from Gen, then there can be
     * synthetic or mandated variables, ignore them.
     */
    initParam(def);
}

Flow:1795

Flow$AbstractAssignAnalyzer#initParam(JCVariableDecl)

protected void initParam(JCVariableDecl def) {
    inits.incl(def.sym.adr); // inits is an instance of com.sun.tools.javac.util.Bits
    uninits.excl(def.sym.adr);
}

com.sun.tools.javac.util.Bits#incl

/** Include x in this set.
 */
public void incl(int x) {
    Assert.check(currentState != BitsState.UNKNOWN);
    Assert.check(x >= 0, "Value of x " + x); // Assert#check is called here
    sizeTo((x >>> wordshift) + 1);
    bits[x >>> wordshift] = bits[x >>> wordshift] |
        (1 << (x & amp; wordmask));
    currentState = BitsState.NORMAL;
}

JCVariableDecl.sym.adr see Symbol#adr

/** The variable's address. Used for different purposes during
 * flow analysis, translation and code generation.
 *Flow analysis:
 * If this is a blank final or local variable, its sequence number.
 * Translation:
 * If this is a private field, its access number.
 * Code generation:
 * If this is a local variable, its logical slot number.
 */
public int adr = -1;

Use Baidu Translation to understand this javadoc:

/**The address of the variable. Used for different purposes during Flow analysis, translation and code generation.
*Flow analysis:
*If this is a blank final variable or local variable, then it is the sequence number.
*Translation:
*If this is a private field, then it is the access number.
*Code generation:
*If this is a local variable, then it is the logical slot number. */
public int adr = -1;

The stack is Flow$Analyzer, so the inference is that it is a problem with my variable definition. Then, I modified the code related to VarDef similar to the one below, mainly focusing on the first parameter modifier of VarDef, and found that I can only use Flags.PARAMETER. Still can’t solve the problem.

JCTree.JCVariableDecl var_exception = maker.VarDef(maker.Modifiers(Flags.PARAMETER), names.fromString("e"), maker.Ident(names.fromString(exceptionClass.getSimpleName())), null);< /pre>
 <h2>The final solution</h2>
 <p>Let me post my code first.</p>
  
  <pre> 1 @Override
 2 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
 3 final Set<? extends Element> dataAnnotations = roundEnv.getElementsAnnotatedWith(EnumGetByCode.class);
 4 dataAnnotations.stream()
 5.filter(element -> element.getKind() == ElementKind.ENUM)//Filter enumeration class
 6.map(element -> trees.getTree(element))
 7.forEach(tree -> {
 8 tree.accept(new TreeTranslator() {
 9 @Override
10 public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
11 astUtil.setClass(jcClassDecl);
12
13 prependGetBeanByName(jcClassDecl);
14
15 JCTree.JCMethodDecl newMethodDecl = prependGetBeanByCode(jcClassDecl);
16 if (newMethodDecl != null) {
17 astUtil.addImport(jcClassDecl);
18
19 prependGetDescriptionByCode(jcClassDecl, newMethodDecl);
20}
21 super.visitClassDef(jcClassDecl);
twenty two 
twenty three                             }
twenty four                         });
25}
26);
27 return true;
28}

The ultimate solution is to refer to a post on Jianshu and set the pos of the context treeMaker instance.

When reaching the next annotation usage, you need to set pos first. Because there are many classes or methods in the system that use target annotations, and during the code generation process (that is, the visitClassDef is rewritten in accept to be the element of the current class append or prepend), there is no modification to treeMarker.pos, so that it remains unchanged Unchanged Even if the operation has progressed to the next class file, pos remains unchanged.
Indeed, when I comment out those append or prepend in visitClassDef, this error will not occur.

The modified code is to add a line of code before calling tree.accept on line 8 above: maker.pos = tree.pos;

Finally relieved!