如何使用maven获取依赖jar的路径
How to get path to dependency jar with maven
给定一个简单的 Maven 项目,例如将 JUnit 作为依赖项,我如何获取 junit.jar
的完整文件路径,它会安装到本地 Maven 存储库中?!
例如如何从工件 junit:junit
到 /Users/foobar/.m2/repository/junit/junit/4.11/junit-4.11.jar
?
路径构建为 $repository_dir/groupId/artifactId/version/artifactId-version.jar
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
一个 hacky 解决方案 使用 mvn dependency:build-classpath
和一些 unix shell 魔法从类路径中提取 jar 路径。
我们有一个这样的 pom.xml
...
<?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>
然后我们生成一个build_classpath
文件。
$ 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
现在我们可以使用一些脚本 foo...
从 build_classpath
中提取 jar 文件路径
$ cat build_classpath | perl -ne 'print "" if /(?:^|:)([^:]+?\/junit-[0-9\.]+\.jar)/'
/Users/foobar/.m2/repository/junit/junit/4.11/junit-4.11.jar
编辑
更简单的 shell 命令,用于 OSX,它只是将每个条目拆分到它自己的行中。 grep 所需依赖项的输出很简单。请注意,该命令字面上使用换行符(换行到下一行)而不是换行符。
$ tr ':' '
' < build_classpath; echo
从the following SO answer开始,看起来最简单的就是使用antrun插件。
<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>
如果你想在你的 运行 代码中获取路径,你可以这样做:
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>
代码:
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();
}
maven 依赖插件有一个目标 'properties'。来自 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.
所以像这样的东西应该可以解决问题:
<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>
然后属性 ${junit:junit:jar}
应该包含jar文件路径
给定一个简单的 Maven 项目,例如将 JUnit 作为依赖项,我如何获取 junit.jar
的完整文件路径,它会安装到本地 Maven 存储库中?!
例如如何从工件 junit:junit
到 /Users/foobar/.m2/repository/junit/junit/4.11/junit-4.11.jar
?
路径构建为 $repository_dir/groupId/artifactId/version/artifactId-version.jar
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
一个 hacky 解决方案 使用 mvn dependency:build-classpath
和一些 unix shell 魔法从类路径中提取 jar 路径。
我们有一个这样的 pom.xml
...
<?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>
然后我们生成一个build_classpath
文件。
$ 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
现在我们可以使用一些脚本 foo...
从build_classpath
中提取 jar 文件路径
$ cat build_classpath | perl -ne 'print "" if /(?:^|:)([^:]+?\/junit-[0-9\.]+\.jar)/'
/Users/foobar/.m2/repository/junit/junit/4.11/junit-4.11.jar
编辑
更简单的 shell 命令,用于 OSX,它只是将每个条目拆分到它自己的行中。 grep 所需依赖项的输出很简单。请注意,该命令字面上使用换行符(换行到下一行)而不是换行符。
$ tr ':' '
' < build_classpath; echo
从the following SO answer开始,看起来最简单的就是使用antrun插件。
<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>
如果你想在你的 运行 代码中获取路径,你可以这样做:
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>
代码:
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();
}
maven 依赖插件有一个目标 'properties'。来自 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.
所以像这样的东西应该可以解决问题:
<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>
然后属性 ${junit:junit:jar}
应该包含jar文件路径