通过Classloader加载Maven工件

时间:2016-02-24 09:32:21

标签: java maven classloader

是否可以在运行时通过Maven加载远程工件,例如使用特定的(Maven)ClassLoader?

对于我的用例,遗留软件在启动测试框架期间使用 URLClassLoader 来提取包含一些资源文件的JAR。

问题是我们目前只使用指向存储库的固定URL而根本不使用Maven工件解析。

将这个添加到项目依赖项是没有选择的,因为我们想从外部配置文件引用特定版本(使用不同版本的打包用例运行测试框架而不更改代码)。

我希望你得到我想要达到的目标 - 它不一定是最漂亮的解决方案,因为我们目前依赖于固定的网址模式,我希望依赖于本地maven设置

1 个答案:

答案 0 :(得分:8)

您可以使用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() });