John Carraher
John Carraher

Reputation: 63

java program (with txt/csv) works fine in IDE but not in jar


I'm currently trying to create an executable jar of a todolist-app I developed in Intellij. I use a CSV file to store the users and tasks, and a txt file to store the current user. Although I've been able to run the program on my IDE, when I try to run it through command prompt on windows I get this error:

Error:

C:\WINDOWS\system32>java --module-path C:\JavaFX\javafx-sdk-14.0.2.1\lib --add-modules javafx.controls,javafx.fxml -jar C:\Users\jkcar\IdeaProjects\toDoList\out\artifacts\toDoList_jar\toDoList.jar
java.io.FileNotFoundException: toDoList.jar\sample\database\users.csv (The system cannot find the path specified)
        at java.base/java.io.FileInputStream.open0(Native Method)
        at java.base/java.io.FileInputStream.open(FileInputStream.java:212)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:154)
        at java.base/java.util.Scanner.<init>(Scanner.java:639)
        at sample.database.userDatabaseHandler.<init>(userDatabaseHandler.java:23)
        at sample.controller.loginController.initialize(loginController.java:46)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
        at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
        at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2591)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
        at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
        at sample.Main.start(Main.java:13)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
        at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
        at java.base/java.lang.Thread.run(Thread.java:832)
UserDatabase with 0 rows initialized

java.nio.file.NoSuchFileException: toDoList.jar\sample\database\loggedInUser.txt
        at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
        at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:235)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:375)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:426)
        at java.base/java.nio.file.Files.readAllBytes(Files.java:3272)
        at java.base/java.nio.file.Files.readString(Files.java:3350)
        at java.base/java.nio.file.Files.readString(Files.java:3309)
        at sample.database.currentUser.<init>(currentUser.java:19)
        at sample.database.userDatabaseHandler.<init>(userDatabaseHandler.java:48)
        at sample.controller.loginController.initialize(loginController.java:46)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
        at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
        at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2591)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
        at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
        at sample.Main.start(Main.java:13)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
        at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
        at java.base/java.lang.Thread.run(Thread.java:832)
Searching for user with UID: null
Exception in Application start method
java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
        at java.base/java.lang.Thread.run(Thread.java:832)

I noticed that the errors have to do with the program not being able to find the csv/txt files I request in the constructors of my userDatabaseHandler.java taskDatabaseHandler.java and currentUserHandler.java classes listed below.
userDatabaseHandler.java

package sample.database;
import javax.swing.*;
import java.io.*;
import java.util.*;


public class userDatabaseHandler {
    //INSTANCE VARIABLES
    private ArrayList<user> allUsers = new ArrayList<>();
    private ArrayList<String[]> rawDataRows= new ArrayList<>();
    private String fileName;
    private user loggedInUser;

    //CONSTRUCTOR
    public userDatabaseHandler(){
        fileName = "src/sample/database/users.csv";
        File file = new File(fileName);

        try{
            Scanner inputStream = new Scanner(file);
            inputStream.nextLine(); //ignores first line

            //DATAROWS SIZE IS 0 HERE

            while (inputStream.hasNext()){
                String data = inputStream.nextLine(); //gets whole line
                String[] values = data.split(","); //splits by commas
                rawDataRows.add(values); //adds the line to an arraylist (dataRows)
            }
            inputStream.close();
        } catch (FileNotFoundException e){
            JOptionPane.showMessageDialog(null, "userDatabaseHandler Constructor error");
            e.printStackTrace();
        }

        System.out.println("UserDatabase with "+rawDataRows.size()+" rows initialized");
        System.out.println();
        //Creation of each User
        for(int i=0; i<rawDataRows.size();i++){
            user tempUser = new user (rawDataRows.get(i)[0], rawDataRows.get(i)[1], rawDataRows.get(i)[2], rawDataRows.get(i)[3], rawDataRows.get(i)[4], rawDataRows.get(i)[5], rawDataRows.get(i)[6]);
            //add each tweet to the allTweets array
            allUsers.add(tempUser);
        }
        //Set Logged in User
        currentUserHandler cUserHandler = new currentUserHandler();
        loggedInUser = getUserByUID(cUserHandler.getCurrentUserID());
    }

    //GETTERS
    public String getCurrentUsersID(){
        return this.loggedInUser.getUserIDAsString();
    }

    //METHODS
    //Sign Up user
    public void addUser(String userID, String firstName, String lastName, String username, String password, String location, String gender){
        //ADD USER TO userDatabase CLASS
        /*
        user newUser = new user(userID, firstName, lastName, username, password, location, gender);
        allUsers.add(newUser);
         */

        //ADD USER TO user.csv FILE
        try{
            FileWriter fw  = new FileWriter(fileName, true);
            BufferedWriter bw = new BufferedWriter(fw);
            PrintWriter pw = new PrintWriter(bw);

            //Check if any sign-up fields are blank
            if(firstName.equals("") || lastName.equals("") || username.equals("") || password.equals("") || location.equals("")) {
                //If blank show error and return (don't sign up user)
                JOptionPane.showMessageDialog(null, "Error: Fill all fields");
                pw.flush();
                pw.close();
                return;
            }else{
                //If all fields filled
                pw.println(userID + "," + firstName + "," + lastName + "," + username + "," + password + "," + location + "," + gender);
                pw.flush();
                pw.close();
            }
        }catch (Exception E){
            JOptionPane.showMessageDialog(null, "User NOT SAVED");
        }
    }

