通过类加载器加载 Maven 工件
Load Maven Artifact via Classloader
是否可以在 运行 时间内通过 Maven 加载远程工件,例如使用特定的 (Maven) 类加载器?
对于我的用例,遗留软件正在使用 URLClassLoader 在测试框架启动期间提取包含一些资源文件的 JAR。
问题是我们目前只使用固定的 URL 指向存储库,实际上根本没有使用 Maven 工件解析。
将它添加到项目依赖项是不可行的,因为我们想从外部配置文件中引用特定版本(到 运行 具有不同版本的打包用例的测试框架,而无需更改代码) .
我希望你能得到我想要实现的目标——它不一定是最漂亮的解决方案,因为我们目前依赖于固定的 URL 模式,我想依赖本地专家改为设置。
您可以使用 Eclipse Aether (http://www.eclipse.org/aether) 使用 GAV 坐标从 Maven 存储库解析和下载 JAR 工件。
然后对您下载的 JAR 使用常规 URLClassLoader
。
您可以在那里找到一些示例:https://github.com/eclipse/aether-demo/blob/master/aether-demo-snippets/
但基本上,您应该做的是:
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
RepositorySystem system = locator.getService(RepositorySystem.class);
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepository localRepo = new LocalRepository("/path/to/your/local/repo");
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
// Set the coordinates of the artifact to download
Artifact artifact = new DefaultArtifact("<groupId>", "<artifactId>", "jar", "<version>");
ArtifactRequest artifactRequest = new ArtifactRequest();
artifactRequest.setArtifact(artifact);
// Search in central repo
artifactRequest.addRepository(new RemoteRepository.Builder("central", "default", "http://repo1.maven.org/maven2/").build());
// Also search in your custom repo
artifactRequest.addRepository(new RemoteRepository.Builder("your-repository", "default", "http://your.repository.url/").build());
// Actually resolve (and download if necessary) the artifact
ArtifactResult artifactResult = system.resolveArtifact(session, artifactRequest);
artifact = artifactResult.getArtifact();
// Create a classloader with the downloaded artifact.
ClassLoader classLoader = new URLClassLoader(new URL[] { artifact.getFile().toURI().toURL() });
是否可以在 运行 时间内通过 Maven 加载远程工件,例如使用特定的 (Maven) 类加载器?
对于我的用例,遗留软件正在使用 URLClassLoader 在测试框架启动期间提取包含一些资源文件的 JAR。
问题是我们目前只使用固定的 URL 指向存储库,实际上根本没有使用 Maven 工件解析。
将它添加到项目依赖项是不可行的,因为我们想从外部配置文件中引用特定版本(到 运行 具有不同版本的打包用例的测试框架,而无需更改代码) .
我希望你能得到我想要实现的目标——它不一定是最漂亮的解决方案,因为我们目前依赖于固定的 URL 模式,我想依赖本地专家改为设置。
您可以使用 Eclipse Aether (http://www.eclipse.org/aether) 使用 GAV 坐标从 Maven 存储库解析和下载 JAR 工件。
然后对您下载的 JAR 使用常规 URLClassLoader
。
您可以在那里找到一些示例:https://github.com/eclipse/aether-demo/blob/master/aether-demo-snippets/
但基本上,您应该做的是:
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
RepositorySystem system = locator.getService(RepositorySystem.class);
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepository localRepo = new LocalRepository("/path/to/your/local/repo");
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
// Set the coordinates of the artifact to download
Artifact artifact = new DefaultArtifact("<groupId>", "<artifactId>", "jar", "<version>");
ArtifactRequest artifactRequest = new ArtifactRequest();
artifactRequest.setArtifact(artifact);
// Search in central repo
artifactRequest.addRepository(new RemoteRepository.Builder("central", "default", "http://repo1.maven.org/maven2/").build());
// Also search in your custom repo
artifactRequest.addRepository(new RemoteRepository.Builder("your-repository", "default", "http://your.repository.url/").build());
// Actually resolve (and download if necessary) the artifact
ArtifactResult artifactResult = system.resolveArtifact(session, artifactRequest);
artifact = artifactResult.getArtifact();
// Create a classloader with the downloaded artifact.
ClassLoader classLoader = new URLClassLoader(new URL[] { artifact.getFile().toURI().toURL() });