Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

download and execute jar file from remote maven repository

Tags:

java

maven

jar

That might be a dumb question but somehow I cannot figure it out (even with the lots of already given answers on stackoverflow) how to do it:

  • I created a maven project
  • I called mvn package and can execute the jar file with java -jar ... and everything works fine.
  • After I deploy the jar into the remote repository, I want everyone in my team to be able to just call a maven command (like mvn exec:java or something like that) on the command line and Maven shall download the jar file from the remote repository and execute it.

Independent of the current directory in which the user is. How do I do that? Currently I get the error message that I need to be in a directory with an existing pom.xml file.

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>
    <groupId>handof.nod</groupId>
    <artifactId>clirunnertest</artifactId>
    <version>1.0</version>
    <name>CLIRunnerTest</name>
    <description>Kleines Testprogramm um zu testen wie Spring Boot auf der Command Line funktioniert</description>
    <packaging>jar</packaging>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- Package as an executable jar/war -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>java</executable>
                    <arguments>
                        <argument>-jar</argument>
                        <argument>target/clirunnertest-1.0.jar</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
like image 543
the hand of NOD Avatar asked Oct 26 '17 20:10

the hand of NOD


2 Answers

Your requirements are quite specific, there are ways to do what you want, but you may not find them suitable for your needs. In a nutshell, your requirements are:

  • Download a Maven artifact from a repository and execute it (supposing it is available on a repo)
  • BUT this needs to be "independent of the current directory in which the user is", i.e. your user should be able to run the command line from anywhere - that's the tricky part, because most Maven plugins require a pom and none will be available.

Solution 1:

What you can do is, in a single command line, download your artifact from the repo and execute it, with something like:

mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.2:copy -Dartifact=handof.nod:clirunnertest:1.0.0:jar -DoutputDirectory=. && java -jar clirunnertest.jar 

What it does is:

  1. Download the jar file using the maven-dependency-plugin (which does not require any POM, lucky us)
  2. Run a java command with your freshly downloaded jar (there are variants such as java -cp clirunnertest.jar MyMainClass

Solution 2:

Solution 1 require your user to specify the java command and its argument, not very flexible. With this solution you'll be able to change the way the command runs without impacting the end user.

First you will need to create a small project containing your exec:java or exec:exec configuration and upload it in your Maven repository, alongside with the jar you want to execute. You only need to write a standalone pom.xml with your jar dependency and related exec configuration such as:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>handof.nod</groupId>
    <artifactId>clirunnertest-pomrunnerproject</artifactId>
    <version>0.1</version>
    <packaging>pom</packaging>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <id>run-java</id>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>handof.nod.clirunnertest.MainClassOrWhatever</mainClass>
                    <arguments>
                        <argument>bla</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>handof.nod</groupId>
            <artifactId>clirunnertest</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
</project>

Once this project is available on your Maven repository, you can run:

mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.2:copy -Dartifact=handof.nod:clirunnertest-pomrunnerproject:0.1:pom -DoutputDirectory=. && mvn exec:java -f clirunnertest-pomrunnerproject-0.1.pom

That will download the pom for this project and execute it like any other Maven project.

You can also do it in two times, first download the pom with the copy goal somewhere on your machine, and then run it from anywhere by specifying the path to the downloaded pom using the -f parameter:

mvn exec:java -f /path/to/the/pom/clirunnertest-pomrunnerproject-0.1.pom

This allow you to run this command from anywhere as long as you specify the path of the pom.


As you see, though they work, these solutions (and many variant you can imagine like these, such as having a bash script available on Nexus, having said configuration in a parent pom and using a sub-project with the -f parameter to use it from anywhere, etc.) are not really flexible nor easy to use and distribute. Maven may not be the best tool to achieve what you want, though implementing your own plugin as you discussed may be a solution ;)

like image 71
Pierre B. Avatar answered Nov 15 '22 03:11

Pierre B.


There is not a single step to do so, and Maven generally wants to be able to use the ~/.m2 folder as a working area. You can however do it in two steps.

  1. Download the artifact directly with dependency:get - see How can I download a specific Maven artifact in one command line? for details.
  2. Then they have the jar file and can start it as usual.

You can also create a pom.xml file for it which the users can download (again as an artifact) and then set it up for mvn exec:java.

If this is something you want to do on a regular basis, I will suggest a regular deployment! Java WebStart works well if you have a webserver somewhere you can store the files.

like image 34
Thorbjørn Ravn Andersen Avatar answered Nov 15 '22 04:11

Thorbjørn Ravn Andersen