Java 库:从资源加载文件

Java Library: load file from resources

我正在开发一个将在我们公司内部使用的 Java 库。它提供了 Aerospike 的包装器。当用户调用工厂方法时,库应该从其资源中读取一个文件。

public static IAerospikeClient newTypedClient(IAerospikeClient client) {
    LOG.info("Trying to load aerospike schema yml");

    URL resource = AerospikeTypedClientFactory.class.getClassLoader().getResource("schema.yml");
    if (resource == null) {
        throw new IllegalArgumentException("File 'schema.yml' is not found");
    }

    byte[] bytes = Files.readAllBytes(Paths.get(resource.toURI()));
    return new TypedAerospikeClient(client, new String(bytes));
}

然后我尝试将此库添加为依赖项并调用 newTypedClient 方法,我收到此错误。

Caused by: java.nio.file.FileSystemNotFoundException
    at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
    at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
    at java.nio.file.Paths.get(Paths.java:143)
    at com.example.AerospikeTypedClientFactory.newTypedClient(AerospikeTypedClientFactory.java:30)

有什么办法可以克服这个错误吗?我想我可以将 schema.yml 文件添加到图书馆消费者的 resources 文件夹中。但我绝对不想谈这个。因为目的是摆脱配置并将它们放在一个工件中。

编辑 1

对于那些参考 How should I use getResource() in Java? 问题的人。我明白 getResource 从类路径中读取。我的问题是我怎样才能得到这项工作?也许,我可以用其他东西代替 getResource/getResourceAsStream 用法。这个想法是 schema.yml 必须打包在库 .jar 存档中。

编辑 2

下面是问题的一步一步

  1. 描述的代码放在 lib 模块中。
  2. lib 打包到 jar 并发布到 Artifactory。
  3. service 依赖于 lib
  4. servicelib 调用 newTypedClient 方法。
  5. FileSystemNotFoundException 加注。

所以,我需要 lib 从它被打包到的 jar 中读取 schema.yml。可能吗?这是描述该过程的图表。

对于那些感兴趣的人,我编写了一个自定义 Gradle 任务,它生成一个带有静态 String 字段的 class。该字段值等于实际文件内容。该任务在 compileJava 之前运行。 对于生成本身,我使用 JavaPoet 库。 这是例子。

task generateSchemaClass {
    def className = "Schema_"
    def directoryPath = "src/main/java/com/example/generated"
    def filePath = directoryPath + className + ".java"
    doFirst {
        TypeSpec typeSpec = TypeSpec.classBuilder("Schema_")
                .addModifiers(Modifier.PUBLIC)
                .addAnnotation(
                        AnnotationSpec.builder(SuppressWarnings.class)
                                .addMember("value", '$S', "all")
                                .build()
                )
                .addField(
                        FieldSpec.builder(String.class, "CONTENT", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
                                .initializer('$S', file('src/main/resources/schema.yml').text)
                                .build()
                )
                .build()
        JavaFile javaFile = JavaFile.builder("com.example.generated", typeSpec).build()
        file(directoryPath).mkdirs()

        def output = file(filePath)
        output.createNewFile()
        output.text = javaFile.toString()
    }
}

compileJava.dependsOn(generateSchemaClass)