java - gradle构建后无法从jar中的资源加载文件

标签 java jar gradle

我的 gradle 构建脚本:

apply plugin: 'java'

jar {
    manifest {
        attributes 'Main-Class': 'com.package.Starter'
    }
}

repositories {
   mavenCentral()
}


dependencies {
   compile 'javax.persistence:persistence-api:1.0.2'
}

我的文件夹结构:

└── main
├── java
│   └── com
│       └── packege
│           ├── pojo
│           │   ├── City.java
│           │   └── GeocodeResponse.java
│           │   
│           └── Starter.java
│       
└── resources
    └── cities.csv

Starter.java 中的 java 函数

private void set_cities(){
    BufferedReader br = null;
    String line = "";
    String cvsSplitBy = ";";
    URL url = Starter.class.getResource("cities.csv");

    // print class folder for debug
    ClassLoader cl = ClassLoader.getSystemClassLoader();

    URL[] urls = ((URLClassLoader)cl).getURLs();

    for(URL url1: urls){
        System.out.println(url1.getFile());
    }

    try {

        br = new BufferedReader(new FileReader(url.getFile())); // <-- null :(((
        while ((line = br.readLine()) != null) {
            String[] data = line.split(cvsSplitBy);
            cities.add(new City(data[1], data[0]));
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在 gradle 构建之后,我想使用 java -jar h.jar 命令从/build/libs/h.jar 中的 jar 文件开始,但输出是:

/path/to/project/h/build/libs/h.jar // <-- output of URL[] urls = ((URLClassLoader)cl).getURLs();
Exception in thread "main" java.lang.NullPointerException
at com.package.Starter.set_cities(Starter.java:90)
at com.package.Starter.<init>(Starter.java:34)
at com.package.Starter.main(Starter.java:133)

提取的jar结构:

├── cities.csv
├── com
│   └── package
│       ├── pojo
│       │   ├── City.class
│       │   ├── GeocodeResponse.class
│       │   ├── GeocodeResponse$Result$AddressComponent.class
│       │   ├── GeocodeResponse$Result.class
│       │   ├── GeocodeResponse$Result$Geometry$Bounds.class
│       │   ├── GeocodeResponse$Result$Geometry$Bounds$Northeast.class
│       │   ├── GeocodeResponse$Result$Geometry$Bounds$Southwest.class
│       │   ├── GeocodeResponse$Result$Geometry.class
│       │   ├── GeocodeResponse$Result$Geometry$Location.class
│       │   ├── GeocodeResponse$Result$Geometry$Viewport.class
│       │   ├── GeocodeResponse$Result$Geometry$Viewport$Northeast.class
│       │   └── GeocodeResponse$Result$Geometry$Viewport$Southwest.class
│       └── Starter.class
└── META-INF
    └── MANIFEST.MF

在 gradle build 命令和 gradle 创建构建文件夹之后:

├── classes
│   └── main
│       └── com
│           └── package
│               ├── pojo
│               │   ├── City.class
│               │   ├── GeocodeResponse.class
│               │   ├── GeocodeResponse$Result$AddressComponent.class
│               │   ├── GeocodeResponse$Result.class
│               │   ├── GeocodeResponse$Result$Geometry$Bounds.class
│               │   ├── GeocodeResponse$Result$Geometry$Bounds$Northeast.class
│               │   ├── GeocodeResponse$Result$Geometry$Bounds$Southwest.class
│               │   ├── GeocodeResponse$Result$Geometry.class
│               │   ├── GeocodeResponse$Result$Geometry$Location.class
│               │   ├── GeocodeResponse$Result$Geometry$Viewport.class
│               │   ├── GeocodeResponse$Result$Geometry$Viewport$Northeast.class
│               │   └── GeocodeResponse$Result$Geometry$Viewport$Southwest.class
│               └── Starter.class
├── com
│   └── package
│       ├── pojo
│       │   ├── City.class
│       │   ├── City.java~
│       │   ├── GeocodeResponse.class
│       │   ├── GeocodeResponse$Result$AddressComponent.class
│       │   ├── GeocodeResponse$Result.class
│       │   ├── GeocodeResponse$Result$Geometry$Bounds.class
│       │   ├── GeocodeResponse$Result$Geometry$Bounds$Northeast.class
│       │   ├── GeocodeResponse$Result$Geometry$Bounds$Southwest.class
│       │   ├── GeocodeResponse$Result$Geometry.class
│       │   ├── GeocodeResponse$Result$Geometry$Location.class
│       │   ├── GeocodeResponse$Result$Geometry$Viewport.class
│       │   ├── GeocodeResponse$Result$Geometry$Viewport$Northeast.class
│       │   └── GeocodeResponse$Result$Geometry$Viewport$Southwest.class
│       ├── Starter.class
│       └── Starter.java~
├── dependency-cache
├── libs
│   ├── h <-- extracted jar
│   │   ├── cities.csv
│   │   ├── com
│   │   │   └── package
│   │   │       ├── pojo
│   │   │       │   ├── City.class
│   │   │       │   ├── GeocodeResponse.class
│   │   │       │   ├── GeocodeResponse$Result$AddressComponent.class
│   │   │       │   ├── GeocodeResponse$Result.class
│   │   │       │   ├── GeocodeResponse$Result$Geometry$Bounds.class
│   │   │       │   ├── GeocodeResponse$Result$Geometry$Bounds$Northeast.class
│   │   │       │   ├── GeocodeResponse$Result$Geometry$Bounds$Southwest.class
│   │   │       │   ├── GeocodeResponse$Result$Geometry.class
│   │   │       │   ├── GeocodeResponse$Result$Geometry$Location.class
│   │   │       │   ├── GeocodeResponse$Result$Geometry$Viewport.class
│   │   │       │   ├── GeocodeResponse$Result$Geometry$Viewport$Northeast.class
│   │   │       │   └── GeocodeResponse$Result$Geometry$Viewport$Southwest.class
│   │   │       └── Starter.class
│   │   └── META-INF
│   │       └── MANIFEST.MF
│   └── h.jar
├── resources
│   └── main
│       └── cities.csv
│       
└── tmp
    ├── compileJava
    └── jar
        └── MANIFEST.MF

最佳答案

您可以使用资源文件的绝对路径和 getResourceAsStream 方法来访问您的 jar,在本例中:

Starter.class.getResourceAsStream("/cities.csv");

关于java - gradle构建后无法从jar中的资源加载文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31605289/

相关文章:

gradle - 从子项目调用任务时如何从根gradle任务引用子项目dir

java - 处理 JButton 集合的事件

java - 从 JSP 页面运行 java 应用程序

Java - For 循环中的 2-Do-While 循环

java - 为什么使用 IPv6 地址的 HttpServletRequest.getRemoteAddr() 返回额外字符

java - Android Java - 如何防止多个 dex 定义?

java - 在外部 Java 库之后清理

java - 如何在 JAR\Java 项目中存储值

gradle - 如何使用 Gradle Kotlin-DSL 添加本地资源

android - 未生成 Sqldelight 数据库架构