    public int getNumUsers(){
        return (allUsers.size());
    }

    public boolean isUserReal(String inUsername, String inPassword){
        if(!inUsername.equals("") || !inPassword.equals("")){
            for(int i = 0; i<allUsers.size(); i++) {
                if (allUsers.get(i).getUsername().equals(inUsername)) {
                    if(allUsers.get(i).getPassword().equals(inPassword)){
                        return true;
                    }
                }
            }
        }else{
            return false;
        }
        return false;
    }

    public user getUserByUID(String aUserID){
        System.out.println("Searching for user with UID: "+aUserID);
        for(int i = 0; i<allUsers.size(); i++){
            if(aUserID.equals(allUsers.get(i).getUserIDAsString())){
                return allUsers.get(i);
            }
        }
        JOptionPane.showMessageDialog(null, "userDatabaseHandler.getUserByUID() ERROR! No User found");
        return allUsers.get(0);
    }

    public user getUserByUserName(String Username){
        for(int i = 0; i<rawDataRows.size(); i++){
            if(Username.equals(rawDataRows.get(i)[3])){
                return allUsers.get(i);
            }
        }
        JOptionPane.showMessageDialog(null, "userDatabaseHandler.getUserByUserName() ERROR! No User found");
        return allUsers.get(0);
    }

    public void LogOutAllUser(){
        try{
            FileWriter fw  = new FileWriter("/sample/database/loggedInUser.txt", false);
            BufferedWriter bw = new BufferedWriter(fw);
            PrintWriter pw = new PrintWriter(bw);
            pw.print("0");
            pw.flush();
            pw.close();
        }catch (Exception E){
            JOptionPane.showMessageDialog(null, "User NOT Logged Out");
        }
    }

}

taskDatabaseHandler.java

package sample.database;

import javax.swing.*;
import java.io.*;
import java.util.*;


public class taskDatabaseHandler {
    //INSTANCE VARIABLES
    private ArrayList<task> allTasks = new ArrayList<>();
    private ArrayList<String[]> rawDataRows= new ArrayList<>();
    private ArrayList<String> rawRawDataRows = new ArrayList<>();
    private String fileName;
    private user loggedInUser;

    //CONSTRUCTOR
    public taskDatabaseHandler(){
        fileName="src/sample/database/tasks.csv";
        File file = new File(fileName);

        try{
            Scanner inputStream = new Scanner(file);
            inputStream.nextLine(); //ignores first line
            while (inputStream.hasNext()){
                String data = inputStream.nextLine(); //gets whole line
                rawRawDataRows.add(data);
                String[] values = data.split(","); //splits by commas
                rawDataRows.add(values); //adds the line to an arraylist (dataRows)
            }
            inputStream.close();
        } catch (FileNotFoundException e){
            JOptionPane.showMessageDialog(null, "taskDatabase Constructor error");
            e.printStackTrace();
        }
        System.out.println("TaskDatabase with " + rawDataRows.size()+ " rows initialized");
        System.out.println();
        //Creation of each Task
        for(int i=0; i<rawDataRows.size();i++){
            task tempTask = new task (rawDataRows.get(i)[0], rawDataRows.get(i)[1], rawDataRows.get(i)[2], rawDataRows.get(i)[3]);
            //add each tweet to the allTweets array
            allTasks.add(tempTask);
        }

        //Set Logged in User
        currentUserHandler cUserHandler = new currentUserHandler();
        userDatabaseHandler genesisUBH = new userDatabaseHandler();
        loggedInUser = genesisUBH.getUserByUID(cUserHandler.getCurrentUserID());
    }

    //GETTERS
    public String getCurrentUsersID(){
        return this.loggedInUser.getUserIDAsString(); //Problem Here
    }


    //METHODS
    public ArrayList<task> getCurrUserTasks(){
        return getAllTaskByUID(getCurrentUsersID());
    }

