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
下面是问题的一步一步
- 描述的代码放在
lib
模块中。
-
lib
打包到 jar
并发布到 Artifactory。
service
依赖于 lib
。
service
从 lib
调用 newTypedClient
方法。
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)
我正在开发一个将在我们公司内部使用的 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
下面是问题的一步一步
- 描述的代码放在
lib
模块中。 -
lib
打包到jar
并发布到 Artifactory。 service
依赖于lib
。service
从lib
调用newTypedClient
方法。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)