CLI-based maven artifact launcher: create classpath based on artifacts in repo and invoke main(...)?

In our maven-based build pipeline we currently collect all the dependencies for a given artifact in target/lib and then create an empty runnable jar pointing to said dependencies, which can then be invoked in the same way as inside Eclipse.

This works well for us, but now I was wondering if we could simplify the process by distributing a maven repository containing just the needed artifacts and have a tiny launcher which - just given the main artifact "coordinates" - can create a classpath pointing the main artifact in the repository (without any copying step) along with all the transitive dependencies, and then invoke main(....)?

I.e what Maven itself can do, but only with the "locate the appropriate artifacts in a single, offline repository" and "create classpath and invoke class" functionality. No network access. No range resolving, etc. The smaller the better.

Any suggestions?

Upvotes: 1

Views: 229

Answers (3)

parsifal
parsifal

Reputation: 1663

The easiest solution IMO is the shade plugin. It creates an "uber-JAR" that contains all of the dependencies inside it.

The primary downside to this plugin is if you have non-class files that live in the same classpath location (this happens a lot with Spring configuration files). You need to tell the plugin how to resolve any overlaps.

You can create an offline repository that holds all of your dependencies. Spring, in fact, does this for its training classes. However, to make this work you need to ensure that the user doesn't have an overriding settings.xml (which is unlikely if you're relying on them to already have Maven). But, if the stars all align, it becomes a matter of passing mvn:exec the right parameters.


@ThorbjørnRavnAndersen - your question seemed to be about creating a runnable JAR; the Maven part appeared to be your approach to a solution. I'm not sure why you would want to deliver a Maven repository, but the translation from G/A/V to repository location is fairly straightforward, and something that you could do with a bit of XPath. Or you could turn to Aether, but that seems to go against your "lightweight, no network, no version ranges" criteria.

Perhaps you could explain why an uber-JAR doesn't suit your needs?

Upvotes: 0

aldrinleal
aldrinleal

Reputation: 3609

The Appassembler Maven Plugin does it.

One of the projects I've made with it was get-another-label. You can look at its pom to get an idea of how it works.

Another solution is pomstrap, which looks like scm:checkout on steroids:

http://pomstrap.tigris.org/

Upvotes: 0

khmarbaise
khmarbaise

Reputation: 97389

I'm not sure but you can take a look at the appassembler-maven-plugin which will generated shell-/batch file which will automatically generate the classpath inside the scripts and afterwards you can package that to a resulting zip file with all dependencies etc. and you can simply unpack the zip and start the bat/sh script to run the application on command line?

The other option might be to use the maven-exec-plugin but it's more intended to execute java/external programms more for the build time but might work also for your purposes.

Upvotes: 1

Related Questions