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

时间:2016-09-29 13:50:01

标签: java annotation-processing

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

- 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中生成,因此无法找到它。

5 个答案:

答案 0 :(得分:5)

我希望src/main/resources中的内容在构建期间(注释处理之前)被复制到target/classes。在这种情况下,您可以这样打开它们:

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

答案 1 :(得分:2)

我和一个Project Lombok开发人员一起看了这个。如果有人知道注释处理,那就是它们;)

我们的结论是,内部处理请求的JavacFileManager没有解析StandardLocation.SOURCE_PATH的路径。我们不确定,但它可能与使用Gradle构建有关。

答案 2 :(得分:0)

我遇到了同样的问题,并且正在寻找解决方案一段时间,发现this cool hack可以解决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")
}

答案 3 :(得分:0)

以下功能对我有用,注解处理器由gradle触发,不是漂亮的而是起作用的:

var id = $("#id").html(); 

其中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的成员

答案 4 :(得分:-1)

  • 如果您的元素是TypeElement的实例,那么您可以使用这些代码来查找源代码

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

    1. element.getEnclosingElement()是您的类包,例如:com.fool
    2. element.getSimpleName()是您的班级名称,例如:人员
  • 然后你可以打印它们: CharSequence content = fileObject.getCharContent(true);