muhqu
muhqu

Reputation: 12809

How to get path to dependency jar with maven

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?

Upvotes: 15

Views: 15216

Answers (5)

muhqu
muhqu

Reputation: 12809

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

Upvotes: 4

Jim Sellers
Jim Sellers

Reputation: 553

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>

Upvotes: 5

Terran
Terran

Reputation: 1153

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

Upvotes: 11

Janus Troelsen
Janus Troelsen

Reputation: 21290

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();
}

Upvotes: 0

SubOptimal
SubOptimal

Reputation: 22973

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

<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>

Upvotes: 1

Related Questions