Файл не найден при запуске Jar - PullRequest
0 голосов
/ 20 марта 2019

Я работаю над очень маленьким Java-проектом, в котором я загружаю настройки приложения из файла JSON, в IDE (IntelliJ) все работает нормально, находит файл и работает правильно, но когда я собираю jar и выполнить его из командной строки, он вызывает исключение FileNotFoundException. что может быть причиной этого?

Вот мой код:

1 - с помощью этого класса я получаю путь к файлу 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;
}
}

Это новый метод, который читает файл JSON:

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;
}

Это основной метод:

публичный класс Main extends Application {

// 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);
}

}

это ошибка cmd, зная, что она прекрасно работает из редактора:

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

это метод писателя:

public static void settingsWriter(SettingsObject settings, String filePath) {
    JSONObject gObj = new JSONObject();
    JSONArray jsonArray = new JSONArray();
    JSONObject staticsOBJ = new JSONObject();

    gObj.put("user", settings.getUserName());
    gObj.put("matricule", settings.getMatricule());

    JSONObject tempObj = new JSONObject();
    tempObj.put("distance", settings.getA().getDistance());
    tempObj.put("heure", settings.getA().getHeure() * 60);
    jsonArray.add(tempObj);

    tempObj = new JSONObject();
    tempObj.put("distance", settings.getB().getDistance());
    tempObj.put("heure", settings.getB().getHeure() * 60);
    jsonArray.add(tempObj);

    tempObj = new JSONObject();
    tempObj.put("distance", settings.getC().getDistance());
    tempObj.put("heure", settings.getC().getHeure() * 60);
    jsonArray.add(tempObj);

    gObj.put("tarifaction", jsonArray);

    staticsOBJ.put("reservation_1", Integer.parseInt(settings.getReservation_1()));
    staticsOBJ.put("reservation_2", Integer.parseInt(settings.getReservation_2()));
    staticsOBJ.put("prise_charge", Double.parseDouble(settings.getPrise_Charge()));
    staticsOBJ.put("tva", Integer.parseInt(settings.getTva()));

    gObj.put("statics", staticsOBJ);

    gObj.put("save_path", settings.getPathSave());

    File jsonFile = new File(filePath);

    try {
            FileWriter fileWriter = new FileWriter(jsonFile);
            fileWriter.write(gObj.toJSONString());
            fileWriter.flush();
            fileWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

1 Ответ

0 голосов
/ 20 марта 2019

Вы храните ваш текстовый файл в пакете с исходным кодом. Таким образом, файл, скорее всего, будет удален во время компиляции, если вы явно не настроили это.

Если вы все еще хотите хранить их там, вам нужно сделать

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);
}
...