Вне плагина Maven способ работы с артефактами осуществляется через эфир. У команды есть образец проекта для получения транзитивных зависимостей данного артефакта под названием ResolveTransitiveDependencies
. Если у вас есть зависимости Эфира настроенные (like shown here), вы можете просто:
public static void main(final String[] args) throws Exception {
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
RepositorySystem system = newRepositorySystem(locator);
RepositorySystemSession session = newSession(system);
RemoteRepository central = new RemoteRepository.Builder("central", "default", "http://repo1.maven.org/maven2/").build();
Artifact artifact = new DefaultArtifact("group.id:artifact.id:version");
CollectRequest collectRequest = new CollectRequest(new Dependency(artifact, JavaScopes.COMPILE), Arrays.asList(central));
DependencyFilter filter = DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE);
DependencyRequest request = new DependencyRequest(collectRequest, filter);
DependencyResult result = system.resolveDependencies(session, request);
for (ArtifactResult artifactResult : result.getArtifactResults()) {
System.out.println(artifactResult.getArtifact().getFile());
}
}
private static RepositorySystem newRepositorySystem(DefaultServiceLocator locator) {
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
return locator.getService(RepositorySystem.class);
}
private static RepositorySystemSession newSession(RepositorySystem system) {
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepository localRepo = new LocalRepository("target/local-repo");
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
return session;
}
Это загрузит артефакты и поместить их в "target/local-repo"
.
Обратите внимание, что вы можете настроить прокси и зеркала с помощью DefaultProxySelector
и DefaultMirrorSelector
в системном сеансе. Можно было бы прочитать файл настройки Maven и использовать его для заполнения сессии, но все становится очень некрасиво очень быстро ...
Если вы хотите, тесную связь с самой Maven, потому что у вас есть доступ к POM для обработки и принятия во внимание настроек, гораздо проще напрямую вызывать Maven программно. В этом случае вам интересен путь каждой зависимости, включая транзитивные зависимости, заданного POM-файла. Для этого цель dependency:list
вместе с установкой outputAbsoluteArtifactFilename
на true
даст (почти) именно это.
Чтобы программно использовать Maven, можно использовать Invoker API. Добавление зависимости к проекту:
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-invoker</artifactId>
<version>2.2</version>
</dependency>
вы можете иметь:
InvocationRequest request = new DefaultInvocationRequest();
request.setPomFile(new File(pomPath));
request.setGoals(Arrays.asList("dependency:list"));
Properties properties = new Properties();
properties.setProperty("outputFile", "dependencies.txt"); // redirect output to a file
properties.setProperty("outputAbsoluteArtifactFilename", "true"); // with paths
properties.setProperty("includeScope", "runtime"); // only runtime (scope compile + runtime)
// if only interested in scope runtime, you may replace with excludeScope = compile
request.setProperties(properties);
Invoker invoker = new DefaultInvoker();
// the Maven home can be omitted if the "maven.home" system property is set
invoker.setMavenHome(new File("/path/to/maven/home"));
invoker.setOutputHandler(null); // not interested in Maven output itself
InvocationResult result = invoker.execute(request);
if (result.getExitCode() != 0) {
throw new IllegalStateException("Build failed.");
}
Pattern pattern = Pattern.compile("(?:compile|runtime):(.*)");
try (BufferedReader reader = Files.newBufferedReader(Paths.get("dependencies.txt"))) {
while (!"The following files have been resolved:".equals(reader.readLine()));
String line;
while ((line = reader.readLine()) != null && !line.isEmpty()) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
// group 1 contains the path to the file
System.out.println(matcher.group(1));
}
}
}
Это создает запрос вызова, который содержит: цели для вызова и свойства системы, так же, как вы бы запустить mvn dependency:list -Dprop=value
на командная строка. Путь к используемым настройкам будет по умолчанию равным стандарту "${user.home}/settings.xml"
, но также можно указать путь к настройкам с помощью request.setUserSettingsFile(...)
и request.setGlobalSettingsFile(...)
. Invoker должен быть установлен для дома Maven (т. Е. Установочного каталога), но только если системное свойство "maven.home"
не установлено.
Результат вызова dependency:list
перенаправлен на файл, который позже обрабатывается после обработки. Выход этой цели состоит из списка зависимостей в формате (классификатор может отсутствовать, если их нет):
group.id:artifact.id:type[:classifier]:version:scope:pathname
Существует не способ вывода только путь файла устраненного артефакта , и тот факт, что классификатор может отсутствовать, усложняет разбор бит (мы не можем разделить на :
с пределом, так как путь может содержать :
...). Во-первых, разрешенные артефакты находятся ниже строки "The following files have been resolved:"
в выходном файле, тогда, поскольку требуемый объем составляет только compile
или runtime
, мы можем получить путь к файлу артефакта с простым регулярным выражением, которое занимает все, что после compile:
или runtime:
, Затем этот путь можно использовать непосредственно как new File
.
Если обручи во время постобработки выглядят слишком хрупкими, я думаю, вы могли бы создать свой собственный плагин, который просто выводит имя файла разрешенного артефакта.
Я не думаю, что это происходит в правильном направлении. Взгляните на ['dependency: get'] (http://maven.apache.org/plugins/maven-dependency-plugin/get-mojo.html) вместо – janos
Если у вас нет файла POM и только есть координаты, вы можете посмотреть на Эфир. Чтобы получить прямые зависимости от эфира, [вы можете сослаться на этот мой ответ] (http://stackoverflow.com/questions/39638138/find-all-direct-dependencies-of-an-artifact-on-maven-central) , Если у вас есть POM, то использование 'dependency: get -Dtransitive = false' будет получать прямые зависимости намного проще. Взгляните на [Invoker API] (http://maven.apache.org/shared/maven-invoker/) – Tunaki
Чтобы уточнить: у меня есть файл POM, но код выполняется вне выполнения Maven. Я хочу заполнить URLClassLoader URL-адресами зависимостей в локальном репо (которые, возможно, придется сначала загрузить из удаленного репо). Я не вижу, как плагин поможет мне ... – Puce