如何解析位于外部库中的java类?

问题描述 投票:0回答:1

我目前正在开发一个插件,可以从枚举创建降价表。 例如,如果我有这个枚举:

enum MyEnum {
  /**
   * Documentation for 1
   */
  MYCONSTANT1(1),
  MYCONSTANT2(2);
  // rest is omitted
}

插件将生成此表:

代码 姓名 描述
1 我的常量1 1 个文档
2 我的常数2

该插件目前需要java文件的路径才能运行,并且工作正常。

我的问题是,如果枚举位于外部工件/库中,则无法使该插件工作,因为它们存储在 jar 中。

我的感觉告诉我,应该有一种可靠的方法来使用 maven 插件 api 或其他一些库来获取 java 文件,但缺乏文档让这对我来说真的很困难。

我应该如何解决这个问题?

有没有办法通过类引用可靠地获取源文件,例如

com.example.MyEnum

我尝试阅读文档,但找不到有关该问题的太多信息。 我也尝试使用 chatgpt,但它产生了太多代码的幻觉,而且由于这个问题非常具体,它无法找到我可以使用的答案。

编辑

我意识到仅仅获取编译后的源文件并反编译它并不那么简单,因为它不包含文档。最好的解决方案是下载工件的源代码,然后解析类文件,就像我在源代码位于项目文件中时所做的那样。

maven maven-plugin documentation-generation maven-plugin-development
1个回答
0
投票

我深入研究了 maven 插件开发文档,我发现您可以使用

RepositorySystem
组件来解析工件源。

ArtifactRequest artifactRequest = new ArtifactRequest(artifact, project.getRemoteProjectRepositories(), null);
ArtifactResult artifactResult = repositorySystem.resolveArtifact(session.getRepositorySession(), artifactRequest)

通过这种方式,您可以在插件的依赖项中定义包含类源的工件,并在运行时解析它。从那里您只需加载 jar 文件并读取其源代码。

这是通过引用获取源文件的完整示例:

private Optional<File> getSourceFile() {
  return execution.getPlugin()
                  .getDependencies()
                  .stream()
                  .map(dependency -> findSourceFileInDependency(sourceClass, dependency))
                  .filter(Objects::nonNull)
                  .findFirst();
}

private File findSourceFileInDependency(String sourceClass, Dependency dependency) {
  String sourceFileName = sourceClass.replace(".", "/") + ".java";
  DefaultArtifact artifact = new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), "sources", "jar", dependency.getVersion());
  ArtifactRequest artifactRequest = new ArtifactRequest(artifact, project.getRemoteProjectRepositories(), null);

  try {
    File artifactFile = repositorySystem.resolveArtifact(session.getRepositorySession(), artifactRequest)
                                        .getArtifact()
                                        .getFile();
    try (JarFile jarFile = new JarFile(artifactFile);
         InputStream sourceFileIs = jarFile.getInputStream(jarFile.getEntry(sourceFileName))) {
      File sourceFile = File.createTempFile(String.format("%s_%s", UUID.randomUUID(), sourceFileName), ".java");
      sourceFile.deleteOnExit();

      Files.copy(sourceFileIs, sourceFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

      return sourceFile;
    } catch (IOException | NullPointerException e) {
    }
  } catch (ArtifactResolutionException e) {
  }

  return null;
}
© www.soinside.com 2019 - 2024. All rights reserved.