Search in sources :

Example 1 with IncrementalBuildHelperRequest

use of org.apache.maven.shared.incremental.IncrementalBuildHelperRequest in project maven-plugins by apache.

the class AbstractCompilerMojo method execute.

@Override
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;
    }
    // ----------------------------------------------------------------------
    // Create the compiler configuration
    // ----------------------------------------------------------------------
    CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
    compilerConfiguration.setOutputLocation(getOutputDirectory().getAbsolutePath());
    compilerConfiguration.setOptimize(optimize);
    compilerConfiguration.setDebug(debug);
    if (debug && StringUtils.isNotEmpty(debuglevel)) {
        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.setVerbose(verbose);
    compilerConfiguration.setShowWarnings(showWarnings);
    compilerConfiguration.setFailOnWarning(failOnWarning);
    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) {
        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 (!StringUtils.isEmpty(meminitial)) {
            String value = getMemoryValue(meminitial);
            if (value != null) {
                compilerConfiguration.setMeminitial(value);
            } else {
                getLog().info("Invalid value for meminitial '" + meminitial + "'. Ignoring this option.");
            }
        }
        if (!StringUtils.isEmpty(maxmem)) {
            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);
    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);
            // CHECKSTYLE_OFF: LineLength
            if ((compiler.getCompilerOutputStyle().equals(CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES) && !canUpdateTarget) || isDependencyChanged() || isSourceChanged(compilerConfiguration, compiler) || incrementalBuildHelper.inputFileTreeChanged(incrementalBuildHelperRequest)) // CHECKSTYLE_ON: LineLength
            {
                getLog().info("Changes detected - recompiling the module!");
                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);
                sources = computeStaleSources(compilerConfiguration, compiler, getSourceInclusionScanner(inputFileEnding));
                compilerConfiguration.setSourceFiles(sources);
            } else {
                compilerConfiguration.setSourceFiles(staleSources);
            }
            preparePaths(compilerConfiguration.getSourceFiles());
        } 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;
        }
    }
    // Dividing pathElements of classPath and modulePath is based on sourceFiles
    compilerConfiguration.setClasspathEntries(getClasspathElements());
    compilerConfiguration.setModulepathEntries(getModulepathElements());
    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") && StringUtils.isNotEmpty(value)) {
                    compilerConfiguration.addCompilerCustomArgument(key + "=" + value, null);
                } else {
                    compilerConfiguration.addCompilerCustomArgument(key, value);
                }
            }
        }
        if (!StringUtils.isEmpty(effectiveCompilerArgument)) {
            compilerConfiguration.addCompilerCustomArgument(effectiveCompilerArgument, null);
        }
        if (compilerArgs != null) {
            for (String arg : compilerArgs) {
                compilerConfiguration.addCompilerCustomArgument(arg, null);
            }
        }
    }
    // ----------------------------------------------------------------------
    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 (getLog().isDebugEnabled() && 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);
        }
    }
    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 {
        try {
            compilerResult = compiler.performCompile(compilerConfiguration);
        } catch (CompilerNotImplementedException cnie) {
            List<CompilerError> messages = compiler.compile(compilerConfiguration);
            compilerResult = convertToCompilerResult(messages);
        }
    } catch (Exception e) {
        // TODO: don't catch Exception
        throw new MojoExecutionException("Fatal error compiling", 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<CompilerMessage>();
    List<CompilerMessage> errors = new ArrayList<CompilerMessage>();
    List<CompilerMessage> others = new ArrayList<CompilerMessage>();
    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;
            }
        }
    }
}
Also used : CompilerMessage(org.codehaus.plexus.compiler.CompilerMessage) ArrayList(java.util.ArrayList) Toolchain(org.apache.maven.toolchain.Toolchain) IncrementalBuildHelperRequest(org.apache.maven.shared.incremental.IncrementalBuildHelperRequest) CompilerConfiguration(org.codehaus.plexus.compiler.CompilerConfiguration) CompilerNotImplementedException(org.codehaus.plexus.compiler.CompilerNotImplementedException) NoSuchCompilerException(org.codehaus.plexus.compiler.manager.NoSuchCompilerException) CompilerException(org.codehaus.plexus.compiler.CompilerException) ArrayList(java.util.ArrayList) List(java.util.List) NoSuchCompilerException(org.codehaus.plexus.compiler.manager.NoSuchCompilerException) Compiler(org.codehaus.plexus.compiler.Compiler) IncrementalBuildHelper(org.apache.maven.shared.incremental.IncrementalBuildHelper) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) CompilerResult(org.codehaus.plexus.compiler.CompilerResult) NoSuchCompilerException(org.codehaus.plexus.compiler.manager.NoSuchCompilerException) CompilerException(org.codehaus.plexus.compiler.CompilerException) InclusionScanException(org.codehaus.plexus.compiler.util.scan.InclusionScanException) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) InvocationTargetException(java.lang.reflect.InvocationTargetException) CompilerNotImplementedException(org.codehaus.plexus.compiler.CompilerNotImplementedException) File(java.io.File) Map(java.util.Map)

Aggregations

File (java.io.File)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 MojoExecutionException (org.apache.maven.plugin.MojoExecutionException)1 IncrementalBuildHelper (org.apache.maven.shared.incremental.IncrementalBuildHelper)1 IncrementalBuildHelperRequest (org.apache.maven.shared.incremental.IncrementalBuildHelperRequest)1 Toolchain (org.apache.maven.toolchain.Toolchain)1 Compiler (org.codehaus.plexus.compiler.Compiler)1 CompilerConfiguration (org.codehaus.plexus.compiler.CompilerConfiguration)1 CompilerException (org.codehaus.plexus.compiler.CompilerException)1 CompilerMessage (org.codehaus.plexus.compiler.CompilerMessage)1 CompilerNotImplementedException (org.codehaus.plexus.compiler.CompilerNotImplementedException)1 CompilerResult (org.codehaus.plexus.compiler.CompilerResult)1 NoSuchCompilerException (org.codehaus.plexus.compiler.manager.NoSuchCompilerException)1 InclusionScanException (org.codehaus.plexus.compiler.util.scan.InclusionScanException)1