How can I run a Java class inside a Maven artifact, automatically resolving dependencies?

If I know the coordinates of the artifact and the class name inside this artifact, can I make Maven run the class, including all its dependencies on the Java classpath?

For example, suppose an employee told me about a tool that I can run that is published in our internal Nexus with the coordinates of the artifact example:cool-tools:1.0.0 . I used this answer to download an artifact. Now I know that the main class name is example.Main . But if I just go to the download location of the artifact and run java -cp cool-tools-1.0.0.jar example.Main , I get NoClassDefFoundError for any cool-tools dependencies.

I know maven-exec-plugin , but as far as I can tell, only for projects where you have the source. Suppose I don’t have access to the source, only with Nexus containing the tool (and all its dependencies). Ideally, I would do something like mvn exec:exec -DmainArtifact='example:cool-tools:1.0.0' -DmainClass='example.Main' , but I don’t think that the exec plugin is really capable of this.

ETA: To be clear, I don't have a local project / POM. I want to do this using only the command line, not writing POM, if possible.

+6
source share
5 answers

There is no turnkey solution for your task. But you can create a simple script to solve this problem:

  • Download pom.xml of your tool from the repo.
  • Download the can of your instrument.
  • Download all its dependencies.
  • Run java for allowed libraries.

Command line:

 > mvn dependency:copy -Dartifact=<tool.group.id>:<tool.artifact.id>:<tool.version>:pom -DoutputDirectory=target > mvn dependency:copy -Dartifact=<tool.group.id>:<tool.artifact.id>:<tool.version> -DoutputDirectory=target > mvn dependency:copy-dependencies -f target/<tool.artifact.id>-<tool.version>.pom -DoutputDirectory=target > java -cp target/* <tool.main.class> 

The. / Target directory will contain your tool + all the dependencies.

More on dependency: copy and dependency: copy-dependency mojos.

Edit

Alternatively, you can create a classpath using libraries in the local repo:

 > mvn dependency:build-classpath -DincludeScope=runtime -f target/<tool.artifact.id>-<tool.version>.pom [-Dmdep.outputFile=/full/path/to/file] 

Learn more about build-classpath mojo.

+7
source

You can download pom from the repository using wget , for example. Then resolve the dependencies and create a path to it, exporting it to a file using Maven. Finally, run with Java and the constructed classpath using something like bash backticks to use the contents of the file.

Like in this answer .

+1
source

u can use IDEs like Intellij idea, which automatically resolves dependencies since you write them in your pom

0
source

As others have already mentioned, there is no solution without creating an additional POM.

One solution would be to use the Maven Shade Plugin in this POM: "This plugin provides the ability to pack an artifact in uber-jar, including its dependencies"

I think the executable JAR is close to what you would like to achieve.

0
source

For me, the first underder almost worked, but I need to tweak the script slightly. In the end, I came up (on a Windows machine) with the following solution:

 > mvn dependency:copy -Dartifact=<tool.group.id>:<tool.artifact.id>:<tool.version>:pom -DoutputDirectory=target > mvn dependency:copy -Dartifact=<tool.group.id>:<tool.artifact.id>:<tool.version> -DoutputDirectory=target > mvn dependency:copy-dependencies -f target/<tool.artifact.id>-<tool.version>.pom -DoutputDirectory=target > cd target > java -cp target/*;<tool.artifact.id>-<tool.version>.jar <tool.main.class> 

On a Unix / Linux machine, the last command has a semicolon ";" must be replaced by a colon ":". When input arguments are entered, just put them in the last line of the script:

 > java -cp target/*;<tool.artifact.id>-<tool.version>.jar <tool.main.class> arg1 arg2 ... 
0
source

Source: https://habr.com/ru/post/971710/


All Articles