【问题标题】:Can you get plugin configuration from a POM using aether?您可以使用以太从 POM 获取插件配置吗?
【发布时间】:2016-09-16 17:35:48
【问题描述】:

我需要阅读 Java 中的插件配置。我已经使用 aether 库来获取运行时依赖项、编译时依赖项等。但是我可以使用 aether 来读取基于 pom 文件的插件配置吗?

类似的东西

<properties>
  <servicePort>8080</servicePort>
  <adminPort>8081</adminPort>
</properties>

<build>
  <plugins>
    <plugin>
      <groupId>com.company.group</groupId>
      <artifactId>my-plugin</artifactId>
      <version>0.1-SNAPSHOT</version>
      <configuration>
        <myConfig>
          <somePropName>someProp</somePropName>
          <portMappings>
            <someProp>${servicePort}</someProp>
            <someProp-admin>${adminPort}</someProp-admin>
          </portMappings>
        </myConfig>
      </configuration>
    </plugin>
  </plugins>
</build>

我希望能够解决

some-Prop 8080
some-prop-admin 8081 

从这个机制

目前我像这样获取编译关系依赖项

Dependency dependency = new Dependency(new DefaultArtifact(
                    coordinate), COMPILE);
CollectRequest collectRequest = new CollectRequest();
collectRequest.setRoot(dependency);

collectRequest.addRepository(this.aetherSession
        .getRemoteRepository());
DependencyNode node = this.aetherSession
        .getRepoSystem()
        .collectDependencies(this.aetherSession.getRepoSession(),
                collectRequest).getRoot();
DependencyRequest dependencyRequest = new DependencyRequest();
dependencyRequest.setRoot(node);
result = this.aetherSession
        .getRepoSystem()
        .resolveDependencies(this.aetherSession.getRepoSession(),
                dependencyRequest).getArtifactResults();
FinalResult.addAll(result);

【问题讨论】:

  • 你能发布你当前的代码来获取编译时依赖吗?您是在编写 Maven 插件还是外部应用程序?
  • 这是一个 java 应用程序,我想使用 aether 从 pom 中读取插件配置

标签: java xml maven aether


【解决方案1】:

我不知道是否有更简单的方法,但是您可以使用 Aether API 来解析您感兴趣的 POM 工件,然后使用 Model Builder API 从中构建一个 Maven 模型。

首先,如果您的工件的坐标不是 POM 工件,您需要通过创建具有相同 GAV 但类型为 "pom" 的新 DefaultArtifact 将它们转换为 POM 工件。要解析工件,您可以在存储库系统上调用resolveArtifact,并使用getArtifact() 检索结果。

获得已解析的工件后,您可以使用maven-model-builder 从工件文件构建 Maven 模型。 ModelBuilder 可以使用DefaultModelBuilderFactory.newInstance() 工厂方法创建。

对于具有父 POM 的工件,需要在请求中设置 ModelResolver 以构建模型。但是,Aether 唯一可用的实现是 DefaultModelResolver,是 maven-aether-provider 内部的包私有,因此我们需要使用反射 API 来构造它。它需要注入由MavenRepositorySystemUtils.newServiceLocator() 返回的serviceLocator 检索的组件。这需要与构建 Aether 会话时使用的定位器相同。

DefaultArtifact artifact = new DefaultArtifact(coordinate);
Artifact pomArtifact = new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion());

ArtifactRequest request = new ArtifactRequest(pomArtifact, Arrays.asList(aetherSession.getRemoteRepository()), null);
pomArtifact = aetherSession.getRepoSystem().resolveArtifact(session, request).getArtifact();

ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
ModelBuildingRequest buildingRequest = new DefaultModelBuildingRequest();
buildingRequest.setPomFile(pomArtifact.getFile());
buildingRequest.setProcessPlugins(true);
buildingRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);

Constructor<?> constr = Class.forName("org.apache.maven.repository.internal.DefaultModelResolver").getConstructors()[0];
constr.setAccessible(true);
ModelResolver modelResolver = (ModelResolver) constr.newInstance(session, null, null,
        serviceLocator.getService(ArtifactResolver.class),
        serviceLocator.getService(VersionRangeResolver.class),
        serviceLocator.getService(RemoteRepositoryManager.class), request.getRepositories());
buildingRequest.setModelResolver(modelResolver);

Model model = modelBuilder.build(buildingRequest).getEffectiveModel();

Xpp3Dom pluginConfiguration = (Xpp3Dom) model.getBuild().getPluginsAsMap().get("com.company.group:my-plugin").getConfiguration();
Xpp3Dom myConfig = pluginConfiguration.getChild("myConfig");
System.out.println(myConfig.getChild("somePropName").getValue()); // prints "someProp"

默认情况下,模型构建器未配置为处理插件,因此我们需要调用setProcessPlugin(true)。获得有效模型后,配置将包含在Xpp3Dom 对象中,您可以在getChild(name) 的帮助下导航以获取命名的子XML 元素,并使用getValue() 获取XML 元素的值。

【讨论】:

  • 尝试测试上面的代码,虽然它获取的是jar而不是pom
  • @user_mda 我已经包含了获取 POM 而不是 JAR 的代码。看看Artifact pomArtifactbuildingRequest.setPomFile(pomArtifact.getFile());
  • 是的,我复制了相同的代码,但解析失败,因为 pomArtifact.getFile() 给了我一个 jar
  • pom 工件是用new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion()); 构造的,所以它不应该引用JAR,第三个参数是扩展名,这里是"pom"(在我的测试中没有我做了)。你用什么coordinate
  • 是的,这就是我所期望的,我使用以下来分配坐标——String.format("%s:%s:%s", groupID, artifactID, version);
猜你喜欢
  • 2019-02-20
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 1970-01-01
相关资源
最近更新 更多