运行Jar时找不到文件

时间:2019-03-20 13:39:24

标签: java json javafx filenotfoundexception

我正在做一个很小的Java项目,在其中我从JSON文件加载应用程序设置,在IDE(IntelliJ)中,它一切正常,可以找到文件并正常工作,但是当我构建jar时并从命令行执行它,则抛出FileNotFoundException。 可能是什么原因造成的?

这是我的一些代码:

1-通过此类,我获得了JSON文件的路径:

this.$data[table].fill(data)

这是读取JSON文件的新方法:

package sample.Utils;

public class JsonFilePLace {
private final String JSONPATH;

public JsonFilePLace(){
    JSONPATH =  getClass().getResource("/sample/data/loadData.json").getPath();
    String path = getClass().getResource("/sample/data/loadData.json").getPath();
    System.out.println(path);
}

public String getJSONPATH() {
    return JSONPATH;
}
}

这是主要方法:

公共类Main扩展Application {

public class JsonParsers {
static String fileContent;


public JsonParsers() throws URISyntaxException, IOException {
    final URL resource = this.getClass().getResource("/loadData.json");
    final Path path = Paths.get(resource.toURI());
    final byte[] bytes = Files.readAllBytes(path);
    fileContent = new String(bytes);

}

public static SettingsObject getSettings(/*String filePath*/) {


    JSONParser jparser = new JSONParser();


    SettingsObject returnedObject = null;


    try {
        Object object = jparser.parse(/*new FileReader(filePath)*/fileContent);
        JSONObject jObject = (JSONObject) object;

        String name = (String) jObject.get("user");
        String matricule = (String) jObject.get("matricule");

        JSONArray jArray = (JSONArray) jObject.get("tarifaction");
        FormulaClass A = null, B = null, C = null;
        int counter = 0;

        for (Object obj : jArray) {
            JSONObject jObj = (JSONObject) obj;
            if (counter == 0)
                A = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));
            if (counter == 1)
                B = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));
            if (counter == 2)
                C = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));

            counter++;
        }

        JSONObject staticsObject = (JSONObject) jObject.get("statics");

        String reservation_1 = String.valueOf(staticsObject.get("reservation_1"));
        String reservation_2 = String.valueOf(staticsObject.get("reservation_2"));
        String prise_charge = (String.valueOf(staticsObject.get("prise_charge")));
        String tva = String.valueOf(staticsObject.get("tva"));

        String savePath = (String) jObject.get("save_path");

        returnedObject = new SettingsObject(name, matricule, A, B, C, reservation_1, reservation_2, prise_charge, tva, savePath);

    } catch (ParseException e) {
        e.printStackTrace();
    }


    return returnedObject;
}

这是cmd错误,因为它在编辑器中运行正常:

// TODO: 19/03/2019 maybe instanciate the settings variable here

public static final String JSONPATH = "loadData.json";

public static SettingsObject GLOBAL_SETTINGS;


@Override
public void start(Stage primaryStage) throws IOException {
    Parent root = FXMLLoader.load(getClass().getResource("uis/sample.fxml"));
    primaryStage.setTitle("Taxi Manager");
    primaryStage.setScene(new Scene(root, 820, 766));
    primaryStage.centerOnScreen();
    primaryStage.show();
}


public static void main(String[] args) throws IOException, URISyntaxException {
    JsonParsers jparsers = new JsonParsers();
    GLOBAL_SETTINGS = jparsers.getSettings();
    launch(args);
}

}

这是writer方法:

C:\Users\Simou\Desktop\Work\WorK\TaxiProgram\out\artifacts\TaxiProgramFr>java -j
ar TaxiProgramFr.jar
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at 
com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Lau
ncherImpl.java:389)
        at 
com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImp
l.java:328)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.nio.file.FileSystemNotFoundException
        at 
com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemPr
ovider.java:171)
        at 
com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider
.java:157)
        at java.nio.file.Paths.get(Unknown Source)
        at sample.Utils.JsonParsers.<init>(JsonParsers.java:24)
        at sample.Main.main(Main.java:36)
        ... 11 more
    Exception running application sample.Main

1 个答案:

答案 0 :(得分:0)

您正在将文本文件存储在源包中。因此,除非您明确配置为不这样做,否则文件很可能在编译过程中被剥离。

如果您仍然想将它们存储在此处,您需要做的是

final URL resource = YourClass.class.getResource("/sample/data/loadData.json");
final Path path = Paths.get(resource.toURI());
final byte[] bytes = Files.readAllBytes(path);
final String fileContent = new String(bytes);

YourClass.class.getResource("/sample/data/loadData.json");

/sample/data/loadData.json是绝对的软件包路径。


我建议将这些文件存储在resource文件夹下。

YourClass.class.getResource("loadData.json");

您需要做的是删除 JsonFilePLace,根本不需要!
代替

final URL resource = YourClass.class.getResource("loadData.json");
final Path path = Paths.get(resource.toURI());
final byte[] bytes = Files.readAllBytes(path);
final String fileContent = new String(bytes);

final Object object = jparser.parse(fileContent);
final JSONObject jObject = (JSONObject) object;

由于这似乎行不通,请直接访问File资源

try (final InputStream is = YourClass.class.getResourceAsStream("loadData.json")) {
    final String fileContent = readString(is);
    final Object object = jparser.parse(fileContent);
    final JSONObject jObject = (JSONObject) object;
    ...
}

private static String readString(final InputStream inputStream) throws IOException {
    final ByteArrayOutputStream result = new ByteArrayOutputStream();
    final byte[] buffer = new byte[1024];
    int length;

    while ((length = inputStream.read(buffer)) != -1) {
        result.write(buffer, 0, length);
    }

    return result.toString(StandardCharsets.UTF_8);
}