ShrinkWrap Resolver 3.0.0-alpha-2 Released
Since we wrote this post we didn't laze around. Check our latest announcement.
The Arquillian team is proud to announce the 3.0.0-alpha-2 release of the ShrinkWrap Resolver component!
You probably know the cases when you have to build a project before running another one or before running tests to use a created archive. Maven Importer provided by ShrinkWrap Resolver can partially help you with it – it compiles the classes and collects dependencies from the pom.xml
file. However, you cannot use Maven plugins, profiles or some variables as it doesn’t do the real Maven build – it just tries to simulate it. You can definitely imagine a situation that you don’t have any Maven binary installed in your local repository or that you need different Maven version for one specific build. That’s why ShrinkWrap Resolver introduces a new feature: Embedded Maven.
Embedded Maven
Embedded Maven provides you a possibility to invoke a Maven build for a selected project directly from your Java code. Internally, it uses maven-invoker and mainly the classes Invoker and InvocationRequest, which basically offers the functionality of running Maven builds directly from the Java code.
So now there can arise some questions: Why should I use Embedded Maven? What are the benefits?
There are bunch of functions added to make the usage more user friendly. The most significant additional functions are:
- downloading and using Maven binaries that the user desires
- uncluttered API (you can write code that runs either trivial or complex builds in one single line)
- additional methods & functions (eg. ignoring build failures or making the build output quiet)
- Java class representing a built project
- easy way of getting a ShrinkWrap Archive created by the build, so you can further enrich it if needed
- automatic functions such as skipping tests and formatting a build output
- possibility to use one’s
Invoker
andInvocationRequest
instances
- and more …
How can I use it?
Your starting point is a class EmbeddedMaven which offers you three methods. At this point you have to decide which approach of setting Maven build options you want to follow.
1) ShrinkWrap Resolver API
Recommended
You can use ShrinkWrap Resolver API that offers additional features in more comfortable but slightly limited way. This approach is linked with these two methods:
EmbeddedMaven.forProject(File pomFile)
EmbeddedMaven.forProject(String pomFile)
Why it is limited? Contrary to second approach or to the pure maven-invoker
:
- you cannot set neither output handler nor error handler because it is already set by ShrinkWrap Resolver. On the other hand, it has three positive effects:
I) the output is automatically formatted (with a prefix->
to make the output visibly separated)
II) after the completion, the build output is accessible using method BuiltProject#getMavenLog
III) you can easily suppress the build output using method ConfigurationStage#setQuiet - you cannot set a project you want to build by setting base directory and a file name separately.
- there are no methods for setting Maven home and binaries, because it is set by ShrinkWrap Resolver itself.
2) Using your own Maven Invoker
With the second approach, you can use your own Invoker
and InvocationRequest
instances. If you use it, then it is expected that all settings are done by yourself so no automatic features are provided by ShrinkWrap Resolver. This approach is linked with the method:
EmbeddedMaven.withMavenInvokerSet(InvocationRequest request, Invoker invoker)
Why it is less comfortable? You can see the differences in these two test cases that does completely the same thing but using different approaches: first approach second approach
These are the disadvantages:
- methods such as
setGoals
andsetProfiles
accept only a list of string. - you have to set the property
skipTests
for eachInvocationRequest
if you don’t want to run the tests. - you don’t have an access to the Maven build output after the build completion
- the build output is not automatically formatted and it cannot be easily suppressed
- the methods for setting Maven home or binaries are accessible in
Invoker
object, but it is advised not to use them as the Maven home is used by ShrinkWrap Resolver
Downloading Maven binaries
In case when there is no Maven binaries installed on the machine or when another Maven version is needed for some specific build, you can ask ShrinkWrap Resolver to download the specific version from the Apache web pages and use it. For this purpose there is a method:
EmbeddedMaven.forProject("path/to/pom.xml").useMaven3Version(String version)
where the desired version is expected (eg: useMaven3Version("3.3.9")
). This version is downloaded from Apache web pages and the downloaded zip is cached in a directory $HOME/.arquillian/resolver/maven/
to not download it over and over again. Zip file is extracted in
${project.directory}/target/resolver-maven/${generated_UUID}
and the path to the extracted binaries is set as Maven home applicable for the build.
There are three more methods for setting Maven binaries that should be used for the build.
EmbeddedMaven.forProject("path/to/pom.xml").useDistribution(URL mavenDist, boolean useCache)
where you need to specify a URL the distribution should be downloaded from. You should also specify if the cache directory should be used. If useCache
is false
, then the zip file is downloaded into ${project.directory}/target/resolver-maven/downloaded
.
Next method
EmbeddedMaven.forProject("path/to/pom.xml").useInstallation(File mavenHome)
uses Maven installation located on the given path.
Last method:
EmbeddedMaven.forProject("path/to/pom.xml").useDefaultDistribution()
basically does nothing. It just says that the default Maven installation that is on your PATH
should be used. It is same as you wouldn’t use any of these methods.
Explanation of additional features:
Skipping tests
Using ShrinkWrap Resolver API approach, there is no need to set the skipTests
property if you don’t want to run any test as it is set automatically. If you still want to run tests, then you can use method: ConfigurationStage#skipTests
Ignoring failures
If the Maven build fails, then an IllegalStateException
is thrown by default. If you use method BuildStage#ignoreFailure, then failures of the Maven build is ignored and a BuiltProject instance with a non-zero value stored in mavenBuildExitCode variable is returned.
BuiltProject
BuiltProject is a Java class that represents a built project. An instance of this class is returned by the method build()
when the Maven build is completed. The most useful method is probably:
builtProject.getDefaultBuiltArchive()
that returns an archive with a default name that was created by the Maven build. As a “default archive name” is understood:
- either combination of artifactId + version + packaging suffix (eg.
- or a finalName set in
<build>
section of project’s POM file + packaging suffix
if no archive with a corresponding name is found, then null
is returned. null
is also returned for the projects with packaging=pom
as it is usually a parent project with a set of modules. To get all modules that are specified use the method:
builtProject.getModules()
which returns list of BuiltProject instances. If you know the name (string within an element <module>
in the parent’s POM file) of a module you are interested in, you can use:
builtProject.getModule(String moduleName)
There are several other useful methods provided by this Java class. For more information see BuiltProject
Examples
First example is just packaging a project and getting the default archive out of it:
EmbeddedMaven.forProject("some/pom.xml").setGoals("package").build().getDefaultBuiltArchive();
Then let’s say that we want to build some project using goals
clean
and package
and with activated profile production
:BuiltProject builtProject = EmbeddedMaven.forProject("path/to/pom.xml")
.setGoals("clean", "package")
.setProfiles("production")
.build();
Then you can get the default archive:
Archive archive = builtProject.getDefaultBuiltArchive();
or all Java archives, that are contained in the build directory:
List javaArchives = builtProject.getArchives(JavaArchive.class);
Let’s say that we want to use Maven 3.1.0 for building a project with a goal install
and property wildfly=true
. We also don’t want to display the build output and we want to ignore all possible build failures:
EmbeddedMaven.forProject("path/to/pom.xml")
.useMaven3Version("3.1.0")
.setGoals("install")
.addProperty("wildfly", "true")
.setQuiet()
.ignoreFailure()
.build();
Some additional examples can be found in integration tests here and here.
What is ShrinkWrap Resolver?
The ShrinkWrap Resolvers project provides a Java API to obtain artifacts from a repository system. This is handy to include third party libraries available in any Maven repository in your test archive. ShrinkWrap Resolvers additionally allow you to reuse all the configuration you've already specified in the Maven build file, making packaging of an application archive much easier job.
Release details
Component | ShrinkWrap Resolver |
---|---|
Version | 3.0.0-alpha-2 view tag |
Release date | 2016-11-30 |
Released by | Matous Jobanek |
Compiled against |
|
Published artifacts org.jboss.shrinkwrap.resolver
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-bom pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-api jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-spi jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-depchain pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-api-maven jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-impl-maven jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-api-maven-archive jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-spi-maven jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-spi-maven-archive jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-impl-maven-archive jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-api-maven-embedded jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-impl-maven-embedded jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-api-gradle-embedded-archive jar javadoc pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-gradle-depchain pom
- org.jboss.shrinkwrap.resolver » shrinkwrap-resolver-impl-gradle-embedded-archive jar javadoc pom
Release notes and resolved issues 5
- Feature Request
-
- SHRINKRES-256 - Add Maven BOM to SWR shrinkwrap-resolver-bom
- SHRINKRES-257 - Implement EmbeddedMaven
- Bug
-
- SHRINKRES-238 - Maven resolver always throws at with(out)Transitivity
- SHRINKRES-239 - maven version incompatibility? Caused by: java.lang.AbstractMethodError \tat org.apache.maven.model.building.DefaultModelBuilder.readParentExternally(DefaultModelBuilder.java:899)
- SHRINKRES-241 - Wrong maven-aether-provider dependency for some reason
Thanks to the following list of contributors: Matous Jobanek, Andrew Lee Rubinger, Michal Matloka, George Gastaldi