1

I've created a project which utilizes image files as well as a text file when executed. Both the text and image files are in my project folder before I exported the project into a runnable jar, but when I ran the jar from the command line, I got a filenotfound exception caused by the program typing to read from the text file. I unzipped the jar to double check and the image and text files weren't there.

package application;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

import javafx.collections.FXCollections;

public class Data {
    private static Data instance=new Data();
    private Map<String,String> saveEntries = new HashMap<>();
    private static String fileName = "ResponseData";

public static Data getInstance() {
    return instance;
}

public void exitSave() throws IOException {
    Path path = Paths.get("ResponseData");
    Iterator<Map.Entry<String, String>> iter = saveEntries.entrySet().iterator();
    BufferedWriter bw = Files.newBufferedWriter(path);
    try {
        while(iter.hasNext()) {
            Map.Entry<String, String> entry = iter.next();
            bw.write(String.format("%s\t%s", entry.getKey(),entry.getValue()));
            bw.newLine();
        }
    } catch (IOException e) {
        new FileNotFoundException("Error when saving data");
    }finally {
        if(bw!=null)
            bw.close();
    }
}



public void updatedSaveEntry(String input, String response) {
    saveEntries.put(input, response);
}

public Map<String,String> getSaveEntries(){
    return this.saveEntries;
}

public void setEntry(Map<String,String> map) {
    Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
    while(iter.hasNext()) {
        Map.Entry<String, String> entry = iter.next();
        saveEntries.put(entry.getKey(), entry.getValue());
    }
}


public void loadEntries() throws IOException{
    saveEntries = FXCollections.observableHashMap();
    Path path = Paths.get(fileName);
    BufferedReader br = Files.newBufferedReader(path);
    String line;
    try {
        while((line=br.readLine())!=null&&!line.trim().isEmpty()) {
            String[] parts = line.split("\t");
            saveEntries.put(parts[0], parts[1]);
        }
    }finally {
        if(br!=null) {
            br.close();
        }
    }

}

}

Eclipse Runnable Jar Export

Project Folder

X and Y
  • 91
  • 1
  • 7
  • So how shall we know why you did not pack the missing files into the jar? You are not giving any details and you do not even ask a real question. You are just describing a fact. – mipa Jul 06 '19 at 07:32
  • Let me revise my statement. Basically, I've created a similar project before which included a text file and exported the project into a jar. The program had no problem saving and retrieving texts from the text file and so I assume the file is also included in the jar file(excuse me if I'm wrong, I'm not quite experienced with IOs). This new project I made also utilized javafx, but the main difference would be that I updated my JDK and JavaFX to the latest versions. I also added a VM argument to the run configuration because of a JavaFX issue(https://openjfx.io/openjfx-docs/#install-javafx) – X and Y Jul 06 '19 at 08:10
  • The VM argument: --module-path "\path\to\javafx-sdk-12.0.1\lib" --add-modules javafx.controls,javafx.fxml , Besides those changes the file IO code of my two projects are pretty much identical, but my current project gives me the filenotfound error when I try running the jar. – X and Y Jul 06 '19 at 08:10
  • You are still missing the point. 1. Whether the text file should be in the jar file or not depends on the way you are accessing the file in your code but you do not provide any information on that. 2. You are constantly talking about export something to a jar file but you do not provide any information how you are doing that. Manually? Via Eclipse? Via some Maven/Gradle plugin or what? If you want to export a text file into a jar, then the export must be configured correctly. E.g., if you are using Maven/Gradle, then the file has to be in the right resource folder. – mipa Jul 06 '19 at 08:23
  • Oh ok. I added the code for my file access class. The error is shown to be at 'Path path = Paths.get("ResponseData");' where the "ResponseData" is the file I have in my project. I exported my project via Eclipse(the screenshot link on the botton). – X and Y Jul 06 '19 at 08:33

2 Answers2

0

Your program is trying to read the file from your local file system and not from the jar file. So it should indeed not be included in the jar file. The program is expecting the file in the current working directory where you execute your program and that can be different if you run your project within Eclipse or if you execute the exported jar file.

mipa
  • 10,369
  • 2
  • 16
  • 35
0

If you are both reading and writing to a file, then locating this file in the application jar is not appropriate as mentioned in the other answer: you should persist your data at an external location.

However, it is usual to keep the read-only resources files (such as images) in the jar. If you want to keep this approach for the images and possibly other resources, you are facing two problems:

  1. Getting Eclipse to include the file in the jar using the Export Runnable Jar feature.

  2. Finding the file in the jar

Including the file

The simplest is probably just to place the file in a source folder. In your project, do New -> Source Folder, give it a name (e.g., "resources"), and move your file there. Normally, if you re-run the export, the file should be in the jar.

Finding the file

Files in jar are accessed differently. See the accepted answer to Reading a resource file from within jar. Note that you don't need to include the name of your resource folder in the path, as this file will be placed at the root of your jar (you can verify this by unpacking it).

SDJ
  • 4,083
  • 1
  • 17
  • 35
  • Your answer is putting the OP on the wrong track because he is not only reading from the file but, according to his code sample, also writing to the file and this won't work if the file is located inside the jar file. So, the OP should actually keep the file out of the jar and just place it into the correct folder. – mipa Jul 06 '19 at 10:07
  • Thank both of you for your help. I fixed the image problem by making a res source folder and accessing the images from there instead. I fixed the data reading problem via the '.createNewFile()' method. – X and Y Jul 06 '19 at 21:11