2

我正在使用 gradle build 构建 uber jar,我使用的插件是 https://github.com/johnrengelman/shadow

我的文件src/main/resources夹中有一个 json 文件,我在下面的代码中使用它

   public Repository<Product> initializeData() {
        ClassLoader classLoader = getClass().getClassLoader();
        File file = new File(classLoader.getResource("product.json").getFile());
        System.out.println(file.getAbsolutePath());
        Repository<Product> productRepository = new ProductRepository();
        return productRepository;
    }

当我运行 uber Jar 时,面临以下问题

$$ java -cp libs/checkout-service-1.0-SNAPSHOT.jar com.noths.runner.Runner
java.nio.file.NoSuchFileException: /home/gradle/checkout-service/file:/home/gradle/checkout-service/libs/checkout-service-1.0-SNAPSHOT.jar!/product.json
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
        at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:371)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:422)
        at java.base/java.nio.file.Files.readAllBytes(Files.java:3206)
        at java.base/java.nio.file.Files.readString(Files.java:3284)
        at java.base/java.nio.file.Files.readString(Files.java:3243)
        at com.noths.runner.Utils.initializeData(Utils.java:21)
        at com.noths.runner.Runner.main(Runner.java:21)
Exception in thread "main" java.lang.NullPointerException
        at com.noths.promotions.ProductPromotion.apply(ProductPromotion.java:26)
        at com.noths.promotions.DefaultPromotionsRunner.setPromotionsChain(DefaultPromotionsRunner.java:21)
        at com.noths.checkout.CheckoutServiceImpl.checkout(CheckoutServiceImpl.java:27)
        at com.noths.runner.Runner.main(Runner.java:25)

我的 build.gradle 看起来像这样

// Shadow Plugin https://github.com/johnrengelman/shadow
plugins {
    id "com.github.johnrengelman.shadow" version "6.0.0"
    id 'java'
}

group 'com'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'

    compileOnly 'org.projectlombok:lombok:1.18.20'
    annotationProcessor 'org.projectlombok:lombok:1.18.20'

    testCompileOnly 'org.projectlombok:lombok:1.18.20'
    testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'

    implementation 'com.google.code.gson:gson:2.8.8'

}

test {
    useJUnitPlatform()
}
4

1 回答 1

1

除非文件系统中有类,否则不能通过 File 访问类路径。一旦文件在 jar 中,通过 File 的访问就必须失败。

所以你应该做的是一个classloader.getResource(...) 或一个getClass().getResource(...)。如果它们返回 null,则您传递的字符串与类路径中的某些内容不匹配,您需要确定字符串或 jar 文件是否需要修复。如果您获得一些资源,则直接打开流并读取数据。

另请参阅 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#getResource(java.lang.String) https://docs。 oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openStream()

我对使用 getClass().getResourceAsStream(...) 犹豫不决,因为您保存了一个函数调用,但在资源不存在的情况下无法给出良好的错误消息。

于 2021-08-27T21:18:23.007 回答