代码之家  ›  专栏  ›  技术社区  ›  DoNuT

通过Classloader加载Maven工件

  •  3
  • DoNuT  · 技术社区  · 8 年前

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

    在我的用例中,遗留软件使用 URL类加载器 在测试框架启动期间提取包含一些资源文件的JAR。

    问题是,我们目前只使用指向存储库的固定URL,实际上根本没有使用Maven工件解析。

    将此添加到项目依赖项中是没有选择的,因为我们希望引用外部配置文件中的特定版本(以在不更改代码的情况下使用打包用例的不同版本运行测试框架)。

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

    1 回复  |  直到 8 年前
        1
  •  9
  •   Benjamin    7 年前

    您可以使用Eclipse Aether( http://www.eclipse.org/aether )使用GAV坐标从maven存储库解析和下载JAR工件。

    然后使用常规 URLClassLoader 使用您下载的JAR。

    您可以在那里找到一些示例: 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() });