Move responsibility for generating native images to a maven plugin

To test the native image you now need to add -Dnative to the command line
This commit is contained in:
Stuart Douglas
2018-07-26 10:06:59 +10:00
parent 55f28fe6a3
commit 8f1647fe09
6 changed files with 198 additions and 71 deletions

View File

@@ -87,23 +87,6 @@
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<systemProperties>
<graal.reportAtRuntime>true</graal.reportAtRuntime>
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>shamrock-maven-plugin</artifactId>
@@ -111,7 +94,7 @@
<executions>
<execution>
<goals>
<goal>run</goal>
<goal>build</goal>
</goals>
</execution>
</executions>
@@ -155,10 +138,12 @@
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.jboss.shamrock.runner.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
@@ -187,5 +172,44 @@
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>shamrock-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<id>native-image</id>
<goals>
<goal>native-image</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -78,18 +78,6 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>shamrock-maven-plugin</artifactId>
@@ -97,7 +85,7 @@
<executions>
<execution>
<goals>
<goal>run</goal>
<goal>build</goal>
</goals>
</execution>
</executions>
@@ -167,5 +155,45 @@
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>shamrock-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<id>native-image</id>
<goals>
<goal>native-image</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -190,7 +190,10 @@ public class JaxrsScanningProcessor implements ResourceProcessor {
for (AnnotationInstance instance : instances) {
MethodInfo method = instance.target().asMethod();
if (method.returnType().kind() == Type.Kind.CLASS) {
processorContext.addReflectiveClass(method.returnType().asClassType().name().toString());
String className = method.returnType().asClassType().name().toString();
if(!className.equals(String.class.getName())) {
processorContext.addReflectiveClass(className);
}
}
}
}

View File

@@ -0,0 +1,108 @@
package org.jboss.shamrock.maven;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
@Mojo(name = "native-image", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME)
public class NativeImageMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true, required = true)
protected MavenProject project;
/**
* The directory for compiled classes.
*/
@Parameter(readonly = true, required = true, defaultValue = "${project.build.outputDirectory}")
private File outputDirectory;
@Parameter(defaultValue = "false")
private boolean reportErrorsAtRuntime;
@Parameter(defaultValue = "false")
private boolean debugSymbols;
@Parameter(readonly = true, required = true, defaultValue = "${project.build.finalName}")
private String finalName;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
String graal = System.getenv("GRAALVM_HOME");
if (graal == null) {
throw new MojoFailureException("GRAALVM_HOME was not set");
}
String nativeImage = graal + File.separator + "bin" + File.separator + "native-image";
StringBuilder cp = new StringBuilder();
cp.append(outputDirectory);
for (Artifact dep : project.getArtifacts()) {
if (!dep.getScope().equals("test")) {
cp.append(File.pathSeparator);
cp.append(dep.getFile().getAbsolutePath());
}
}
try {
List<String> command = new ArrayList<>();
command.add(nativeImage);
command.add("--no-server");
command.add("-cp");
command.add(cp.toString());
command.add("-H:IncludeResources=META-INF/.*");
command.add("org.jboss.shamrock.runner.Main");
if (reportErrorsAtRuntime) {
command.add("-H:+ReportUnsupportedElementsAtRuntime");
}
if (debugSymbols) {
command.add("-g");
}
command.add(finalName);
System.out.println(command);
Process process = Runtime.getRuntime().exec(command.toArray(new String[0]), new String[]{}, new File(outputDirectory.getParent()));
new Thread(new ProcessReader(process.getInputStream())).start();
new Thread(new ProcessReader(process.getErrorStream())).start();
if (process.waitFor() != 0) {
throw new RuntimeException("Image generation failed");
}
} catch (Exception e) {
throw new MojoFailureException("Failed to build native image", e);
}
}
private static final class ProcessReader implements Runnable {
private final InputStream inputStream;
private ProcessReader(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public void run() {
byte[] b = new byte[100];
int i;
try {
while ((i = inputStream.read(b)) > 0) {
System.out.print(new String(b, 0, i));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -14,7 +14,7 @@ import org.apache.maven.project.MavenProject;
import org.jboss.shamrock.deployment.ClassOutput;
import org.jboss.shamrock.deployment.Runner;
@Mojo(name = "run", defaultPhase = LifecyclePhase.PROCESS_CLASSES)
@Mojo(name = "build", defaultPhase = LifecyclePhase.PROCESS_CLASSES)
public class ShamrockMojo extends AbstractMojo {
/**

View File

@@ -1,14 +1,8 @@
package org.jboss.shamrock.junit;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import org.junit.runner.Description;
import org.junit.runner.Result;
@@ -44,17 +38,8 @@ public class GraalTest extends BlockJUnit4ClassRunner {
}
private void runInternal(RunNotifier notifier) {
boolean reportAtRuntime = Boolean.getBoolean("graal.reportAtRuntime");
boolean debugSymbols = Boolean.getBoolean("graal.debugSymbols");
if (first) {
first = false;
String graal = System.getenv("GRAALVM_HOME");
if (graal == null) {
notifier.fireTestFailure(new Failure(Description.createSuiteDescription(GraalTest.class), new RuntimeException("GRAALVM_HOME was not set")));
return;
}
String nativeImage = graal + File.separator + "bin" + File.separator + "native-image";
URL mainClassUri = getClass().getClassLoader().getResource("org/jboss/shamrock/runner/Main.class");
if (mainClassUri == null) {
notifier.fireTestFailure(new Failure(Description.createSuiteDescription(GraalTest.class), new RuntimeException("Unable to find shamrock main class")));
@@ -69,27 +54,6 @@ public class GraalTest extends BlockJUnit4ClassRunner {
String path = externalForm.substring(5, jar);
try {
List<String> command = new ArrayList<>();
command.add(nativeImage);
command.add("-jar");
command.add(path);
command.add("-H:IncludeResources=META-INF/.*");
if(reportAtRuntime) {
command.add("-H:+ReportUnsupportedElementsAtRuntime");
}
if(debugSymbols) {
command.add("-g");
}
command.add("--no-server");
Process process = Runtime.getRuntime().exec(command.toArray(new String[0]), new String[]{}, new File(path.substring(0, path.lastIndexOf(File.separator))));
new Thread(new ProcessReader(process.getInputStream())).start();
new Thread(new ProcessReader(process.getErrorStream())).start();
if (process.waitFor() != 0) {
notifier.fireTestFailure(new Failure(Description.createSuiteDescription(GraalTest.class), new RuntimeException("Image generation failed")));
return;
}
String outputFile = path.substring(0, path.lastIndexOf('.'));
System.out.println("Executing " + outputFile);
final Process testProcess = Runtime.getRuntime().exec(outputFile);