Maven: how to query the executable classpath?

2019-09-10 03:45发布

问题:

I have a maven project with some specified dependencies.

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.4</version>
</dependency>

How can I query maven to find out the path it's using for these dependencies, or the classpath I should use for independent execution?

My goal is to build a wrapper which runs the program with the appropriate classpath.

回答1:

Several alternatives are available in Maven:

Maven Dependency Plugin (build-classpath goal)

Look at the Maven Dependency Plugin, especially the build-classpath goal provides exactly the full classpath for external execution usages. Among many options, The outputFile parameter may be helpful.
You don't need to configure it for usage, just run

mvn dependency:build-classpath

On your project and you'll see the classpath as part of the build output. Or

mvn dependency:build-classpath -Dmdep.outputFile=classpath.txt

To redirect just the classpath to a file.

Maven Dependency Plugin (copy-dependencies goal)

To build a wrapper, you could also look at the copy-dependencies goal, which would copy the required dependencies (jars), including transitive dependencies, to a configured folder (so you don't need hardcoded paths to your local machine).
An example of plugin configuration is available on the official site, here. For instance, the following configuration:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.10</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                        <includeScope>runtime</includeScope>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Would add to the folder target/dependencies all the dependencies declared in scope compile. NOTE: with respect to the linked official example, I added the <includeScope>runtime</includeScope> configuration entry (which will include compile and runtime scoped dependencies, according to documentation and my tests), otherwise it would also include the test scope by default (which is something I believe you would not need at runtime).

Exec Maven Plugin (java or exec goals)

Alternatively, you can use the Exec Maven Plugin to execute a main from Maven using the required classpath.
An example of plugin configuration is available on the official site, here.
The following configuration for instance:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.1</version>
    <executions>
        <execution>
            <id>my-execution</id>
            <phase>package</phase>
            <goals>
                <goal>java</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <mainClass>com.sample.MainApp</mainClass>
    </configuration>
</plugin>

Will configure the Exec plugin to run via mvn exec:java the main class MainApp as configured, obviously with the required classpath.

Maven Assembly Plugin

Lastly, the Maven Assembly Plugin also provides facilities to build an executable jar with dependencies, as explained here, in another question on stackoverflow.