68

For my current purposes I have a Maven project which creates a war file, and I want to see what actual classpath it is using when creating the war. Is there a way to do that in a single command -- without having to compile the entire project?

One idea is to have Maven generate the target/classpath.properties file and then stop at that point.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Alexander Bird
  • 38,679
  • 42
  • 124
  • 159

7 Answers7

109

To get the classpath all by itself in a file, you can:

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

Or add this to the POM.XML:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.9</version>
        <executions>
          <execution>
            <id>build-classpath</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>build-classpath</goal>
            </goals>
            <configuration>
              <!-- configure the plugin here -->
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

From: http://maven.apache.org/plugins/maven-dependency-plugin/usage.html

Janik Zikovsky
  • 3,086
  • 7
  • 26
  • 34
  • 14
    The `mvn dependency:build-classpath` will by default ouput the classpath for the `test` [dependency scope](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope) which includes `system`, `provided`, `compile`, `runtime` and `test`. If you want to get the classpath for `compile` or `runtime` scopes. You can use `-Dmdep.includeScope=compile` – RubenLaguna Oct 27 '17 at 15:53
  • 2
    @ecerulm Thank you, that's a very valuable detail. But `-DincludeScope=compile` has worked for me instead of `-Dmdep.includeScope`. – Pavel S. May 16 '18 at 10:12
  • I've added a complementary [answer](https://stackoverflow.com/a/50368537/1512875) below that allows specifying a desired scope. – Pavel S. May 16 '18 at 10:38
  • 1
    In my use-case I wanted the classpath printed on stdout without having to mess with temporary files. This works: `mvn dependency:build-classpath -Dmdep.includeScope=runtime -Dmdep.outputFile=/dev/fd/4 4>&1 >/dev/null` – pmakholm Aug 07 '18 at 12:26
  • To get it to STDOUT in Linux (and no logging messages) you can use `mvn dependency:build-classpath -Dmdep.outputFile=/dev/stdout -q` – peschü Dec 04 '19 at 09:20
  • I got this error when right click mvnw.cmd > open in terminal [ERROR] Unknown lifecycle phase ".outputFile=cp.txt". You must specify a valid lifecycle phase or a goal in the forma........ – user1169587 Jan 15 '23 at 10:40
22

This command outputs the classpath on Mac and Linux:

mvn -q exec:exec -Dexec.executable=echo -Dexec.args="%classpath"

Having the result printed and not saved into a file might be useful, for instance, when assigning the result to a variable in a Bash script. This solution runs on Mac and Linux only, but so do Bash shell scripts.

In Windows (e.g. in BAT files), where there is no echo executable, you will need something like this (untested):

mvn -q exec:exec -Dexec.executable=cmd -Dexec.args="/c echo %classpath"

Alternatively, you can just execute java program with the classpath:

mvn -q exec:exec -Dexec.executable=java -Dexec.args="-cp %classpath Main"

Or even like that (it will use the correct classpath automatically):

mvn -q exec:java -Dexec.mainClass="Main" 

However, both these alternative approaches suffer from Maven adding its error messages when your program fails.

Danila Piatov
  • 1,201
  • 15
  • 15
17

or call "mvn -e -X ...." and check the output...

Philip Helger
  • 1,814
  • 18
  • 28
  • I don't think that solves the problem because showing errors and debug information doesn't help output the classpath being used. – Alexander Bird May 20 '13 at 18:06
  • 5
    the debug information contains the whole classpath for each involved lifecycle plugin (incl. other things as well) – Philip Helger May 20 '13 at 18:48
  • Thank you sir, I wrote an iteration over your solution, feel free to reuse any of it if you consider it beneficial for the future reader, because right now my answer it's at the bottom and few people will read it (http://stackoverflow.com/a/37551032/2265487) – ElMesa May 31 '16 at 16:31
11

As ecerulm noted in his comment to Janik's answer, you may want to specify the scope to dependency:build-classpath, as classpath output will differ for different scopes (by default test is used for some reason). I've ended up with a command like this:

mvn -DincludeScope=compile dependency:build-classpath

