The maven-utils artifact is based on the latest maven 3 release. As such is "should" work together with older distributions of maven. However, to ensure compatibility with older maven versions, separate artifacts are published for maven 3.9.11, 3.9.4, 3.8.4 and 3.3.9. Once a new maven version is released, a new artifact will be published for that version and the maven-utils artifact will be updated to use the latest maven version. The maven-utils artifact will always use the latest maven version and should be used if you want to use the latest features of maven. The other artifacts should be used if you want to ensure compatibility with a particular older maven version.
High level api to interact with maven from within the jvm
Use it by adding the dependency to your maven pom, e.g:
<dependency>
<groupId>se.alipsa</groupId>
<artifactId>maven-utils</artifactId>
<version>1.4.0</version>
</dependency>import org.apache.maven.shared.invoker.InvocationResult;
import se.alipsa.mavenutils.MavenUtils;
File pomFile = new File("pom.xml");
InvocationResult result = MavenUtils.runMaven(pomFile, new String[]{"clean", "install"}, null, null);The arguments to runMaven(final File pomFile, String[] mvnArgs, @Nullable File javaHome, @Nullable InvocationOutputHandler consoleOutputHandler, @Nullable InvocationOutputHandler warningOutputHandler) are as follows:
- pomFile the pom.xml file to parse
- mvnArgs the arguments (targets) to send to maven (e.g. clean install). Flags (like
-DskipTests,-Pprofile,-pl module) are parsed into the appropriate invocation request fields rather than being treated as goals. - javaHome an optional Java home to use for this invocation; if null, the default JAVA_HOME is used
- consoleOutputHandler where normal maven output will be sent, defaults to System.out if null
- warningOutputHandler where maven warning outputs will be sent, defaults to System.err if null
- InvocationResult the result of running the targets
- MavenInvocationException if there is a problem with parsing or running maven
MavenUtils now supports deterministic maven distribution selection with modes:
- WRAPPER
- HOME
- DEFAULT
Default precedence is:
- WRAPPER (
mvnwon Unix,mvnw.cmdon Windows, and.mvn/wrapper/maven-wrapper.propertiespresent) - configured Maven home (when provided through options)
- DEFAULT (
locateMavenHome())
Existing APIs remain backwards compatible but are now wrapper-preferred by default.
Use MavenExecutionOptions to control behavior per call:
import se.alipsa.mavenutils.MavenUtils;
File pomFile = new File("pom.xml");
MavenUtils.MavenExecutionOptions options = new MavenUtils.MavenExecutionOptions(
pomFile.getParentFile(), // projectDir (optional)
null, // configuredMavenHome (optional)
true // preferWrapper
);To get selection metadata for logging/debugging:
import se.alipsa.mavenutils.MavenUtils;
MavenUtils.MavenRunResult runResult = MavenUtils.runMavenWithSelection(
pomFile,
new String[]{"validate"},
null,
options,
null,
null
);
println("Maven mode used: " + runResult.getDistributionSelection().getMode());Note that maven need to be installed locally for DEFAULT mode to work. MavenUtils will first look for the MAVEN_HOME system property, then the MAVEN_HOME environment variable and if still not found will try to locate the mvn command in the PATH.
The static method locateMavenHome is used to find maven home.
import se.alipsa.mavenutils.MavenUtils;
String mavenHome = MavenUtils.locateMavenHome();Get the local repository
import se.alipsa.mavenutils.MavenUtils;
import org.eclipse.aether.repository.LocalRepository;
LocalRepository localRepository = MavenUtils.getLocalRepository();For the methods below, an instance of MavenUtils must be created. This allows you to pass in a list of RemoteRepositories used for the resolution. If you use the default constructor (as in the examples below) you get the Maven Central repository.
import java.io.File;
import org.apache.maven.model.Model;
import se.alipsa.mavenutils.MavenUtils;
File pomFile = new File("pom.xml");
MavenUtils mavenUtils = new MavenUtils();
Model model = mavenUtils.parsePom(pomFile);import java.io.File;
import se.alipsa.mavenutils.MavenUtils;
File pomFile = new File("pom.xml");
MavenUtils mavenUtils = new MavenUtils();
ClassLoader loader = mavenUtils.getMavenDependenciesClassloader(pomFile, this.getClass().getClassLoader())The method is defined as getMavenDependenciesClassloader(File pomFile, @Nullable ClassLoader possibleParent)
import java.util.Set;
import java.io.File;
import se.alipsa.mavenutils.MavenUtils;
File pomFile = new File("pom.xml");
MavenUtils mavenUtils = new MavenUtils();
Set<File> dependencies = mavenUtils.resolveDependencies(pomFile);To get dependency resolution metadata:
MavenUtils.DependenciesResolutionResult resolveResult =
mavenUtils.resolveDependenciesWithSelection(pomFile, options);
println("Maven mode used: " + resolveResult.getDistributionSelection().getMode());
Set<File> dependencies = resolveResult.getDependencies();import se.alipsa.mavenutils.MavenUtils;
import java.io.File;
MavenUtils mavenUtils = new MavenUtils();
File file = mavenUtils.resolveArtifact("org.slf4j", "slf4j-api", null, "jar", "1.7.32");The method is defined as resolveArtifact(String groupId, String artifactId, String classifier, String extension, String version)
- groupId is the same as the tag in the pom.xml
- artifactId is the same as the tag in the pom.xml
- classifier is typically null, javadoc, sources, dist etc
- extension could be pom, jar, zip etc.
- version is the same as the tag in the pom.xml
There is also a simplified version of resolveArtifact requiring only groupId, artifactId and version where classifier is "null" and extension is "jar".
ArtifactLookup fetches maven-metadata.xml from a Maven repository and returns the latest
published version. It can also compare a known version against the latest one using SemanticVersion.
import se.alipsa.mavenutils.ArtifactLookup;
import se.alipsa.mavenutils.CompareResult;
ArtifactLookup lookup = new ArtifactLookup(); // defaults to Maven Central
// Fetch the latest version
String latest = lookup.fetchLatestVersion("org.slf4j", "slf4j-api");
// Or use a dependency string shorthand
String latest2 = lookup.fetchLatestVersion("org.slf4j:slf4j-api");
// Compare a known version against the latest
CompareResult result = lookup.compareWithLatest("org.slf4j", "slf4j-api", "1.7.36");
if (result.compareResult() < 0) {
System.out.println("A newer version is available: " + result.latestVersion());
}
// Compare using a dependency string
CompareResult result2 = lookup.compareWithLatest("org.slf4j:slf4j-api:1.7.36");A custom repository URL can be passed to the constructor:
ArtifactLookup lookup = new ArtifactLookup("https://my.repo.example/maven2/");ArtifactLookup throws NotFoundException when the artifact does not exist and
NetworkException when the repository is unreachable.
For a more elaborate explanation see the maven documentation
Maven-utils uses slf4j for logging so a slf4j implementation needs to be present for logging to work.
The code in this repository is licenced under the MIT license. However, maven-utils depends on a number of other libraries to be able to do its thing. Below is a list of them with their respective license.
Used for logging. Licence: MIT
Used to run maven. Licence: Apache 2.0
Used to run maven and to parse the pom file. License: Apache 2.0
Used to run maven and to parse the pom file. License: Apache 2.0
Used to run maven and to parse the pom file. License: Apache 2.0
Used to resolve dependencies. License: EPL 1.0
Used to resolve dependencies. License: EPL 1.0
Used to resolve dependencies. License: EPL 1.0
Used for unit testing. Licence: EPL 2.0
Used for unit testing. Licence: MIT