public void execute()

in src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java [650:1257]


    public void execute() throws MojoExecutionException, CompilationFailureException {
        // ----------------------------------------------------------------------
        // Look up the compiler. This is done before other code than can
        // cause the mojo to return before the lookup is done possibly resulting
        // in misconfigured POMs still building.
        // ----------------------------------------------------------------------

        Compiler compiler;

        getLog().debug("Using compiler '" + compilerId + "'.");

        try {
            compiler = compilerManager.getCompiler(compilerId);
        } catch (NoSuchCompilerException e) {
            throw new MojoExecutionException("No such compiler '" + e.getCompilerId() + "'.");
        }

        // -----------toolchains start here ----------------------------------
        // use the compilerId as identifier for toolchains as well.
        Toolchain tc = getToolchain();
        if (tc != null) {
            getLog().info("Toolchain in maven-compiler-plugin: " + tc);
            if (executable != null) {
                getLog().warn("Toolchains are ignored, 'executable' parameter is set to " + executable);
            } else {
                fork = true;
                // TODO somehow shaky dependency between compilerId and tool executable.
                executable = tc.findTool(compilerId);
            }
        }
        // ----------------------------------------------------------------------
        //
        // ----------------------------------------------------------------------

        List<String> compileSourceRoots = removeEmptyCompileSourceRoots(getCompileSourceRoots());

        if (compileSourceRoots.isEmpty()) {
            getLog().info("No sources to compile");

            return;
        }

        // Verify that target or release is set
        if (!targetOrReleaseSet) {
            MessageBuilder mb = MessageUtils.buffer()
                    .a("No explicit value set for target or release! ")
                    .a("To ensure the same result even after upgrading this plugin, please add ")
                    .newline()
                    .newline();

            writePlugin(mb);

            getLog().warn(mb.toString());
        }

        // ----------------------------------------------------------------------
        // Create the compiler configuration
        // ----------------------------------------------------------------------

        CompilerConfiguration compilerConfiguration = new CompilerConfiguration();

        compilerConfiguration.setOutputLocation(getOutputDirectory().getAbsolutePath());

        compilerConfiguration.setOptimize(optimize);

        compilerConfiguration.setDebug(debug);

        compilerConfiguration.setDebugFileName(getDebugFileName());

        compilerConfiguration.setImplicitOption(implicit);

        if (debug && (debuglevel != null && !debuglevel.isEmpty())) {
            String[] split = StringUtils.split(debuglevel, ",");
            for (String aSplit : split) {
                if (!(aSplit.equalsIgnoreCase("none")
                        || aSplit.equalsIgnoreCase("lines")
                        || aSplit.equalsIgnoreCase("vars")
                        || aSplit.equalsIgnoreCase("source"))) {
                    throw new IllegalArgumentException("The specified debug level: '" + aSplit + "' is unsupported. "
                            + "Legal values are 'none', 'lines', 'vars', and 'source'.");
                }
            }
            compilerConfiguration.setDebugLevel(debuglevel);
        }

        compilerConfiguration.setParameters(parameters);

        compilerConfiguration.setEnablePreview(enablePreview);

        compilerConfiguration.setVerbose(verbose);

        compilerConfiguration.setShowWarnings(showWarnings);

        compilerConfiguration.setFailOnWarning(failOnWarning);

        if (failOnWarning && !showWarnings) {
            getLog().warn("The property failOnWarning is set to true, but showWarnings is set to false.");
            getLog().warn("With compiler's warnings silenced the failOnWarning has no effect.");
        }

        compilerConfiguration.setShowDeprecation(showDeprecation);

        compilerConfiguration.setSourceVersion(getSource());

        compilerConfiguration.setTargetVersion(getTarget());

        compilerConfiguration.setReleaseVersion(getRelease());

        compilerConfiguration.setProc(proc);

        File generatedSourcesDirectory = getGeneratedSourcesDirectory();
        compilerConfiguration.setGeneratedSourcesDirectory(
                generatedSourcesDirectory != null ? generatedSourcesDirectory.getAbsoluteFile() : null);

        if (generatedSourcesDirectory != null) {
            if (!generatedSourcesDirectory.exists()) {
                generatedSourcesDirectory.mkdirs();
            }

            String generatedSourcesPath = generatedSourcesDirectory.getAbsolutePath();

            compileSourceRoots.add(generatedSourcesPath);

            if (isTestCompile()) {
                getLog().debug("Adding " + generatedSourcesPath + " to test-compile source roots:\n  "
                        + StringUtils.join(project.getTestCompileSourceRoots().iterator(), "\n  "));

                project.addTestCompileSourceRoot(generatedSourcesPath);

                getLog().debug("New test-compile source roots:\n  "
                        + StringUtils.join(project.getTestCompileSourceRoots().iterator(), "\n  "));
            } else {
                getLog().debug("Adding " + generatedSourcesPath + " to compile source roots:\n  "
                        + StringUtils.join(project.getCompileSourceRoots().iterator(), "\n  "));

                project.addCompileSourceRoot(generatedSourcesPath);

                getLog().debug("New compile source roots:\n  "
                        + StringUtils.join(project.getCompileSourceRoots().iterator(), "\n  "));
            }
        }

        compilerConfiguration.setSourceLocations(compileSourceRoots);

        compilerConfiguration.setAnnotationProcessors(annotationProcessors);

        compilerConfiguration.setProcessorPathEntries(resolveProcessorPathEntries());

        compilerConfiguration.setSourceEncoding(encoding);

        compilerConfiguration.setFork(fork);

        if (fork) {
            if (!(meminitial == null || meminitial.isEmpty())) {
                String value = getMemoryValue(meminitial);

                if (value != null) {
                    compilerConfiguration.setMeminitial(value);
                } else {
                    getLog().info("Invalid value for meminitial '" + meminitial + "'. Ignoring this option.");
                }
            }

            if (!(maxmem == null || maxmem.isEmpty())) {
                String value = getMemoryValue(maxmem);

                if (value != null) {
                    compilerConfiguration.setMaxmem(value);
                } else {
                    getLog().info("Invalid value for maxmem '" + maxmem + "'. Ignoring this option.");
                }
            }
        }

        compilerConfiguration.setExecutable(executable);

        compilerConfiguration.setWorkingDirectory(basedir);

        compilerConfiguration.setCompilerVersion(compilerVersion);

        compilerConfiguration.setBuildDirectory(buildDirectory);

        compilerConfiguration.setOutputFileName(outputFileName);

        if (CompilerConfiguration.CompilerReuseStrategy.AlwaysNew.getStrategy().equals(this.compilerReuseStrategy)) {
            compilerConfiguration.setCompilerReuseStrategy(CompilerConfiguration.CompilerReuseStrategy.AlwaysNew);
        } else if (CompilerConfiguration.CompilerReuseStrategy.ReuseSame.getStrategy()
                .equals(this.compilerReuseStrategy)) {
            if (getRequestThreadCount() > 1) {
                if (!skipMultiThreadWarning) {
                    getLog().warn("You are in a multi-thread build and compilerReuseStrategy is set to reuseSame."
                            + " This can cause issues in some environments (os/jdk)!"
                            + " Consider using reuseCreated strategy."
                            + System.getProperty("line.separator")
                            + "If your env is fine with reuseSame, you can skip this warning with the "
                            + "configuration field skipMultiThreadWarning "
                            + "or -Dmaven.compiler.skipMultiThreadWarning=true");
                }
            }
            compilerConfiguration.setCompilerReuseStrategy(CompilerConfiguration.CompilerReuseStrategy.ReuseSame);
        } else {

            compilerConfiguration.setCompilerReuseStrategy(CompilerConfiguration.CompilerReuseStrategy.ReuseCreated);
        }

        getLog().debug("CompilerReuseStrategy: "
                + compilerConfiguration.getCompilerReuseStrategy().getStrategy());

        compilerConfiguration.setForceJavacCompilerUse(forceJavacCompilerUse);

        boolean canUpdateTarget;

        IncrementalBuildHelper incrementalBuildHelper = new IncrementalBuildHelper(mojoExecution, session);

        final Set<File> sources;

        IncrementalBuildHelperRequest incrementalBuildHelperRequest = null;

        if (useIncrementalCompilation) {
            getLog().debug("useIncrementalCompilation enabled");
            try {
                canUpdateTarget = compiler.canUpdateTarget(compilerConfiguration);

                sources = getCompileSources(compiler, compilerConfiguration);

                preparePaths(sources);

                incrementalBuildHelperRequest = new IncrementalBuildHelperRequest().inputFiles(sources);

                DirectoryScanResult dsr = computeInputFileTreeChanges(incrementalBuildHelper, sources);

                boolean idk = compiler.getCompilerOutputStyle()
                                .equals(CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES)
                        && !canUpdateTarget;
                boolean dependencyChanged = isDependencyChanged();
                boolean sourceChanged = isSourceChanged(compilerConfiguration, compiler);
                boolean inputFileTreeChanged = hasInputFileTreeChanged(dsr);
                // CHECKSTYLE_OFF: LineLength
                if (idk || dependencyChanged || sourceChanged || inputFileTreeChanged)
                // CHECKSTYLE_ON: LineLength
                {
                    String cause = idk
                            ? "idk"
                            : (dependencyChanged ? "dependency" : (sourceChanged ? "source" : "input tree"));
                    getLog().info("Changes detected - recompiling the module! :" + cause);
                    if (showCompilationChanges) {
                        for (String fileAdded : dsr.getFilesAdded()) {
                            getLog().info("\t+ " + fileAdded);
                        }
                        for (String fileRemoved : dsr.getFilesRemoved()) {
                            getLog().info("\t- " + fileRemoved);
                        }
                    }

                    compilerConfiguration.setSourceFiles(sources);
                } else {
                    getLog().info("Nothing to compile - all classes are up to date");

                    return;
                }
            } catch (CompilerException e) {
                throw new MojoExecutionException("Error while computing stale sources.", e);
            }
        } else {
            getLog().debug("useIncrementalCompilation disabled");

            Set<File> staleSources;
            try {
                staleSources =
                        computeStaleSources(compilerConfiguration, compiler, getSourceInclusionScanner(staleMillis));

                canUpdateTarget = compiler.canUpdateTarget(compilerConfiguration);

                if (compiler.getCompilerOutputStyle().equals(CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES)
                        && !canUpdateTarget) {
                    getLog().info("RESCANNING!");
                    // TODO: This second scan for source files is sub-optimal
                    String inputFileEnding = compiler.getInputFileEnding(compilerConfiguration);

                    staleSources = computeStaleSources(
                            compilerConfiguration, compiler, getSourceInclusionScanner(inputFileEnding));
                }

            } catch (CompilerException e) {
                throw new MojoExecutionException("Error while computing stale sources.", e);
            }

            if (staleSources.isEmpty()) {
                getLog().info("Nothing to compile - all classes are up to date");

                return;
            }

            compilerConfiguration.setSourceFiles(staleSources);

            try {
                // MCOMPILER-366: if sources contain the module-descriptor it must be used to define the modulepath
                sources = getCompileSources(compiler, compilerConfiguration);

                if (getLog().isDebugEnabled()) {
                    getLog().debug("#sources: " + sources.size());
                    for (File file : sources) {
                        getLog().debug(file.getPath());
                    }
                }

                preparePaths(sources);
            } catch (CompilerException e) {
                throw new MojoExecutionException("Error while computing stale sources.", e);
            }
        }

        // Dividing pathElements of classPath and modulePath is based on sourceFiles
        compilerConfiguration.setClasspathEntries(getClasspathElements());

        compilerConfiguration.setModulepathEntries(getModulepathElements());

        compilerConfiguration.setIncludes(getIncludes());

        compilerConfiguration.setExcludes(getExcludes());

        Map<String, String> effectiveCompilerArguments = getCompilerArguments();

        String effectiveCompilerArgument = getCompilerArgument();

        if ((effectiveCompilerArguments != null) || (effectiveCompilerArgument != null) || (compilerArgs != null)) {
            if (effectiveCompilerArguments != null) {
                for (Map.Entry<String, String> me : effectiveCompilerArguments.entrySet()) {
                    String key = me.getKey();
                    String value = me.getValue();
                    if (!key.startsWith("-")) {
                        key = "-" + key;
                    }

                    if (key.startsWith("-A") && (value != null && !value.isEmpty())) {
                        compilerConfiguration.addCompilerCustomArgument(key + "=" + value, null);
                    } else {
                        compilerConfiguration.addCompilerCustomArgument(key, value);
                    }
                }
            }
            if (!(effectiveCompilerArgument == null || effectiveCompilerArgument.isEmpty())) {
                compilerConfiguration.addCompilerCustomArgument(effectiveCompilerArgument, null);
            }
            if (compilerArgs != null) {
                for (String arg : compilerArgs) {
                    compilerConfiguration.addCompilerCustomArgument(arg, null);
                }
            }
        }

        // ----------------------------------------------------------------------
        // Dump configuration
        // ----------------------------------------------------------------------
        if (getLog().isDebugEnabled()) {
            getLog().debug("Classpath:");

            for (String s : getClasspathElements()) {
                getLog().debug(" " + s);
            }

            if (!getModulepathElements().isEmpty()) {
                getLog().debug("Modulepath:");
                for (String s : getModulepathElements()) {
                    getLog().debug(" " + s);
                }
            }

            getLog().debug("Source roots:");

            for (String root : getCompileSourceRoots()) {
                getLog().debug(" " + root);
            }

            try {
                if (fork) {
                    if (compilerConfiguration.getExecutable() != null) {
                        getLog().debug("Excutable: ");
                        getLog().debug(" " + compilerConfiguration.getExecutable());
                    }
                }

                String[] cl = compiler.createCommandLine(compilerConfiguration);
                if (cl != null && cl.length > 0) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(cl[0]);
                    for (int i = 1; i < cl.length; i++) {
                        sb.append(" ");
                        sb.append(cl[i]);
                    }
                    getLog().debug("Command line options:");
                    getLog().debug(sb);
                }
            } catch (CompilerException ce) {
                getLog().debug(ce);
            }
        }

        List<String> jpmsLines = new ArrayList<>();

        // See http://openjdk.java.net/jeps/261
        final List<String> runtimeArgs = Arrays.asList(
                "--upgrade-module-path", "--add-exports", "--add-reads", "--add-modules", "--limit-modules");

        // Custom arguments are all added as keys to an ordered Map
        Iterator<Map.Entry<String, String>> entryIter =
                compilerConfiguration.getCustomCompilerArgumentsEntries().iterator();
        while (entryIter.hasNext()) {
            Map.Entry<String, String> entry = entryIter.next();

            if (runtimeArgs.contains(entry.getKey())) {
                jpmsLines.add(entry.getKey());

                String value = entry.getValue();
                if (value == null) {
                    entry = entryIter.next();
                    value = entry.getKey();
                }
                jpmsLines.add(value);
            } else if ("--patch-module".equals(entry.getKey())) {
                String value = entry.getValue();
                if (value == null) {
                    entry = entryIter.next();
                    value = entry.getKey();
                }

                String[] values = value.split("=");

                StringBuilder patchModule = new StringBuilder(values[0]);
                patchModule.append('=');

                Set<String> patchModules = new LinkedHashSet<>();
                Set<Path> sourceRoots = new HashSet<>(getCompileSourceRoots().size());
                for (String sourceRoot : getCompileSourceRoots()) {
                    sourceRoots.add(Paths.get(sourceRoot));
                }

                String[] files = values[1].split(PS);

                for (String file : files) {
                    Path filePath = Paths.get(file);
                    if (getOutputDirectory().toPath().equals(filePath)) {
                        patchModules.add("_"); // this jar
                    } else if (getOutputDirectory().toPath().startsWith(filePath)) {
                        // multirelease, can be ignored
                        continue;
                    } else if (sourceRoots.contains(filePath)) {
                        patchModules.add("_"); // this jar
                    } else {
                        JavaModuleDescriptor descriptor = getPathElements().get(file);

                        if (descriptor == null) {
                            if (Files.isDirectory(filePath)) {
                                patchModules.add(file);
                            } else {
                                getLog().warn("Can't locate " + file);
                            }
                        } else if (!values[0].equals(descriptor.name())) {
                            patchModules.add(descriptor.name());
                        }
                    }
                }

                StringBuilder sb = new StringBuilder();

                if (!patchModules.isEmpty()) {
                    for (String mod : patchModules) {
                        if (sb.length() > 0) {
                            sb.append(", ");
                        }
                        // use 'invalid' separator to ensure values are transformed
                        sb.append(mod);
                    }

                    jpmsLines.add("--patch-module");
                    jpmsLines.add(patchModule + sb.toString());
                }
            }
        }

        if (!jpmsLines.isEmpty()) {
            Path jpmsArgs = Paths.get(getOutputDirectory().getAbsolutePath(), "META-INF/jpms.args");
            try {
                Files.createDirectories(jpmsArgs.getParent());

                Files.write(jpmsArgs, jpmsLines, Charset.defaultCharset());
            } catch (IOException e) {
                getLog().warn(e.getMessage());
            }
        }

        // ----------------------------------------------------------------------
        // Compile!
        // ----------------------------------------------------------------------

        if (StringUtils.isEmpty(compilerConfiguration.getSourceEncoding())) {
            getLog().warn("File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
                    + ", i.e. build is platform dependent!");
        }

        CompilerResult compilerResult;

        if (useIncrementalCompilation) {
            incrementalBuildHelperRequest.outputDirectory(getOutputDirectory());

            incrementalBuildHelper.beforeRebuildExecution(incrementalBuildHelperRequest);

            getLog().debug("incrementalBuildHelper#beforeRebuildExecution");
        }

        try {
            compilerResult = compiler.performCompile(compilerConfiguration);
        } catch (Exception e) {
            // TODO: don't catch Exception
            throw new MojoExecutionException("Fatal error compiling", e);
        }

        if (createMissingPackageInfoClass
                && compilerResult.isSuccess()
                && compiler.getCompilerOutputStyle() == CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE) {
            try {
                SourceMapping sourceMapping = getSourceMapping(compilerConfiguration, compiler);
                createMissingPackageInfoClasses(compilerConfiguration, sourceMapping, sources);
            } catch (Exception e) {
                getLog().warn("Error creating missing package info classes", e);
            }
        }

        if (useIncrementalCompilation) {
            if (incrementalBuildHelperRequest.getOutputDirectory().exists()) {
                getLog().debug("incrementalBuildHelper#afterRebuildExecution");
                // now scan the same directory again and create a diff
                incrementalBuildHelper.afterRebuildExecution(incrementalBuildHelperRequest);
            } else {
                getLog().debug(
                                "skip incrementalBuildHelper#afterRebuildExecution as the output directory doesn't exist");
            }
        }

        List<CompilerMessage> warnings = new ArrayList<>();
        List<CompilerMessage> errors = new ArrayList<>();
        List<CompilerMessage> others = new ArrayList<>();
        for (CompilerMessage message : compilerResult.getCompilerMessages()) {
            if (message.getKind() == CompilerMessage.Kind.ERROR) {
                errors.add(message);
            } else if (message.getKind() == CompilerMessage.Kind.WARNING
                    || message.getKind() == CompilerMessage.Kind.MANDATORY_WARNING) {
                warnings.add(message);
            } else {
                others.add(message);
            }
        }

        if (failOnError && !compilerResult.isSuccess()) {
            for (CompilerMessage message : others) {
                assert message.getKind() != CompilerMessage.Kind.ERROR
                        && message.getKind() != CompilerMessage.Kind.WARNING
                        && message.getKind() != CompilerMessage.Kind.MANDATORY_WARNING;
                getLog().info(message.toString());
            }
            if (!warnings.isEmpty()) {
                getLog().info("-------------------------------------------------------------");
                getLog().warn("COMPILATION WARNING : ");
                getLog().info("-------------------------------------------------------------");
                for (CompilerMessage warning : warnings) {
                    getLog().warn(warning.toString());
                }
                getLog().info(warnings.size() + ((warnings.size() > 1) ? " warnings " : " warning"));
                getLog().info("-------------------------------------------------------------");
            }

            if (!errors.isEmpty()) {
                getLog().info("-------------------------------------------------------------");
                getLog().error("COMPILATION ERROR : ");
                getLog().info("-------------------------------------------------------------");
                for (CompilerMessage error : errors) {
                    getLog().error(error.toString());
                }
                getLog().info(errors.size() + ((errors.size() > 1) ? " errors " : " error"));
                getLog().info("-------------------------------------------------------------");
            }

            if (!errors.isEmpty()) {
                throw new CompilationFailureException(errors);
            } else {
                throw new CompilationFailureException(warnings);
            }
        } else {
            for (CompilerMessage message : compilerResult.getCompilerMessages()) {
                switch (message.getKind()) {
                    case NOTE:
                    case OTHER:
                        getLog().info(message.toString());
                        break;

                    case ERROR:
                        getLog().error(message.toString());
                        break;

                    case MANDATORY_WARNING:
                    case WARNING:
                    default:
                        getLog().warn(message.toString());
                        break;
                }
            }
        }
    }