Within the POM, it could be used like this:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.9</version>
        <executions>
          <execution>
            <id>build-classpath</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>build-classpath</goal>
            </goals>
            <configuration>
              <includeScope>compile</includeScope>
              <!-- Omit to print on console: -->
              <outputFile>${project.build.directory}/compile-classpath.txt</outputFile>
            </configuration>
          </execution>
          <execution>
            <id>build-test-classpath</id>
            <phase>generate-test-sources</phase>
            <goals>
              <goal>build-classpath</goal>
            </goals>
            <configuration>
              <includeScope>test</includeScope>
              <!-- Omit to print on console: -->
              <outputFile>${project.build.directory}/test-classpath.txt</outputFile>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

This will output 2 versions of classpath, one for main build and the other for tests.

Pavel S.
  • 1,202
  • 1
  • 13
  • 29
8

The command mvn dependency:list will list the classpath with all the jars used for compilation, runtime and test in the following format:

INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ MyProject ---
[INFO]
[INFO] The following files have been resolved:
[INFO]    org.netbeans.api:org-openide-filesystems:jar:RELEASE80:compile
[INFO]    org.netbeans.api:org-netbeans-modules-queries:jar:RELEASE80:compile
[INFO]    org.netbeans.api:org-netbeans-api-progress:jar:RELEASE80:compile
[INFO]    org.netbeans.api:org-openide-dialogs:jar:RELEASE80:compile
[INFO]    org.apache.derby:derby:jar:10.11.1.1:compile
[INFO]    org.netbeans.api:org-openide-windows:jar:RELEASE80:compile

The only requirement is that the compilation is finished. It doesn't work if the compilation isn't ran.

An other command is The command mvn dependency:tree.

Paul Guralivu
  • 89
  • 1
  • 3
6

Added the missing arg for scope to Janiks answer. Now it is complete. You are welcome.

mvn -q exec:exec -Dexec.classpathScope="compile" -Dexec.executable="echo" -Dexec.args="%classpath" 
mjs
  • 21,431
  • 31
  • 118
  • 200
1

This is a single command solution but does compile the code.

mvn -e -X -Dmaven.test.skip=true clean compile | grep -o -P '\-classpath .*? ' | awk '{print $2}'

Shell script example usage

MAVEN_CLASSPATH=$(mvn -e -X -Dmaven.test.skip=true clean compile | grep -o -P '\-classpath .*? ' | awk '{print $2}')

I used a variation of it in a shell script to run a standalone main() (for Hibernate schema generation) this way

#/bin/bash

MAVEN_TEST_CLASSPATH=$(mvn -e -X clean package | grep -o -P '\-classpath .*?test.*? ')

java $MAVEN_TEST_CLASSPATH foo.bar.DBSchemaCreate

File output example

mvn -e -X -Dmaven.test.skip=true clean compile | grep -o -P '\-classpath .*? ' | awk '{print $2}' > maven.classpath
Community
  • 1
  • 1
ElMesa
  • 928
  • 8
  • 19
  • With maven 3.3.9, your grep-command does not return anything (unfortunately, I can not see any classpath when running with -e -X). Is there maybe an update to this solution? – David Georg Reichelt Dec 20 '16 at 14:19
  • Tested right now on Mint 18 (based on Ubuntu 16.04) and it works :O. Could you provide console responses for `uname -a` and `maven --version` ? On the tested system with successful results the are $ uname -a --> `"Linux ******* 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux"`. $ mvn --version --> `"Apache Maven 3.3.9; Java version: 1.8.0_111, vendor: Oracle Corporation; OS name: 'linux', version: '4.4.0-21-generic', arch: 'amd64', family: 'unix'` – ElMesa Dec 21 '16 at 16:28
  • Note that if you are not in Linux grep may not be on your system (like in windows) or could behave differently (like on macos for some combination of options). If you are on windows you could try Cygwin or MinGW to have grep, but I don't know if you'll have problems similar to macos, where the Cygwin or MinGW could behave differently than the one used on the Ubuntu 16.04 packages. (if you use windows and find useful the MinGW or Cygwin approach please let me know to update the answer) – ElMesa Dec 21 '16 at 16:32