All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.tatarka.RetrolambdaExec.groovy Maven / Gradle / Ivy

There is a newer version: 3.7.1
Show newest version
package me.tatarka

import groovy.transform.CompileStatic
import org.gradle.api.Project
import org.gradle.api.ProjectConfigurationException
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.file.FileCollection
import org.gradle.process.JavaExecSpec
import org.gradle.util.VersionNumber

import static me.tatarka.RetrolambdaPlugin.checkIfExecutableExists

/**
 * Runs retrolambda with the given args, used by {@link RetrolambdaTask} and {@link RetrolambdaTransform}.
 */
@CompileStatic
class RetrolambdaExec {

    private static final int COMMANDLINE_LENGTH_LIMIT = 3496;

    FileCollection classpath
    File inputDir;
    File outputDir;
    FileCollection includedFiles
    List jvmArgs;
    int bytecodeVersion;
    boolean defaultMethods;

    private final Project project;

    RetrolambdaExec(Project project) {
        this.project = project;
    }

    public void exec() {
        project.javaexec { JavaExecSpec exec ->
            // Ensure retrolambda runs on java8
            def retrolambda = project.extensions.getByType(RetrolambdaExtension.class)
            def retrolambdaConfig = project.configurations.getByName("retrolambdaConfig")

            if (!retrolambda.onJava8) {
                def java = "${retrolambda.tryGetJdk()}/bin/java"
                if (!checkIfExecutableExists(java)) {
                    throw new ProjectConfigurationException("Cannot find executable: $java", null)
                }
                exec.executable java
            }

            String path = classpath.asPath

            exec.classpath = project.files(retrolambdaConfig)
            exec.main = 'net.orfjackal.retrolambda.Main'
            exec.jvmArgs = [
                    "-Dretrolambda.inputDir=$inputDir",
                    "-Dretrolambda.outputDir=$outputDir",
                    "-Dretrolambda.classpath=${path}",
                    "-Dretrolambda.bytecodeVersion=$bytecodeVersion",
            ]

            VersionNumber retrolambdaVersion = retrolambdaVersion(retrolambdaConfig)
            boolean requiresJavaAgent = !requireVersion(retrolambdaVersion, '1.6.0')
            if (requiresJavaAgent) {
                exec.jvmArgs "-javaagent:$exec.classpath.asPath"
            }

            boolean supportIncludeFiles = requireVersion(retrolambdaVersion, '2.1.0')
            if (supportIncludeFiles && classpathLengthGreaterThanLimit(path)) {
                File classpathFile = File.createTempFile("inc-", ".path")
                classpathFile.withWriter('UTF-8') { writer ->
                    for (String item : this.classpath) {
                        writer.write(item + "\n")
                    }
                }
                classpathFile.deleteOnExit();
                exec.jvmArgs "-Dretrolambda.classpathFile=${classpathFile.absolutePath}"
            } else {
                exec.jvmArgs "-Dretrolambda.classpath=${path}"
            }

            if (includedFiles != null) {
                if (supportIncludeFiles && changeFileLengthGreaterThanLimit(includedFiles)) {
                    def includedFile = File.createTempFile("inc-", ".list")
                    includedFile.withWriter('UTF-8') { writer ->
                        for (File file : includedFiles) {
                            writer.write(file.toString() + "\n")
                        }
                    }
                    includedFile.deleteOnExit();
                    exec.jvmArgs "-Dretrolambda.includedFilesFile=${includedFile.absolutePath}"
                } else {
                    def includedArg = "-Dretrolambda.includedFiles=${includedFiles.join(File.pathSeparator)}"
                    exec.jvmArgs includedArg
                    project.logger.quiet(includedArg)
                }

            }

            if (defaultMethods) {
                exec.jvmArgs "-Dretrolambda.defaultMethods=true"
            }

            for (String arg : jvmArgs) {
                exec.jvmArgs arg
            }
        }
    }

    private static boolean classpathLengthGreaterThanLimit(String path) {
        return path.length() > COMMANDLINE_LENGTH_LIMIT
    }

    private static boolean changeFileLengthGreaterThanLimit(FileCollection includedFiles) {
        int total = 0;
        for (File file : includedFiles) {
            total += file.toString().length();
            if (total > COMMANDLINE_LENGTH_LIMIT) {
                return true
            }
        }
        return false
    }

    private static VersionNumber retrolambdaVersion(Configuration retrolambdaConfig) {
        retrolambdaConfig.resolve()
        Dependency retrolambdaDep = retrolambdaConfig.dependencies.iterator().next()
        if (!retrolambdaDep.version) {
            // Don't know version
            return null
        }
        return VersionNumber.parse(retrolambdaDep.version)

    }

    private static boolean requireVersion(VersionNumber retrolambdaVersion, String version, boolean fallback = false) {
        if (retrolambdaVersion == null) {
            // Don't know version, assume fallback
            return fallback
        }
        def targetVersionNumber = VersionNumber.parse(version)
        return retrolambdaVersion >= targetVersionNumber
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy