title: What is the substitute for com.sun.tools after jdk 16?
body: <p>I read some articles which teach how to implement Lombok. It mentions that lombok was implemented by JavacTrees, TreeMaker in the jdk package com.sun.tools like below:</p>
  <pre><code>import com.sun.source.tree.Tree;
  import com.sun.tools.javac.api.JavacTrees;
  import com.sun.tools.javac.code.Flags;
  import com.sun.tools.javac.code.Type;
  import com.sun.tools.javac.processing.JavacProcessingEnvironment;
  import com.sun.tools.javac.tree.JCTree;
  import com.sun.tools.javac.tree.TreeMaker;
  import com.sun.tools.javac.tree.TreeTranslator;
  import com.sun.tools.javac.util.*;
  
  import javax.annotation.processing.*;
  import javax.lang.model.SourceVersion;
  import javax.lang.model.element.Element;
  import javax.lang.model.element.TypeElement;
  import javax.tools.Diagnostic;
  import java.util.Set;
  
  @SupportedSourceVersion(SourceVersion.RELEASE_8)
  @SupportedAnnotationTypes(&quot;com.example.lombok.MyGetter&quot;)
  public class MyGetterProcessor extends AbstractProcessor {
  
      private Messager messager;
      private JavacTrees javacTrees; 
      private TreeMaker treeMaker;
      private Names names;
  
      @Override
      public synchronized void init(ProcessingEnvironment processingEnv) {
          super.init(processingEnv);
          this.messager = processingEnv.getMessager();
          this.javacTrees = JavacTrees.instance(processingEnv);
          Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
          this.treeMaker = TreeMaker.instance(context);
          this.names = Names.instance(context);
      }
  
      @Override
      public boolean process(Set&lt;? extends TypeElement&gt; annotations, RoundEnvironment roundEnv) {
          Set&lt;? extends Element&gt; elementsAnnotatedWith = roundEnv.getElementsAnnotatedWith(MyGetter.class);
          elementsAnnotatedWith.forEach(e -&gt; {
              JCTree tree = javacTrees.getTree(e);
              tree.accept(new TreeTranslator() {
                  @Override
                  public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
                      List&lt;JCTree.JCVariableDecl&gt; jcVariableDeclList = List.nil();
  
                      for (JCTree jcTree : jcClassDecl.defs) {
                          if (jcTree.getKind().equals(Tree.Kind.VARIABLE)) {
                              JCTree.JCVariableDecl jcVariableDecl = (JCTree.JCVariableDecl) jcTree;
                              jcVariableDeclList = jcVariableDeclList.append(jcVariableDecl);
                          }
                      }
  
                      jcVariableDeclList.forEach(jcVariableDecl -&gt; {
                          messager.printMessage(Diagnostic.Kind.NOTE, jcVariableDecl.getName() + &quot; has been processed&quot;);
                          jcClassDecl.defs = jcClassDecl.defs.prepend(makeGetterMethodDecl(jcVariableDecl));
                      });
                      super.visitClassDef(jcClassDecl);
                  }
              });
          });
          return true;
      }
  
      private JCTree.JCMethodDecl makeGetterMethodDecl(JCTree.JCVariableDecl jcVariableDecl) {
          ListBuffer&lt;JCTree.JCStatement&gt; statements = new ListBuffer&lt;&gt;();
          // 生成表达式 例如 this.a = a;
          JCTree.JCExpressionStatement aThis = makeAssignment(treeMaker.Select(treeMaker.Ident(
                  names.fromString(&quot;this&quot;)), jcVariableDecl.getName()), treeMaker.Ident(jcVariableDecl.getName()));
          statements.append(aThis);
          JCTree.JCBlock block = treeMaker.Block(0, statements.toList());
  
  
          JCTree.JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.PARAMETER),
                  jcVariableDecl.getName(), jcVariableDecl.vartype, null);
          List&lt;JCTree.JCVariableDecl&gt; parameters = List.of(param);
  
  
          JCTree.JCExpression methodType = treeMaker.Type(new Type.JCVoidType());
          return treeMaker.MethodDef(treeMaker.Modifiers(Flags.PUBLIC),
                  getNewMethodName(jcVariableDecl.getName()), methodType, List.nil(),
                  parameters, List.nil(), block, null);
  
      }
  
      private Name getNewMethodName(Name name) {
          String s = name.toString();
          return names.fromString(&quot;get&quot; + s.substring(0, 1).toUpperCase() + s.substring(1, name.length()));
      }
  
      private JCTree.JCExpressionStatement makeAssignment(JCTree.JCExpression lhs, JCTree.JCExpression rhs) {
          return treeMaker.Exec(
                  treeMaker.Assign(
                          lhs,
                          rhs
                  )
          );
      }
  }
  </code></pre>
  <p>However, com.sun.tools cannot be accessible after jdk 16. How is it implemented after jdk 16?</p>
  <p>I try to find the source code of new version of Lombok but I only find the source code of the version below 1.18.20 of Lombok in github. The version below 1.18.20 of Lombok still use com.sun.tools to implement. As I know, after Lombok 1.18.20, it used another implementation.</p>
  <p>How can I do that after jdk 16 without access of com.sun.tools?</p>
  <p>Updates:
  I read the new version of source code of Lombok. I saw it import the package as below:</p>
  <pre><code>import com.sun.tools.javac.jvm.ClassWriter;
  import com.sun.tools.javac.main.JavaCompiler;
  import com.sun.tools.javac.processing.JavacFiler;
  import com.sun.tools.javac.processing.JavacProcessingEnvironment;
  import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  import com.sun.tools.javac.util.Context;
  </code></pre>
  <p>but these package has already not been accessible after jdk 16. Why Lombok can still use them?</p>