Skip to content

Commit

Permalink
Support for maven plugin (resolve) on fat jar
Browse files Browse the repository at this point in the history
It's useful occasionally to do dependency computations on fat jars.
The thin jar launcher already supports it, so this just adds a step
in the maven plugin that means we don't *require* a thin jar to
be the target of the project build.
  • Loading branch information
Dave Syer committed Feb 12, 2020
1 parent 492a078 commit ad19fd9
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 3 deletions.
8 changes: 7 additions & 1 deletion maven-plugin/pom.xml
Expand Up @@ -18,6 +18,7 @@
<properties>
<maven.version>3.1.1</maven.version>
<plexus-archiver.version>3.4</plexus-archiver.version>
<dependency.version>2.3.1</dependency.version>
</properties>

<dependencies>
Expand All @@ -35,6 +36,11 @@
<artifactId>maven-plugin-api</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.twdata.maven</groupId>
<artifactId>mojo-executor-maven-plugin</artifactId>
<version>${dependency.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
Expand Down Expand Up @@ -85,7 +91,7 @@
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
Expand Down
Expand Up @@ -17,21 +17,39 @@
package org.springframework.boot.experimental.maven;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.BuildPluginManager;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
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;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.StringUtils;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;

import static org.twdata.maven.mojoexecutor.MojoExecutor.artifactId;
import static org.twdata.maven.mojoexecutor.MojoExecutor.configuration;
import static org.twdata.maven.mojoexecutor.MojoExecutor.element;
import static org.twdata.maven.mojoexecutor.MojoExecutor.executeMojo;
import static org.twdata.maven.mojoexecutor.MojoExecutor.executionEnvironment;
import static org.twdata.maven.mojoexecutor.MojoExecutor.goal;
import static org.twdata.maven.mojoexecutor.MojoExecutor.groupId;
import static org.twdata.maven.mojoexecutor.MojoExecutor.name;
import static org.twdata.maven.mojoexecutor.MojoExecutor.plugin;
import static org.twdata.maven.mojoexecutor.MojoExecutor.version;

/**
* Resolves the dependencies for a thin jar artifact (or a set of them). The deployable
Expand All @@ -58,7 +76,25 @@ public class ResolveMojo extends ThinJarMojo {
private File outputDirectory;

/**
* A list of the deployable thin libraries that must be downloaded and assembled.
* Directory containing the thin launcher.
*/
@Parameter(defaultValue = "${project.build.directory}/thin", required = true, property = "thin.jarDirectory")
private File jarDirectory;

/**
* Artifact containing the thin launcher
* (group:artifact:version[:packaging[:classifier]]).
*/
@Parameter(defaultValue = "org.springframework.boot.experimental:spring-boot-thin-launcher:1.0.24.BUILD-SNAPSHOT:jar:exec", required = true, property = "thin.launcherArtifact")
private String thinLauncherArtifact;

/**
* A list of the deployable thin libraries that must be do
*
* @Component private RepositorySystemSession session;
*
* @Component private RemoteRepositoryManager remoteRepositoryManager;wnloaded and
* assembled.
*/
@Parameter
private List<Dependency> deployables;
Expand All @@ -81,6 +117,15 @@ public class ResolveMojo extends ThinJarMojo {
@Component
protected ArchiverManager archiverManager;

@Component
private MavenProject mavenProject;

@Component
private MavenSession mavenSession;

@Component
private BuildPluginManager pluginManager;

@Override
public void execute() throws MojoExecutionException, MojoFailureException {

Expand Down Expand Up @@ -116,6 +161,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {
"No deployables found. If your only deployable is the current project jar, you need to run 'mvn package' at the same time.");
}

File thinJar = downloadThinJar();

for (File deployable : deployables) {
getLog().info("Deploying: " + deployable);
try {
Expand All @@ -124,7 +171,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {

FileUtils.copyFile(deployable,
new File(outputDirectory, deployable.getName()));
runWithForkedJvm(deployable, outputDirectory);
runWithForkedJvm(thinJar, outputDirectory,
"--thin.archive=" + deployable.getAbsolutePath());
}
catch (Exception e) {
throw new MojoExecutionException("Cannot locate deployable " + deployable,
Expand Down Expand Up @@ -156,4 +204,53 @@ public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("All deployables and dependencies ready in: " + outputDirectory);
}

private File downloadThinJar() throws MojoExecutionException, MojoFailureException {

executeMojo(
plugin(groupId("org.apache.maven.plugins"),
artifactId("maven-dependency-plugin"), version("3.1.1")),
goal("copy"),
configuration(
element(name("outputDirectory"), jarDirectory.getAbsolutePath()),
element(name("artifact"), thinLauncherArtifact),
element(name("stripVersion"), "true")),
executionEnvironment(mavenProject, mavenSession, pluginManager));
Artifact jar = decode(thinLauncherArtifact);
File from = new File(jarDirectory, jarFile(jar, null));
File to = new File(jarDirectory, jarFile(jar, jar.getVersion()));
try {
FileUtils.rename(from, to);
}
catch (IOException e) {
throw new MojoFailureException("Cannot rename file", e);
}
return to;

}

private String jarFile(Artifact jar, String version) {
return jar.getArtifactId() + (StringUtils.isEmpty(version) ? "" : "-" + version)
+ (StringUtils.isEmpty(jar.getClassifier()) ? ""
: "-" + jar.getClassifier())
+ "." + jar.getExtension();
}

private Artifact decode(String artifact) throws MojoFailureException {
String[] tokens = StringUtils.split(artifact, ":");
if (tokens.length < 3 || tokens.length > 5) {
throw new MojoFailureException("Invalid artifact, you must specify "
+ "groupId:artifactId:version[:packaging[:classifier]] " + artifact);
}
String classifier = null;
String packaging = "jar";
if (tokens.length >= 4) {
packaging = tokens[3];
}
if (tokens.length == 5) {
classifier = tokens[4];
}
return new DefaultArtifact(tokens[0], tokens[1], classifier, packaging,
tokens[2]);
}

}

0 comments on commit ad19fd9

Please sign in to comment.