跳至主要內容

动态编译技术

DHB大约 2 分钟Java动态加载编译

动态编译技术

com.sun.tools.javac.jvm.ClassWriter#writeClass 把字节码写出到OutputStream中

编译过程

java文件-> JCCompilationUnit(类) -> 注解处理器 -> 写出class文件

JCCompilationUnit生成

语法树生成

    protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) {
        long msec = now();
        JCCompilationUnit tree = make.TopLevel(List.nil());
        if (content != null) {
            if (verbose) {
                log.printVerbose("parsing.started", filename);
            }
            if (!taskListener.isEmpty()) {
                TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, filename);
                taskListener.started(e);
                keepComments = true;
                genEndPos = true;
            }
            Parser parser = parserFactory.newParser(content, keepComments(), genEndPos,
                                lineDebugInfo, filename.isNameCompatible("module-info", Kind.SOURCE));
            tree = parser.parseCompilationUnit();
            if (verbose) {
                log.printVerbose("parsing.done", Long.toString(elapsed(msec)));
            }
        }

        tree.sourcefile = filename;

        if (content != null && !taskListener.isEmpty()) {
            TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, tree);
            taskListener.finished(e);
        }

        return tree;
    }

注解处理器

com.sun.tools.javac.processing.JavacProcessingEnvironment#initProcessorIterator中初始化注解处理器的迭代器

初始化注解处理器迭代器

    private void initProcessorIterator(Iterable<? extends Processor> processors) {
        Iterator<? extends Processor> processorIterator;

        if (options.isSet(Option.XPRINT)) {
            try {
                processorIterator = List.of(new PrintingProcessor()).iterator();
            } catch (Throwable t) {
                AssertionError assertError =
                    new AssertionError("Problem instantiating PrintingProcessor.");
                assertError.initCause(t);
                throw assertError;
            }
        } else if (processors != null) {
            // 编译器指定的处理器
            processorIterator = processors.iterator();
        } else {
            if (processorLoaderException == null) {
                /*
                 * If the "-processor" option is used, search the appropriate
                 * path for the named class.  Otherwise, use a service
                 * provider mechanism to create the processor iterator.
                 */
                // 优先处理"-processor"这个参数
                String processorNames = options.get(Option.PROCESSOR);
                if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
                    processorIterator = (processorNames == null) ?
                            new ServiceIterator(serviceLoader, log) :
                            new NameServiceIterator(serviceLoader, log, processorNames);
                } else if (processorNames != null) {
                    processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
                } else {
                    // 通过ServiceLoader类加载,SPI机制
                    processorIterator = new ServiceIterator(processorClassLoader, log);
                }
            } else {
                /*
                 * A security exception will occur if we can't create a classloader.
                 * Ignore the exception if, with hindsight, we didn't need it anyway
                 * (i.e. no processor was specified either explicitly, or implicitly,
                 * in service configuration file.) Otherwise, we cannot continue.
                 */
                processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
                        processorLoaderException);
            }
        }
        // 这里也有一个处理,还没深入研究
        PlatformDescription platformProvider = context.get(PlatformDescription.class);
        java.util.List<Processor> platformProcessors = Collections.emptyList();
        if (platformProvider != null) {
            platformProcessors = platformProvider.getAnnotationProcessors()
                                                 .stream()
                                                 .map(PluginInfo::getPlugin)
                                                 .toList();
        }
        List<Iterator<? extends Processor>> iterators = List.of(processorIterator,
                                                                platformProcessors.iterator());
        Iterator<? extends Processor> compoundIterator =
                Iterators.createCompoundIterator(iterators, i -> i);
        discoveredProcs = new DiscoveredProcessors(compoundIterator);
    }

执行处理器

com.sun.tools.javac.main.JavaCompiler#processAnnotations

-> com.sun.tools.javac.processing.JavacProcessingEnvironment#doProcessing

