java - Maven Resolver 始终从远程存储库下载 maven-metadata.xml

标签 java maven dependencies repository

我目前正在开发一个项目,该项目具有用于 Maven 依赖项的内置库加载器。

这是我当前的代码:

public class ResolverTest {
    
    private static final File LOCAL_REPO_DIR = new File("localRepo");
    
    public static void main(String[] args) throws MalformedURLException, DependencyResolutionException {
        downloadLibraries(
            Arrays.asList(
                "https://repo1.maven.org/maven2/",
                "https://repository.apache.org/content/repositories/snapshots/"
            ),
            List.of("commons-io:commons-io:2.12.0-SNAPSHOT")
        );
    }
    
    public static List<URL> downloadLibraries(List<String> repositories, List<String> libraries) throws DependencyResolutionException, MalformedURLException {
        // setup connection
        var locator = MavenRepositorySystemUtils.newServiceLocator();
        locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
        locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
        
        var repoSystem = locator.getService(RepositorySystem.class);
        
        var session = MavenRepositorySystemUtils.newSession();
        session.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_FAIL);
        session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_NEVER);
        session.setLocalRepositoryManager(repoSystem.newLocalRepositoryManager(session, new LocalRepository(LOCAL_REPO_DIR)));
        session.setTransferListener(new LoggingTransferListener());
        session.setReadOnly();
        
        List<RemoteRepository> remoteRepos = new ArrayList<>();
        
        var repoIdx = 0;
        for (var repoUrl : repositories) {
            remoteRepos.add(new RemoteRepository.Builder(String.valueOf(repoIdx), "default", repoUrl).build());
            repoIdx++;
        }
        
        remoteRepos = repoSystem.newResolutionRepositories(session, remoteRepos);
        
        // download libraries
        var request = new DependencyRequest(
            new CollectRequest(
                (Dependency) null,
                libraries.stream().map(library ->
                    new Dependency(new DefaultArtifact(library), null)
                ).toList(),
                remoteRepos
            ),
            null
        );
        
        var results = repoSystem.resolveDependencies(session, request).getArtifactResults();
        
        var urls = new ArrayList<URL>();
        for (var result : results) {
            urls.add(result.getArtifact().getFile().toURI().toURL());
        }
        
        return urls;
    }
    
    private static class LoggingTransferListener extends AbstractTransferListener {
        
        @Override
        public void transferInitiated(TransferEvent event) {
            System.out.println("Init transfer " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName());
        }
        
    }
    
}
implementation("org.apache.maven:maven-resolver-provider:3.8.6")
implementation("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3")
implementation("org.apache.maven.resolver:maven-resolver-transport-http:1.8.2")

我遇到的问题是,每次重新启动程序并再次调用库加载器时,解析器都会尝试从所有存储库下载依赖项的 maven-metadata.xml 文件在之前的尝试中没有。

这似乎只发生在快照依赖项上。

在上面的示例中,我还使用了RepositoryPolicy.UPDATE_POLICY_NEVER。如果将其设置为RepositoryPolicy.UPDATE_POLICY_ALWAYS,则解析器会从所有存储库中提取元数据(就像它应该的那样)。 那么,即使设置了 UPDATE_POLICY_NEVER,为什么它仍然从其他存储库中提取呢?

将 session 设置为离线模式 (session.setOffline(true);) 也不起作用:maven 解析器抛出 DependencyResolutionException: org.eclipse.aether.resolution.DependencyResolutionException :无法在离线模式下访问中心(https://repo.maven.apache.org/maven2),并且之前尚未从中下载 Artifact ( Artifact 的路径)。(依赖项位于我的本地存储库中,但不是从中央下载的)

最佳答案

嗯...

// this one prevents maven from downloading metadata.xml
// if I understand properly it tries to find maven-metadata-0.xml
// in local repository and in case of failure tries remote repositories
session.setResolutionErrorPolicy(new SimpleResolutionErrorPolicy(true, false));

// this one prevents maven from creating _remote.repositories files
// in local repository, yours: in my local repo, but wasn't downloaded from central
session.setLocalRepositoryManager(repoSystem.newLocalRepositoryManager(session, new LocalRepository(LOCAL_REPO_DIR, "simple")));

关于java - Maven Resolver 始终从远程存储库下载 maven-metadata.xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73479191/

相关文章:

java - 高效获取Java 2D数组的row.max和row.sum

java - 使用不同的组件(功能)构建自定义 Java 对象

java - 轻量级,不断更新的 Java 图表

java - 如何使用 Eclipse 和 Maven 配置 Java 项目以连接到 Amazon RDS

maven - 依赖类型 ejb 和 ejb-client 有什么区别

java - 如何构建依赖于另一个项目的 Gradle 项目,但使本地路径不受版本控制?

java - Gradle 子项目对共享代码的依赖

android - 构建 gradle : Could not find method packagingOptions() for arguments root Project "fasterDev"

java - 打印数字三角形 - 两个正方形

java - Java 11 的 GitLab Auto DevOps 问题