14

Given a simple Maven project with for example JUnit as dependency, how do I get the full filepath to the junit.jar inside the local maven repository it will be installed into?!

e.g. How to get from artifact junit:junit to /Users/foobar/.m2/repository/junit/junit/4.11/junit-4.11.jar?

muhqu
  • 12,329
  • 6
  • 28
  • 30

5 Answers5

11

The maven dependency plugin has a goal 'properties'. From documentation:

Goal that sets a property pointing to the artifact file for each project dependency. For each dependency (direct and transitive) a project property will be set which follows the groupId:artifactId:type:[classifier] form and contains the path to the resolved artifact.

So something like this should do the trick:

<properties>
    <maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
</properties>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>${maven-dependency-plugin.version}</version>
    <executions>
        <execution>
            <phase>initialize</phase>
            <goals>
                <goal>properties</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Then the property ${junit:junit:jar} should contain the jar file path

Terran
  • 1,091
  • 18
  • 29
  • 1
    This is actually the best answer. – wilx Feb 25 '20 at 21:35
  • 1
    This works wonderfully in Maven, e.g. when using those properties in Surefire on ``. Unfortunately, IntelliJ IDEA incorrectly imports `` in that case, being unable to resolve the synthetic properties for automatically using them for run configurations. So I ended up defining properties like `${settings.localRepository}/net/bytebuddy/byte-buddy/${bytebuddy.version}\byte-buddy-${bytebuddy.version}.jar` and using them inside of ``. Now IDEA automatically imports the right arguments for running single tests. – kriegaex Apr 30 '20 at 04:21
5

From the following SO answer, it looks like the easiest is to use the antrun plugin.

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <phase>process-resources</phase>
            <configuration>
                <tasks>
                    <echo>${maven.dependency.junit.junit.jar.path}</echo>
                </tasks>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Asbjørn Ulsberg
  • 8,721
  • 3
  • 45
  • 61
Jim Sellers
  • 523
  • 3
  • 15
4

A hacky solution using mvn dependency:build-classpath and some unix shell magic to extract the jar-path from the classpath.

We have a pom.xml like this...

<?xml version="1.0" encoding="UTF-8"?>
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>myproject</artifactId>
  <version>1.0-SNAPSHOT</version>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Then we generate a build_classpath file.

$ mvn dependency:build-classpath -Dmdep.outputFile=build_classpath
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:build-classpath (default-cli) @ myproject ---
[INFO] Wrote classpath file '/Users/foobar/maven-test/build_classpath'.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.050 s
[INFO] Finished at: 2015-01-23T09:17:40+01:00
[INFO] Final Memory: 11M/245M
[INFO] ------------------------------------------------------------------------
$ cat build_classpath
/Users/foobar/.m2/repository/junit/junit/4.11/junit-4.11.jar:/Users/foobar/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar

Now we can extract the jar file path from build_classpath using some scripting foo...

$ cat build_classpath | perl -ne 'print "$1" if /(?:^|:)([^:]+?\/junit-[0-9\.]+\.jar)/'
/Users/foobar/.m2/repository/junit/junit/4.11/junit-4.11.jar

EDIT

Simpler shell command, used in OSX, which simply splits each entry onto it's own line. It's simple to grep the output for whichever dependency is desired. Note, the command literally uses a newline line(wraps to the next line) instead of a newline character.

$ tr ':' '
' < build_classpath; echo
Tony
  • 953
  • 1
  • 10
  • 22
muhqu
  • 12,329
  • 6
  • 28
  • 30
  • This solution is great for a one off without changing your POM, which is pretty much always how I want to do it. – Tony Dec 16 '21 at 19:18
1

The path is build as $repository_dir/groupId/artifactId/version/artifactId-version.jar

<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
SubOptimal
  • 22,518
  • 3
  • 53
  • 69
  • Yeah, sure... but where the dependency is installed really depends on how the user who invokes `mvn` has configured it's maven installation. This can be quiet unfortunate, e.g. on shared build servers etc. I was looking for some command that just outputs where the jar is located. – muhqu Jan 23 '15 at 08:43
  • 1
    What do you mean by `shared build servers.`. The output gives the location of the junit file. – khmarbaise Jan 23 '15 at 09:08
0

If you want to get the path inside your running code, you can do this:

POM:

    <dependency>
        <groupId>com.github.nodyn</groupId>
        <artifactId>jvm-npm</artifactId>
        <version>a0c3f12</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-impl</artifactId>
        <version>1.1.0</version>
    </dependency>
            <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-transport-file</artifactId>
        <version>1.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-connector-basic</artifactId>
        <version>1.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-aether-provider</artifactId>
        <version>3.1.0</version>
    </dependency>

Code:

final String mavenRepositoryPath = "c:\\mvn\\repository";

private static RepositorySystem newRepositorySystem() {
    DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
    locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
    locator.addService(TransporterFactory.class, FileTransporterFactory.class);

    locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() {
        @Override
        public void serviceCreationFailed(Class<?> type, Class<?> impl, Throwable exception) {
            throw new RuntimeException(exception);
        }
    });

    return locator.getService(RepositorySystem.class);
}

private static File getJvmNpmFile() {
    Artifact artifact = new DefaultArtifact("com.github.nodyn:jvm-npm:a0c3f12");

    DefaultRepositorySystemSession session = new org.eclipse.aether.DefaultRepositorySystemSession();
    RepositorySystem system = newRepositorySystem();
    ArtifactRequest request = new ArtifactRequest();
    request.setArtifact(artifact);
    //request.setRepositories(new ArrayList<>( Arrays.asList( new RemoteRepository.Builder( "central", "default", "http://central.maven.org/maven2/" ).build()) ));
    //request.setRepositories( new org.eclipse.aether.DefaultRepositorySystemSession().getLocalRepository() );
    LocalRepository localRepo = new LocalRepository(mvnRepositoryPath);
    session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));

    ArtifactResult result;
    try {
        result = system.resolveArtifact(session, request);
    } catch (ArtifactResolutionException ex) {
        throw new RuntimeException(ex);
    }

    //System.out.println("Resolved artifact " + artifact + " to " + result.getArtifact().getFile() + " from " + result.getRepository());
    return result.getArtifact().getFile();
}
Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196