    public void addTask(task iTask){
        //ADD USER TO tasks.csv FILE
        try{
            FileWriter fw  = new FileWriter(fileName, true);
            BufferedWriter bw = new BufferedWriter(fw);
            PrintWriter pw = new PrintWriter(bw);

            //Check if any sign-up fields are blank
            if(iTask.getTaskIDAsString().equals("") || iTask.getUserIDAsString().equals("") || iTask.getDueDate().equals("") || iTask.getDescription().equals("")) {
                //If blank show error and return (don't sign up user)
                JOptionPane.showMessageDialog(null, "Error: Empty Task");
                pw.flush();
                pw.close();
                return;
            }else{
                //If all fields filled
                allTasks.add(iTask);
                rawDataRows.add(iTask.getRawData());
                rawRawDataRows.add(iTask.getRawRawData());

                pw.println(iTask.getTaskID() + "," + iTask.getUserID() + "," + iTask.getDueDate() + "," + iTask.getDescription());
                pw.flush();
                pw.close();
            }
        }catch (Exception E){
            JOptionPane.showMessageDialog(null, "Task NOT SAVED");
        }
    }

    public int getNextTaskID(){
        int highestID = 0;
        for(int i =0;i<allTasks.size();i++){
            if(allTasks.get(i).getTaskID()>highestID){
                highestID = allTasks.get(i).getTaskID();
            }
        }
        return (highestID+1);
    }

    public void removeTask(task inputTask){
        for(int i = 0; i<rawDataRows.size(); i++){
            if(allTasks.get(i).equals(inputTask)){
                //Remove Task
                removeLineFromFile("/sample/database/tasks.csv", rawRawDataRows.get(i));
                allTasks.remove(i);
                rawDataRows.remove(i);
                rawRawDataRows.remove(i);
                return;
            }
        }
    }

    public ArrayList<task> getAllTaskByUID(String UserID){
        ArrayList<task> allRetTasks = new ArrayList<task>();
        for(int i = 0; i<allTasks.size(); i++){
            if(UserID.equals(allTasks.get(i).getUserIDAsString())){
                allRetTasks.add(allTasks.get(i));
            }
        }
        return allRetTasks;
    }

    public task getAllTaskByDescription(String Description){
        for(int i = 0; i<rawDataRows.size(); i++){
            if(Description.equals(allTasks.get(i).getDescription())){
                return allTasks.get(i);
            }
        }
        return allTasks.get(1);
    }

    public void removeLineFromFile(String file, String lineToRemove) {

        try {

            File inFile = new File(file);

            if (!inFile.isFile()) {
                System.out.println("'"+lineToRemove+"' is not an existing file");
                return;
            }

            //Construct the new file that will later be renamed to the original filename.
            File tempFile = new File(inFile.getAbsolutePath() + ".tmp");

            BufferedReader br = new BufferedReader(new FileReader(file));
            PrintWriter pw = new PrintWriter(new FileWriter(tempFile));

            String line = null;

            //Read from the original file and write to the new
            //unless content matches data to be removed.
            while ((line = br.readLine()) != null) {

                if (!line.trim().equals(lineToRemove)) {

                    pw.println(line);
                    pw.flush();
                }
            }
            pw.close();
            br.close();

            //Delete the original file
            if (!inFile.delete()) {
                System.out.println("Could not delete file");
                return;
            }

            //Rename the new file to the filename the original file had.
            if (!tempFile.renameTo(inFile))
                System.out.println("Could not rename file");

        }
        catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }

}

currentUserHandler.java
package sample.database;

import javax.swing.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class currentUserHandler {
    //INSTANCE VARIABLES
    String fileName;
    String currentUserID;

    //CONSTRUCTER
    public currentUserHandler(){
        fileName = "src/sample/database/loggedInUser.txt";
        File loggedInUserFile = new File(fileName);
        try{
            String text = Files.readString(Paths.get(fileName));

            if(!text.equals("")) {
                String loggedInUserID = text; //gets the logged in user
                currentUserID = loggedInUserID;
            }else{
                currentUserID = "0";
            }
        } catch (FileNotFoundException e){
            JOptionPane.showMessageDialog(null, "Error Setting Logged in User");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //GETTERS
    public String getCurrentUserID(){
        return this.currentUserID;
    }

    //SETTERS
    public void setCurrentUserID(String newID){
        this.currentUserID = newID;
        try{
            FileWriter fw  = new FileWriter(fileName, false);
            BufferedWriter bw = new BufferedWriter(fw);
            PrintWriter pw = new PrintWriter(bw);

            pw.print(newID);
            //JOptionPane.showMessageDialog(null, "LoggedInUserSaved");

            pw.flush();
            pw.close();
        }catch (Exception E){
            JOptionPane.showMessageDialog(null, "LoggedInUser Not Saved");
        }
    }


}

FilePaths
IDE Filepaths

I was wondering if anyone has any recommendations on how to reformat my constructors (specifically the File declaration at the beginning of each) so they will run in the jar and IDE. Thank you for any help you can give

Upvotes: 1

Views: 333

Answers (1)

John Carraher
John Carraher

Reputation: 63

Thank you all for your help,
Turns out that writing to any file (ie: txt and csv) doesn't work within a JAR. JARs are locked and can't be edited once created. To fix my problem I just moved my txt and csv files into a new folder under my C:// drive and changed the path to them in my handlers.

Upvotes: 1

Related Questions