簡體   English   中英

在 Java 程序中從 Maven 存儲庫下載工件

[英]Download artifact from Maven repository in Java program

我需要編寫從給定 Maven 存儲庫下載給定工件 (GAV) 的 Java 代碼。 過去我使用了 Nexus 2 的 REST 接口(這很容易),但我想要一些獨立於所使用的存儲庫(Nexus 2、Nexus 3、Artifactory)的東西。

Fetching Maven artifacts programmatically 中提出了類似的問題,但主要答案來自 2014 年,並建議自 2014 年以來未更新的庫。

可以使用 Aether(版本 1.1.0)做以下事情:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;


public class ArtifactDownload
{

  private static RepositorySystem newRepositorySystem()
  {
    DefaultServiceLocator locator = MavenRepositorySystemUtils
        .newServiceLocator();
    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,
      File localRepository)
  {
    DefaultRepositorySystemSession session = MavenRepositorySystemUtils
        .newSession();
    LocalRepository localRepo = new LocalRepository(localRepository.toString());
    session.setLocalRepositoryManager(system.newLocalRepositoryManager(session,
        localRepo));
    return session;
  }


  public static File getArtifactByAether(String groupId, String artifactId,
      String version, String classifier, String packaging, File localRepository)
      throws IOException
  {
    RepositorySystem repositorySystem = newRepositorySystem();
    RepositorySystemSession session = newSession(repositorySystem,
        localRepository);

    Artifact artifact = new DefaultArtifact(groupId, artifactId, classifier,
        packaging, version);
    ArtifactRequest artifactRequest = new ArtifactRequest();
    artifactRequest.setArtifact(artifact);

    List<RemoteRepository> repositories = new ArrayList<>();

    RemoteRepository remoteRepository = new RemoteRepository.Builder("public",
        "default", "http://somerepo").build();

    repositories.add(remoteRepository);

    artifactRequest.setRepositories(repositories);
    File result;

    try
    {
      ArtifactResult artifactResult = repositorySystem.resolveArtifact(session,
          artifactRequest);
      artifact = artifactResult.getArtifact();
      if (artifact != null)
      {
        result = artifact.getFile();
      }
      else
      {
        result = null;
      }
    }
    catch (ArtifactResolutionException e)
    {
      throw new IOException("Artefakt " + groupId + ":" + artifactId + ":"
          + version + " konnte nicht heruntergeladen werden.");
    }

    return result;

  }
}

使用以下工件

    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-api</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-spi</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-impl</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-connector-basic</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-transport-file</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-transport-http</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-aether-provider</artifactId>
      <version>${mavenVersion}</version>
    </dependency>

<aetherVersion>1.1.0</aetherVersion>
<mavenVersion>3.3.3</mavenVersion>

