首页 > 解决方案 > java 程序(带有 txt/csv)在 IDE 中可以正常工作,但不能在 jar 中

问题描述


我目前正在尝试为我在 Intellij 中开发的 todolist-app 创建一个可执行 jar。我使用 CSV 文件来存储用户和任务,并使用 txt 文件来存储当前用户。虽然我已经能够在我的 IDE 上运行该程序,但当我尝试通过 Windows 上的命令提示符运行它时,我收到此错误:

错误:

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)

我注意到错误与程序无法找到我在下面列出的 userDatabaseHandler.java taskDatabaseHandler.java 和 currentUserHandler.java 类的构造函数中请求的 csv/txt 文件有关。
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");
        }
    }

}

任务数据库处理程序.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
包 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 文件路径

我想知道是否有人对如何重新格式化我的构造函数(特别是每个开头的 File 声明)有任何建议,以便它们可以在 jar 和 IDE 中运行。感谢您提供的任何帮助

标签: javaintellij-ideajarexecutable-jar

解决方案


谢谢大家的帮助,
结果证明写入任何文件(即:txt 和 csv)在 JAR 中都不起作用。JAR 被锁定,一旦创建就无法编辑。为了解决我的问题,我只是将我的 txt 和 csv 文件移动到我的 C:// 驱动器下的一个新文件夹中,并在我的处理程序中更改了它们的路径。


推荐阅读