java - 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 中运行。感谢您提供的任何帮助
解决方案
谢谢大家的帮助,
结果证明写入任何文件(即:txt 和 csv)在 JAR 中都不起作用。JAR 被锁定,一旦创建就无法编辑。为了解决我的问题,我只是将我的 txt 和 csv 文件移动到我的 C:// 驱动器下的一个新文件夹中,并在我的处理程序中更改了它们的路径。
推荐阅读
- azure - 无法确定在 Azure 流分析中使用哪个窗口
- autodesk-forge - 通过命令行打开 Revit BIM360 模型
- python - 在 Glue 中合并/压缩/复制两个动态帧
- intellij-idea - IntelliJIDEA 花费太多时间来打开一个新项目
- r - 添加满足两个条件的值
- jboss - JBAS010441:无法为驱动程序 [org.mariadb] 加载模块?
- sas - 原始数据导入
- sql - 选择合理的指标以尽快恢复范围的最小值和最大值,
- ruby-on-rails - 使用 Webpack 在 Rails 6 中安装 Glide.js
- docker - 如何使用客户端 api 从正在运行的 pod 获取当前命名空间