Skip to content

Commit

Permalink
Use Quarkus Maven plugin to build native executables
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvavrik committed Dec 22, 2023
1 parent f38097e commit 2e932a4
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 6 deletions.
16 changes: 16 additions & 0 deletions examples/amq-amqp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,20 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
19 changes: 19 additions & 0 deletions examples/amq-tcp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
</parent>
<artifactId>examples-amq-tcp</artifactId>
<name>Quarkus - Test Framework - Examples - AMQ TCP</name>
<properties>
<quarkus.build.skip>true</quarkus.build.skip>
</properties>
<dependencies>
<dependency>
<groupId>io.quarkiverse.artemis</groupId>
Expand All @@ -35,4 +38,20 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,17 @@ private Path tryToReuseOrBuildArtifact() {
}

private Path buildArtifact() {
if (QuarkusProperties.isNativePackageType(getContext()) && OS.WINDOWS.isCurrentOs()) {
return new QuarkusMavenPluginBuildHelper(this).buildNativeExecutable();
if (QuarkusProperties.isNativePackageType(getContext())) {
return new QuarkusMavenPluginBuildHelper(this)
.buildNativeExecutable()
.orElseGet(() -> {
LOG.warn("""
Quarkus Maven plugin is missing, falling back to Quarkus bootstrap strategy.
Please add 'quarkus-maven-plugin' to your project as the bootstrap strategy will be removed
in the future.
""");
return buildArtifactUsingQuarkusBootstrap();
});
}
return buildArtifactUsingQuarkusBootstrap();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
Expand All @@ -45,6 +47,11 @@

class QuarkusMavenPluginBuildHelper {

private static final Set<String> FAILSAFE_BUILD_LIFECYCLE_PHASES = Set.of("verify", "install", "deploy",
"integration-test");
// following constant helps us to detect args specified before lifecycle phase like `mvn -Dstuff verify`
// TODO: this should probably be more robust
private static final String LAUNCHER = "org.codehaus.plexus.classworlds.launcher.Launcher";
private static final String JAVA_SUFFIX = ".java";
private static final String POM_XML = "pom.xml";
private final Path appFolder;
Expand All @@ -58,10 +65,38 @@ class QuarkusMavenPluginBuildHelper {
this.appFolder = resourceBuilder.getApplicationFolder();
this.appClassNames = Arrays.stream(resourceBuilder.getAppClasses()).map(Class::getName).collect(toUnmodifiableSet());
this.forcedDependencies = List.copyOf(resourceBuilder.getForcedDependencies());
this.cmdLineBuildArgs = Set.copyOf(resourceBuilder.getBuildPropertiesSetAsSystemProperties());
this.cmdLineBuildArgs = findMavenCommandLineArgs();
}

Path buildNativeExecutable() {
private static Set<String> findMavenCommandLineArgs() {
Set<String> mvnArgs = new HashSet<>();
ProcessHandle processHandle = ProcessHandle.current();
do {
if (processHandle.info().arguments().isPresent()) {
String[] args = processHandle.info().arguments().get();
boolean keepArgs = false;
for (String arg : args) {
if (arg == null) {
// this is probably not necessary, but let's stay on the safe side
continue;
}
if (keepArgs && arg.startsWith("-D")) {
mvnArgs.add(arg);
} else if (LAUNCHER.equals(arg) || FAILSAFE_BUILD_LIFECYCLE_PHASES.contains(arg)) {
// order is important here - we only want to propagate mvn args
keepArgs = true;
}
}
if (keepArgs) {
return mvnArgs;
}
}
processHandle = processHandle.parent().orElse(null);
} while (processHandle != null);
throw new IllegalStateException("Failed to detect mvn command line arguments");
}

Optional<Path> buildNativeExecutable() {
// this snapshot helps to determine next time app is restarted whether build is necessary (what has changes)
createSnapshotOfBuildProperties.run();

Expand Down Expand Up @@ -113,8 +148,7 @@ Path buildNativeExecutable() {
nativeRunnerExpectedLocation += EXE;
}
return findTargetFile(mavenBuildProjectRoot.resolve(TARGET), nativeRunnerExpectedLocation)
.map(Path::of)
.orElseThrow(() -> new IllegalStateException("Native executable is missing"));
.map(Path::of);
}

private String[] getBuildNativeExecutableCmd() {
Expand Down

0 comments on commit 2e932a4

Please sign in to comment.