66
77import com .google .common .base .Joiner ;
88import com .google .common .collect .ImmutableMap ;
9+ import java .io .*;
10+ import java .lang .reflect .Method ;
11+ import java .net .URL ;
12+ import java .net .URLClassLoader ;
13+ import java .util .*;
14+ import org .apache .maven .artifact .Artifact ;
915import org .apache .maven .execution .MavenSession ;
1016import org .apache .maven .plugin .*;
1117import org .apache .maven .plugins .annotations .*;
1218import org .apache .maven .project .MavenProject ;
1319import org .apache .maven .toolchain .*;
1420
15- import java .io .*;
16- import java .util .*;
1721
1822import static org .twdata .maven .mojoexecutor .MojoExecutor .*;
1923
@@ -63,6 +67,16 @@ abstract class ProcessClassesMojo extends AbstractMojo {
6367 */
6468 @ Parameter (defaultValue = "1.7" , property = "retrolambdaTarget" , required = true )
6569 public String target ;
70+
71+ /**
72+ * Should we start new process or perform the retrolambdafication in the
73+ * same VM as Maven runs in (which has to be 1.8 then)? If the VM is
74+ * forked, it uses -javaagent argument to intercept class definitions.
75+ * When we run in the same process, we hook into the class generation
76+ * by internal "lambda dumping" API.
77+ */
78+ @ Parameter (defaultValue = "false" )
79+ public boolean fork ;
6680
6781 protected abstract File getInputDir ();
6882
@@ -79,7 +93,11 @@ public void execute() throws MojoExecutionException {
7993 retrieveRetrolambdaJar (version );
8094
8195 getLog ().info ("Processing classes with Retrolambda" );
82- processClasses ();
96+ if (fork ) {
97+ processClassesWithAgent ();
98+ } else {
99+ processClasses ();
100+ }
83101 }
84102
85103 String getJavaCommand () {
@@ -130,7 +148,7 @@ private void retrieveRetrolambdaJar(String version) throws MojoExecutionExceptio
130148 executionEnvironment (project , session , pluginManager ));
131149 }
132150
133- private void processClasses () throws MojoExecutionException {
151+ private void processClassesWithAgent () throws MojoExecutionException {
134152 String retrolambdaJar = getRetrolambdaJarPath ();
135153 executeMojo (
136154 plugin (groupId ("org.apache.maven.plugins" ),
@@ -155,6 +173,33 @@ private void processClasses() throws MojoExecutionException {
155173 element ("arg" , attribute ("value" , retrolambdaJar ))))),
156174 executionEnvironment (project , session , pluginManager ));
157175 }
176+
177+ private void processClasses () throws MojoExecutionException {
178+ String retrolambdaJar = getRetrolambdaJarPath ();
179+ File jar = new File (retrolambdaJar );
180+
181+ try {
182+ StringBuilder sb = new StringBuilder ();
183+ sb .append (getInputDir ());
184+ for (Artifact a : project .getArtifacts ()) {
185+ if (a .getFile () != null ) {
186+ sb .append (File .pathSeparator );
187+ sb .append (a .getFile ());
188+ }
189+ }
190+
191+ URLClassLoader url = new URLClassLoader (new URL [] { jar .toURI ().toURL () });
192+ Class <?> mainClass = Class .forName ("net.orfjackal.retrolambda.Main" , true , url );
193+ System .setProperty ("retrolambda.bytecodeVersion" , "" + targetBytecodeVersions .get (target ));
194+ System .setProperty ("retrolambda.inputDir" , getInputDir ().getAbsolutePath ());
195+ System .setProperty ("retrolambda.outputDir" , getOutputDir ().getAbsolutePath ());
196+ System .setProperty ("retrolambda.classpath" , sb .toString ());
197+ Method main = mainClass .getMethod ("main" , String [].class );
198+ main .invoke (null , (Object ) new String [0 ]);
199+ } catch (Exception ex ) {
200+ throw new MojoExecutionException ("Cannot initialize classloader for " + retrolambdaJar , ex );
201+ }
202+ }
158203
159204 private String getRetrolambdaJarPath () {
160205 return getRetrolambdaJarDir () + "/" + getRetrolambdaJarName ();
0 commit comments