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

net.orfjackal.retrolambda.maven.ProcessClassesMojo Maven / Gradle / Ivy

// Copyright © 2013-2014 Esko Luontola 
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package net.orfjackal.retrolambda.maven;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import net.orfjackal.retrolambda.*;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.*;
import org.apache.maven.plugins.annotations.*;
import org.apache.maven.project.MavenProject;
import org.apache.maven.toolchain.*;

import java.io.*;
import java.util.*;

import static org.twdata.maven.mojoexecutor.MojoExecutor.*;

abstract class ProcessClassesMojo extends AbstractMojo {

    private static final Map targetBytecodeVersions = ImmutableMap.of(
            "1.5", 49,
            "1.6", 50,
            "1.7", 51,
            "1.8", 52
    );

    @Component
    ToolchainManager toolchainManager;

    @Component
    private MavenSession session;

    @Component
    private BuildPluginManager pluginManager;

    @Component
    protected MavenProject project;

    /**
     * Directory of the Java 8 installation for running Retrolambda.
     * The JRE to be used will be determined in priority order:
     * 
    *
  1. This parameter
  2. *
  3. JDK toolchain
  4. *
  5. Same as Maven
  6. *
* * @since 1.2.0 */ @Parameter(property = "java8home", required = false) public File java8home; /** * The Java version targeted by the bytecode processing. Possible values are * 1.5, 1.6, 1.7 and 1.8. After processing the classes will be compatible * with the target JVM provided the known limitations are considered. See * project documentation * for more details. * * @since 1.2.0 */ @Parameter(defaultValue = "1.7", property = "retrolambdaTarget", required = true) public String target; /** * Forces Retrolambda to run in a separate process. The default is not to fork, * in which case Maven has to run under Java 8, or this plugin will fall back * to forking. The forked process uses a Java agent hook for capturing the lambda * classes generated by Java 8, whereas the non-forked version hooks into internal * Java APIs, making it more susceptible to breaking between Java releases. * * @since 1.6.0 */ @Parameter(defaultValue = "false") public boolean fork; protected abstract File getInputDir(); protected abstract File getOutputDir(); protected abstract List getClasspathElements() throws DependencyResolutionRequiredException; @Override public void execute() throws MojoExecutionException { validateTarget(); validateFork(); if (fork) { processClassesInForkedProcess(); } else { processClassesInCurrentProcess(); } } private void validateTarget() throws MojoExecutionException { if (!targetBytecodeVersions.containsKey(target)) { String possibleValues = Joiner.on(", ").join(new TreeSet(targetBytecodeVersions.keySet())); throw new MojoExecutionException( "Unrecognized target '" + target + "'. Possible values are " + possibleValues); } } private void validateFork() { if (!fork && !Main.isRunningJava8()) { getLog().warn("Maven is not running under Java 8 - forced to fork the process"); fork = true; } } private void processClassesInCurrentProcess() throws MojoExecutionException { getLog().info("Processing classes with Retrolambda"); try { Properties p = new Properties(); p.setProperty(Config.BYTECODE_VERSION, "" + targetBytecodeVersions.get(target)); p.setProperty(Config.INPUT_DIR, getInputDir().getAbsolutePath()); p.setProperty(Config.OUTPUT_DIR, getOutputDir().getAbsolutePath()); p.setProperty(Config.CLASSPATH, getClasspath()); Retrolambda.run(new Config(p)); } catch (Throwable t) { throw new MojoExecutionException("Failed to run Retrolambda", t); } } private void processClassesInForkedProcess() throws MojoExecutionException { String version = getRetrolambdaVersion(); getLog().info("Retrieving Retrolambda " + version); retrieveRetrolambdaJar(version); getLog().info("Processing classes with Retrolambda"); String retrolambdaJar = getRetrolambdaJarPath(); executeMojo( plugin(groupId("org.apache.maven.plugins"), artifactId("maven-antrun-plugin"), version("1.7")), goal("run"), configuration(element( "target", element("exec", attributes( attribute("executable", getJavaCommand()), attribute("failonerror", "true")), element("arg", attribute("value", "-Dretrolambda.bytecodeVersion=" + targetBytecodeVersions.get(target))), element("arg", attribute("value", "-Dretrolambda.inputDir=" + getInputDir().getAbsolutePath())), element("arg", attribute("value", "-Dretrolambda.outputDir=" + getOutputDir().getAbsolutePath())), element("arg", attribute("value", "-Dretrolambda.classpath=" + getClasspath())), element("arg", attribute("value", "-javaagent:" + retrolambdaJar)), element("arg", attribute("value", "-jar")), element("arg", attribute("value", retrolambdaJar))))), executionEnvironment(project, session, pluginManager)); } private void retrieveRetrolambdaJar(String version) throws MojoExecutionException { // TODO: use Maven's built-in artifact resolving, so that we can refer to retrolambda.jar in the local repository without copying it executeMojo( plugin(groupId("org.apache.maven.plugins"), artifactId("maven-dependency-plugin"), version("2.8")), goal("copy"), configuration(element("artifactItems", element("artifactItem", element(name("groupId"), "net.orfjackal.retrolambda"), element(name("artifactId"), "retrolambda"), element(name("version"), version), element(name("overWrite"), "true"), element(name("outputDirectory"), getRetrolambdaJarDir()), element(name("destFileName"), getRetrolambdaJarName())))), executionEnvironment(project, session, pluginManager)); } String getJavaCommand() { String javaCommand = getJavaCommand(new File(System.getProperty("java.home"))); Toolchain tc = toolchainManager.getToolchainFromBuildContext("jdk", session); if (tc != null) { getLog().info("Toolchain in retrolambda-maven-plugin: " + tc); javaCommand = tc.findTool("java"); } if (java8home != null) { if (tc != null) { getLog().warn("Toolchains are ignored, 'java8home' parameter is set to " + java8home); } javaCommand = getJavaCommand(java8home); } return javaCommand; } private static String getJavaCommand(File javaHome) { return new File(javaHome, "bin/java").getPath(); } private String getClasspath() { try { StringBuilder sb = new StringBuilder(); for (String classpathElement : getClasspathElements()) { if (sb.length() > 0) { sb.append(File.pathSeparator); } sb.append(classpathElement); } return sb.toString(); } catch (DependencyResolutionRequiredException e) { throw new RuntimeException(e); } } private String getRetrolambdaJarPath() { return getRetrolambdaJarDir() + "/" + getRetrolambdaJarName(); } private String getRetrolambdaJarDir() { return project.getBuild().getDirectory() + "/retrolambda"; } private String getRetrolambdaJarName() { return "retrolambda.jar"; } private static String getRetrolambdaVersion() throws MojoExecutionException { try { InputStream is = ProcessClassesMojo.class.getResourceAsStream( "/META-INF/maven/net.orfjackal.retrolambda/retrolambda-maven-plugin/pom.properties"); try { Properties p = new Properties(); p.load(is); return p.getProperty("version"); } finally { is.close(); } } catch (IOException e) { throw new MojoExecutionException("Failed to detect the Retrolambda version", e); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy