如何使用注释处理器从 src/main/resources 读取文件?

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

我有一个简单的注释处理器,需要从与注释类相同的项目中读取配置文件。结构示例:

- myproject 
  - src
    - main
      - java
        - my.package.SourceFile
      - resources
        - config.json

在注释处理器中,我尝试读取文件:

FileObject resource = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "", "config.json");

但它会抛出

FileNotFoundException
。我还尝试了其他路径,例如
../resources/config.json
(会抛出
Invalid relative name: ../resources/config.json
)。我尝试将配置文件放入
src/main/java
(甚至
src/main/java/my/package
)中,我不喜欢,但这仍然会抛出
FileNotFoundException

如果我能让

filer.getResource()
告诉我它在哪里,那就已经很有帮助了。为了找出答案,我尝试生成一个文件:

filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "dummy");

myproject/build/classes/main/dummy
中生成。不幸的是,我无法在
SOURCE_PATH
中生成,所以这对找出这个问题没有帮助。

java annotation-processing
6个回答
9
投票

我希望在构建期间(在注释处理之前)将

src/main/resources
中的内容复制到
target/classes
。在这种情况下,您可以像这样打开它们:

ProcessingEnvironment pe = ...;
FileObject fileObject = pe.getFiler()
    .getResource( StandardLocation.CLASS_OUTPUT, "", "config.json" );
InputStream jsonStream = fileObject.openInputStream();

4
投票

我和一位 Lombok 项目开发人员一起研究过这个问题。如果有人知道注释处理,那就是他们了;)

我们的结论是,内部处理请求的

JavacFileManager
没有解析
StandardLocation.SOURCE_PATH
的路径。我们不确定,但这可能与使用 Gradle 构建有关。


1
投票

我遇到了同样的问题,并寻找解决方案一段时间,发现了这个很酷的黑客可以在Android上解决问题

下面你可以看到我的纯 Java/Kotlin 项目的解决方案

fun ProcessingEnvironment.getResourcesDirectory(): File {
val dummySourceFile = filer.createSourceFile("dummy" + System.currentTimeMillis())
var dummySourceFilePath = dummySourceFile.toUri().toString()

if (dummySourceFilePath.startsWith("file:")) {
    if (!dummySourceFilePath.startsWith("file://")) {
        dummySourceFilePath = "file://" + dummySourceFilePath.substring("file:".length)
    }
} else {
    dummySourceFilePath = "file://$dummySourceFilePath"
}

val cleanURI = URI(dummySourceFilePath)

val dummyFile = File(cleanURI)

val projectRoot = dummyFile.parentFile.parentFile.parentFile.parentFile.parentFile

return File(projectRoot.absolutePath + "/resources")
}

0
投票

以下功能对我有用,注释处理器由 gradle 触发,它不是漂亮的功能,但有效:

private fun resolveApplicationPropertiesFile(): File {
    val projectRoot = Path.of(processingEnv.filer.getResource(StandardLocation.CLASS_OUTPUT, "", "doesntmatter")
            .toUri())
            .parent
            .parent
            .parent
            .parent
            .parent
            .parent
    val properties = Path.of(projectRoot.toString(), "src", "main", "resources", "application.yml")
    return properties.toFile()
}

其中

processingEnv
AbstractProcessor

的成员

0
投票

答案可能与某些用例无关。如果您想读取自己的配置/属性文件来处理注释。我在我的注释处理器中找到了解决办法 cURL

我将

cURL.config
文件放在 src 文件夹的同一级别。然后我使用
System.getProperty("user.dir")
来获取文件夹路径。现在我可以读取该文件了。

my-java-project/
├── src/
│   ├── main/
│   │   ├── java/
│   │   └── resources/
├── cURL.config
├── pom.xml (for Maven projects)
└── build.gradle (for Gradle projects)

源代码

private static final String CURRENT_WORKING_DIR = System.getProperty("user.dir");
private static final String CONFIG_FILE = "cURL.config";

File configFile = new File(CURRENT_WORKING_DIR + File.separatorChar + CONFIG_FILE);
if (configFile.exists()) {
    try (
            FileInputStream fileInputStream = new FileInputStream(configFile)
    ) {
        Properties properties = new Properties();
        properties.load(fileInputStream);
        String collectionName = properties.getProperty("collection.name");
    } catch (Exception ignored) {
    }
}

如果您想查看原始源代码,请查看github存储库https://github.com/BytesCraftIO/cURL


-2
投票
  • 如果您的元素是

    TypeElement
    的实例,那么您可以使用这些代码来查找您的源代码

    FileObject fileObject = processingEnv.getFiler().getResource(
              StandardLocation.SOURCE_PATH, element.getEnclosingElement().toString(),
              element.getSimpleName() + ".java");

    1. element.getEnclosingElement()
      是你的类包,例如:com.fool
    2. element.getSimpleName()
      是你的班级名称,例如:Person
  • 然后你可以打印它们:

    CharSequence content = fileObject.getCharContent(true);

© www.soinside.com 2019 - 2024. All rights reserved.