我目前正在开发一个项目,该项目具有用于 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/