-> com.sun.tools.javac.processing.JavacProcessingEnvironment.Round#run

-> com.sun.tools.javac.processing.JavacProcessingEnvironment#discoverAndRunProcs

通过读取Processor类的getSupportedOptions方法获取支持的处理器,然后执行。

编译

com.sun.tools.javac.main.JavaCompiler#compile核心代码

    public void compile(Collection<JavaFileObject> sourceFileObjects,
                        Collection<String> classnames,
                        Iterable<? extends Processor> processors,
                        Collection<String> addModules)
    {
        if (!taskListener.isEmpty()) {
            taskListener.started(new TaskEvent(TaskEvent.Kind.COMPILATION));
        }

        if (processors != null && processors.iterator().hasNext())
            explicitAnnotationProcessingRequested = true;
        // as a JavaCompiler can only be used once, throw an exception if
        // it has been used before.
        if (hasBeenUsed)
            checkReusable();
        hasBeenUsed = true;

        // forcibly set the equivalent of -Xlint:-options, so that no further
        // warnings about command line options are generated from this point on
        options.put(XLINT_CUSTOM.primaryName + "-" + LintCategory.OPTIONS.option, "true");
        options.remove(XLINT_CUSTOM.primaryName + LintCategory.OPTIONS.option);

        start_msec = now();

        try {
            // 初始化类注解处理器
            initProcessAnnotations(processors, sourceFileObjects, classnames);

            for (String className : classnames) {
                int sep = className.indexOf('/');
                if (sep != -1) {
                    modules.addExtraAddModules(className.substring(0, sep));
                }
            }

            for (String moduleName : addModules) {
                modules.addExtraAddModules(moduleName);
            }

            // These method calls must be chained to avoid memory leaks
            // 执行类注解处理器
            processAnnotations(
                enterTrees(
                        stopIfError(CompileState.ENTER,
                                initModules(stopIfError(CompileState.ENTER, parseFiles(sourceFileObjects))))
                ),
                classnames
            );

            // If it's safe to do so, skip attr / flow / gen for implicit classes
            if (taskListener.isEmpty() &&
                    implicitSourcePolicy == ImplicitSourcePolicy.NONE) {
                todo.retainFiles(inputFiles);
            }

            // 生成class文件, 关键是generate方法
            if (!CompileState.ATTR.isAfter(shouldStopPolicyIfNoError)) {
                switch (compilePolicy) {
                case SIMPLE:
                    generate(desugar(flow(attribute(todo))));
                    break;

                case BY_FILE: {
                        Queue<Queue<Env<AttrContext>>> q = todo.groupByFile();
                        while (!q.isEmpty() && !shouldStop(CompileState.ATTR)) {
                            generate(desugar(flow(attribute(q.remove()))));
                        }
                    }
                    break;

                case BY_TODO:
                    while (!todo.isEmpty())
                        generate(desugar(flow(attribute(todo.remove()))));
                    break;

                default:
                    Assert.error("unknown compile policy");
                }
            }
        } catch (Abort ex) {
            if (devVerbose)
                ex.printStackTrace(System.err);
        } finally {
            if (verbose) {
                elapsed_msec = elapsed(start_msec);
                log.printVerbose("total", Long.toString(elapsed_msec));
            }

            reportDeferredDiagnostics();

            if (!log.hasDiagnosticListener()) {
                printCount("error", errorCount());
                printCount("warn", warningCount());
                printSuppressedCount(errorCount(), log.nsuppressederrors, "count.error.recompile");
                printSuppressedCount(warningCount(), log.nsuppressedwarns, "count.warn.recompile");
            }
            if (!taskListener.isEmpty()) {
                taskListener.finished(new TaskEvent(TaskEvent.Kind.COMPILATION));
            }
            close();
            if (procEnvImpl != null)
                procEnvImpl.close();
        }
    }

资料

https://zhuanlan.zhihu.com/p/434948213

上次编辑于:
贡献者: dhb