在 kotlin func 中使用资源 - 不适用于 fat jar(一个 jar)
Using resource in kotlin func - does not work with fat jar (one jar)
我有如下一段代码:
fun main(args: Array<String>) {
val urlForCSR: URL = ClassLoader.getSystemClassLoader().getResource("merchant.id")
// also tried ClassLoader.getSystemResource("merchant.id")
...
以下当来自 intelliJ 的 运行 工作正常并找到资源时。但是当 运行 使用捆绑的 jar 时,它会给出 NullPointerException
.
- 资源路径:
/src/main/resources/merchant.id
- 代码路径:
/src/main/java/Route.kt
以下是 Maven 配置片段:
...
<!-- Make this jar executable -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>RouteKt</mainClass> <!-- Class generated (for above main func - named Route.kt) -->
</manifest>
</archive>
</configuration>
</plugin>
<!-- Includes the runtime dependencies -->
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
对于上述资源,是否有任何其他 war 可以获得 URL,可以使用一个罐子或其他制作胖罐子的方法。
罐子内容:
jar tf target/Route-1.0-SNAPSHOT.jar
META-INF/
META-INF/MANIFEST.MF
merchant.id
RouteKt$main.class
RouteKt.class
META-INF/maven/
META-INF/maven/groupId/
META-INF/maven/groupId/TokenGenerator/
META-INF/maven/groupId/TokenGenerator/pom.xml
META-INF/maven/groupId/TokenGenerator/pom.properties
一罐内容物:
META-INF/MANIFEST.MF
main/Route-1.0-SNAPSHOT.jar
lib/kotlin-stdlib-0.1-SNAPSHOT.jar
lib/kotlin-runtime-0.1-SNAPSHOT.jar
lib/spark-core-2.3.jar
lib/slf4j-api-1.7.12.jar
lib/slf4j-simple-1.7.12.jar
lib/jetty-server-9.3.2.v20150730.jar
...
OneJar 将您的所有代码打包到一个 JAR 文件中,该文件还包含 lib/
目录中的其他 JAR 文件,或者在 JAR 之外的其他目录中作为对它们的引用(取决于您使用的 onejar 系统).它使用自定义 class 加载程序来完成这项工作。因此,它会破坏您对系统 class 加载器的使用。
解决此的一种方法是使用与您要加载的资源相同的 JAR 中的 class,因此它的 class 加载器可能已正确设置到您的资源的 JAR 或嵌套 JAR 或纳尼亚魔法位置:
val stream = MyClass::class.java.getResourceAsStream("/merchant.id")
其中 MyClass
是来自与 merchant.id
相同 JAR 的 class,资源路径必须是绝对路径,前导 /
一定要获取 流 而不是资源 URL ,这可能对您来说无法使用,因为它不是可以理解的 URL系统。它可以为一个 JAR 中的一个 JAR 生成一个 URL,而 Java 的其余部分无法理解,例如 file:/path/to/jarfile/bot.jar!/config/file.txt
(或更糟!)。它可以工作,但我不确定它何时是一个包含文件的 JAR 中的 JAR。
次要选项:
val stream = Thread.currentThread().contextClassLoader.getResourceAsStream("/merchant.id")
检查您的资源名称:
在您的问题中,您说要读取资源 merchant.id
,但随后会显示具有 merchant.id.soft.applepaydev-v1.csr
的 JAR 内容...如果您尝试加载此确切资源,请确保这些名称匹配。
onejar 中的资源加载必须自定义,这很难看。 In a link to one resource that talks about resource loading with onejar:
There are a number of ways that Java supports finding and opening resources:
- URL findResource(String resource): returns a resource, or null if not found.
- Enumeration findResources(String resource): returns an enumeration of resource URL's which match the given string
- URL.openConnection(): opens a connection to a resource by its URL.
One-Jar supports all of these mechanisms within the context of a One-Jar file, which may contain Jar files that have duplicate resources.
这个问题是从其他 Stack Overflow 帖子中引用的,因此这几乎是一个重复的问题:
- Classpath resources inside one-jar packaged via sbt
- How to get a path to a resource in a Java JAR file
- How to get an URL for a resource directory when using OneJar?
- Onejar and resource loading
谷歌搜索找到更多资源。
我有如下一段代码:
fun main(args: Array<String>) {
val urlForCSR: URL = ClassLoader.getSystemClassLoader().getResource("merchant.id")
// also tried ClassLoader.getSystemResource("merchant.id")
...
以下当来自 intelliJ 的 运行 工作正常并找到资源时。但是当 运行 使用捆绑的 jar 时,它会给出 NullPointerException
.
- 资源路径:
/src/main/resources/merchant.id
- 代码路径:
/src/main/java/Route.kt
以下是 Maven 配置片段:
...
<!-- Make this jar executable -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>RouteKt</mainClass> <!-- Class generated (for above main func - named Route.kt) -->
</manifest>
</archive>
</configuration>
</plugin>
<!-- Includes the runtime dependencies -->
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
对于上述资源,是否有任何其他 war 可以获得 URL,可以使用一个罐子或其他制作胖罐子的方法。
罐子内容:
jar tf target/Route-1.0-SNAPSHOT.jar
META-INF/
META-INF/MANIFEST.MF
merchant.id
RouteKt$main.class
RouteKt.class
META-INF/maven/
META-INF/maven/groupId/
META-INF/maven/groupId/TokenGenerator/
META-INF/maven/groupId/TokenGenerator/pom.xml
META-INF/maven/groupId/TokenGenerator/pom.properties
一罐内容物:
META-INF/MANIFEST.MF
main/Route-1.0-SNAPSHOT.jar
lib/kotlin-stdlib-0.1-SNAPSHOT.jar
lib/kotlin-runtime-0.1-SNAPSHOT.jar
lib/spark-core-2.3.jar
lib/slf4j-api-1.7.12.jar
lib/slf4j-simple-1.7.12.jar
lib/jetty-server-9.3.2.v20150730.jar
...
OneJar 将您的所有代码打包到一个 JAR 文件中,该文件还包含 lib/
目录中的其他 JAR 文件,或者在 JAR 之外的其他目录中作为对它们的引用(取决于您使用的 onejar 系统).它使用自定义 class 加载程序来完成这项工作。因此,它会破坏您对系统 class 加载器的使用。
解决此的一种方法是使用与您要加载的资源相同的 JAR 中的 class,因此它的 class 加载器可能已正确设置到您的资源的 JAR 或嵌套 JAR 或纳尼亚魔法位置:
val stream = MyClass::class.java.getResourceAsStream("/merchant.id")
其中 MyClass
是来自与 merchant.id
相同 JAR 的 class,资源路径必须是绝对路径,前导 /
一定要获取 流 而不是资源 URL ,这可能对您来说无法使用,因为它不是可以理解的 URL系统。它可以为一个 JAR 中的一个 JAR 生成一个 URL,而 Java 的其余部分无法理解,例如 file:/path/to/jarfile/bot.jar!/config/file.txt
(或更糟!)。它可以工作,但我不确定它何时是一个包含文件的 JAR 中的 JAR。
次要选项:
val stream = Thread.currentThread().contextClassLoader.getResourceAsStream("/merchant.id")
检查您的资源名称:
在您的问题中,您说要读取资源 merchant.id
,但随后会显示具有 merchant.id.soft.applepaydev-v1.csr
的 JAR 内容...如果您尝试加载此确切资源,请确保这些名称匹配。
onejar 中的资源加载必须自定义,这很难看。 In a link to one resource that talks about resource loading with onejar:
There are a number of ways that Java supports finding and opening resources:
- URL findResource(String resource): returns a resource, or null if not found.
- Enumeration findResources(String resource): returns an enumeration of resource URL's which match the given string
- URL.openConnection(): opens a connection to a resource by its URL.
One-Jar supports all of these mechanisms within the context of a One-Jar file, which may contain Jar files that have duplicate resources.
这个问题是从其他 Stack Overflow 帖子中引用的,因此这几乎是一个重复的问题:
- Classpath resources inside one-jar packaged via sbt
- How to get a path to a resource in a Java JAR file
- How to get an URL for a resource directory when using OneJar?
- Onejar and resource loading
谷歌搜索找到更多资源。