我最近發現自己需要從 Maven 存儲庫下載文件。 我偶然發現(在: https : //www.hascode.com/2017/09/downloading-maven-artifacts-from-a-pom-file-programmatically-with-eclipse-aether/#comment-5602 )跟隨https: //github.com/shrinkwrap/resolver庫,它比 Eclipse Aether 項目更容易使用。

String artifactoryUrl = "https://your-repo:port/repository";
String[] requiredTypes = new String[] { "zip", "xml" };

for (String requiredType : requiredTypes) {
    MavenResolvedArtifact[] result = Maven.configureResolver()
            .withMavenCentralRepo(false)
            .withRemoteRepo("default", artifactoryUrl, "default")
            .useLegacyLocalRepo(true) // You can also set to ignore origin of artifacts present in local repository via useLegacyLocalRepo(true) method.
            .resolve(
                    group + ":" +
                    id + ":" +
                    requiredType + ":" +
                    version
            )
            .withTransitivity()
            .asResolvedArtifact();

    for (MavenResolvedArtifact mavenResolvedArtifact : result) {
        System.out.println(mavenResolvedArtifact);
        System.out.println(mavenResolvedArtifact.asFile().getAbsolutePath());
    }
 }

您正在描述maven-dependency-plugin 的功能(獲取目標)

因此,在 maven 插件的上下文中,Java 代碼可以完全滿足您的需求。

我會簡單地

  • github檢索get插件的源代碼
  • 刪除所有 maven 插件的東西(@Component 依賴注入、參數)
  • 在需要的地方集成它的要點(並添加對所需的內部 maven 庫的依賴)

您可以使用 aether API 下載 Maven 工件,該 API 將下載給定 POM.xml 文件中的 jars

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.DefaultModelBuilderFactory;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.ModelBuilder;
import org.apache.maven.model.building.ModelBuildingResult;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.Proxy;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.repository.RemoteRepository.Builder;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.aether.util.repository.DefaultProxySelector;

public class DownloadingArtifactsByPomExample {

public static final String TARGET_LOCAL_REPOSITORY = "target/local-repository";

public static void main(String[] args) throws Exception {
    File projectPomFile = new 
File("C:\\Users\\user\\Desktop\\TEST_Aether\\test\\pom.xml");
//Paths.get("","pom.xml").toAbsolutePath().toFile();

    System.out.printf("loading this sample project's Maven descriptor from %s\n", 
projectPomFile);
    System.out.printf("local Maven repository set to %s\n",
            Paths.get("", TARGET_LOCAL_REPOSITORY).toAbsolutePath());

    RepositorySystem repositorySystem = getRepositorySystem();
    RepositorySystemSession repositorySystemSession = 
getRepositorySystemSession(repositorySystem);

    final DefaultModelBuildingRequest modelBuildingRequest = new 
DefaultModelBuildingRequest()
            .setPomFile(projectPomFile);

    ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
    ModelBuildingResult modelBuildingResult = 
modelBuilder.build(modelBuildingRequest);

    Model model = modelBuildingResult.getEffectiveModel();
    System.out.printf("Maven model resolved: %s, parsing its dependencies..\n", 
model);
    for (Dependency d : model.getDependencies()) {
        System.out.printf("processing dependency: %s\n", d);
        Artifact artifact = new DefaultArtifact(d.getGroupId(), d.getArtifactId(), 
d.getType(), d.getVersion());
        ArtifactRequest artifactRequest = new ArtifactRequest();
        artifactRequest.setArtifact(artifact);
        artifactRequest.setRepositories(getRepositories(repositorySystem, 
repositorySystemSession));

        try {
            ArtifactResult artifactResult = 
repositorySystem.resolveArtifact(repositorySystemSession,
                    artifactRequest);
            artifact = artifactResult.getArtifact();
            // to load the artifact in current classloader
            ClassLoader classLoader = new URLClassLoader(new URL[] { 
artifact.getFile().toURI().toURL() });
            URL u = artifact.getFile().toURI().toURL();
            URLClassLoader urlClassLoader = (URLClassLoader) 
ClassLoader.getSystemClassLoader();
            Class urlClass = URLClassLoader.class;
            Method method = urlClass.getDeclaredMethod("addURL", new Class[] { 
URL.class });
            method.setAccessible(true);
            method.invoke(urlClassLoader, new Object[] { u });
            System.out.printf("artifact %s resolved to %s\n", artifact, 
artifact.getFile());
        } catch (ArtifactResolutionException e) {
            System.err.printf("error resolving artifact: %s\n", e.getMessage());
        }

    }

}

public static RepositorySystem getRepositorySystem() {
    DefaultServiceLocator serviceLocator = 
MavenRepositorySystemUtils.newServiceLocator();
    serviceLocator.addService(RepositoryConnectorFactory.class, 
BasicRepositoryConnectorFactory.class);
    serviceLocator.addService(TransporterFactory.class, 
FileTransporterFactory.class);
    serviceLocator.addService(TransporterFactory.class, 
HttpTransporterFactory.class);

    serviceLocator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() {
        @Override
        public void serviceCreationFailed(Class<?> type, Class<?> impl, Throwable 
exception) {
            System.err.printf("error creating service: %s\n", 
exception.getMessage());
            exception.printStackTrace();
        }
    });

    return serviceLocator.getService(RepositorySystem.class);
}

public static DefaultRepositorySystemSession 
getRepositorySystemSession(RepositorySystem system) {
    DefaultRepositorySystemSession repositorySystemSession = 
MavenRepositorySystemUtils.newSession();

    LocalRepository localRepository = new LocalRepository(TARGET_LOCAL_REPOSITORY);
    repositorySystemSession

.setLocalRepositoryManager(system.newLocalRepositoryManager(repositorySystemSession, 
localRepository));

    repositorySystemSession.setRepositoryListener(new 
ConsoleRepositoryEventListener());
    repositorySystemSession.setProxySelector(new DefaultProxySelector()
            .add(new Proxy(Proxy.TYPE_HTTPS, "proxy.tcs.com", 8080), 
Arrays.asList("localhost", "127.0.0.1")));
    return repositorySystemSession;
}

public static List<RemoteRepository> getRepositories(RepositorySystem system, 
RepositorySystemSession session) {
    return Arrays.asList(getCentralMavenRepository());
}

private static RemoteRepository getCentralMavenRepository() {
    // In "http://central.maven.org we can provide local m2 repository location to
    // load the jars into local repo
    // like file://C:user/m2/repository
    RemoteRepository.Builder builder = new Builder("central", "default", " 
   http://central.maven.org/maven2/");
    // for proxy
    builder.setProxy(new Proxy("type", "host", 8080));// port 8080
    RemoteRepository central = builder.build();
    return central;
}

}

import org.eclipse.aether.AbstractRepositoryListener;
import org.eclipse.aether.RepositoryEvent;

public class ConsoleRepositoryEventListener extends AbstractRepositoryListener {

@Override
public void artifactInstalled(RepositoryEvent event) {
    System.out.printf("artifact %s installed to file %s\n, event.getArtifact()", 
event.getFile());
}

@Override
public void artifactInstalling(RepositoryEvent event) {
    System.out.printf("installing artifact %s to file %s\n, event.getArtifact()", 
event.getFile());
}

@Override
public void artifactResolved(RepositoryEvent event) {
    System.out.printf("artifact %s resolved from repository %s\n", event.getArtifact(), event.getRepository());
}

@Override
public void artifactDownloading(RepositoryEvent event) {
    System.out.printf("downloading artifact %s from repository %s\n", event.getArtifact(), event.getRepository());
}

@Override
public void artifactDownloaded(RepositoryEvent event) {
    System.out.printf("downloaded artifact %s from repository %s\n", event.getArtifact(), event.getRepository());
}

@Override
public void artifactResolving(RepositoryEvent event) {
    System.out.printf("resolving artifact %s\n", event.getArtifact());
}

}

<properties>
    <aetherVersion>1.1.0</aetherVersion>
    <mavenVersion>3.2.1</mavenVersion>
</properties>
<dependencies>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-api</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-spi</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-util</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-impl</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-connector-basic</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-transport-file</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-transport-http</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-aether-provider</artifactId>
        <version>${mavenVersion}</version>
    </dependency>
</dependencies>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM