Win a copy of Java Concurrency Live Lessons this week in the Threads forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

load/write file with getClass().getResource() is working in Eclipse, but not working in jar  RSS feed

 
Nope Torres
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Again, I posted this question once in StackOverFlow:

original question

but here comes a shorter version:

When I use these lines to read/write a java.io.File:





it's only working as a project in Eclipse.


For example, if there's a file named inputData.txt in the package com.WindThunderStudio.resources, invoking returns:

/Y:/CtrlRecau_WinSuite_DYL/desarrollo/workspace_NEW/CalSaldoFichaje/bin/com/WindThunderStudio/resources/inputData.txt


And, returns:

Y:\CtrlRecau_WinSuite_DYL\desarrollo\workspace_NEW\CalSaldoFichaje\bin\com\WindThunderStudio\resources\inputData.txt



But, if I pack this project as a runnable JAR and run it in Windows OS, it's different. When writing data, the constructed file's absolute path is:

d:\desarrollo\file:\D:\desarrollo\Cal6.jar!\com\WindThunderStudio\resources\inputData.txt


and its path(calling file.getPath()) is:

file:\D:\desarrollo\Cal6.jar!\com\WindThunderStudio\resources\inputData.txt


We can see that the



part is obsolete.

But why it's there when the program runs as a JAR? But it's due to be run and distributed as JAR. Am I using the wrong methods to construct the java.io.File for manipulation?



 
Nope Torres
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry I forget to switch to I/O subforum. If anyone can move this post to there, it's appreciated.
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you put the resource into a JAR then you can't expect to access it as if it were a file. Sure, you can read from it but you can't write to it because a JAR is a read-only thing.

So you're going to have to use a more reasonable strategy. My suggestion: Pick a place in the user's home directory where you are going to store the file. Then your process for reading the file is this:

1. Look in the user's home directory.

2. If it's not there, get the resource from the JAR.

And your process for writing the file is simply to write it into the user's home directory.

You can find out what the user's home directory is by inspecting the "user.dir" system property. You might want to write the file directly there, or you might want to create a subdirectory for your application and write the file into that subdirectory.
 
Nope Torres
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:If you put the resource into a JAR then you can't expect to access it as if it were a file. Sure, you can read from it but you can't write to it because a JAR is a read-only thing.

So you're going to have to use a more reasonable strategy. My suggestion: Pick a place in the user's home directory where you are going to store the file. Then your process for reading the file is this:

1. Look in the user's home directory.

2. If it's not there, get the resource from the JAR.

And your process for writing the file is simply to write it into the user's home directory.

You can find out what the user's home directory is by inspecting the "user.dir" system property. You might want to write the file directly there, or you might want to create a subdirectory for your application and write the file into that subdirectory. When it's a project, what path should it be? The same level with src, with com package....?



So Paul, thanks for your reply! Your idea is like, you cannot change an executable when running it right?

If I understand well, now it makes sense to me. I was thinking about doing something like "open the jar with 7z and edit some files and compress it again"... but when it's running it's locked.

Now, as I don't like the idea of messing up the user document folder, I want to store the file where the jar is stored. So the question changes to be:

How can I find the absolute path of the JAR I am running, and get this path to create a file? The approach must be consistent whether it's a Java project or it's a runnable jar.
 
Dave Tolls
Ranch Hand
Posts: 2504
27
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nope Torres wrote:
Now, as I don't like the idea of messing up the user document folder...


user.dir is not the documents folder, it's the root directory, so Users/<username> in a Windows 10 environment.
Lots of software put stuff in there (usually in their own '.<appname>' directory), or under there in the APPDATA area.
 
Nope Torres
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:
Nope Torres wrote:
Now, as I don't like the idea of messing up the user document folder...


user.dir is not the documents folder, it's the root directory, so Users/<username> in a Windows 10 environment.
Lots of software put stuff in there (usually in their own '.<appname>' directory), or under there in the APPDATA area.


OK, so I understand it's in Windows, and in Linux it's . So we don't have to consider cross-platform problems.

But if I still want to save it where the JAR is? Isn't it more portable?
 
Dave Tolls
Ranch Hand
Posts: 2504
27
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I wouldn't say it was more portable.
You can't guarantee you can easily find out where the jar file is located.

I much prefer creating something in the user.dir like:
.mycompany/myapplication/myfile
 
Campbell Ritchie
Sheriff
Posts: 53779
128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nope Torres wrote:. . . and in Linux it's .
No, the location /. on a linux box is the same as / viz the root of the file system. You will not find your user directory there. It will be something like /home/nopetorres/currentLocation and seems to be the same as you would get from the Linux pwd (=Print Working Directory) instruction.
 
Nope Torres
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:I wouldn't say it was more portable.
You can't guarantee you can easily find out where the jar file is located.

I much prefer creating something in the user.dir like:
.mycompany/myapplication/myfile


Thanks Campell, now I see it, the root in Linux is not the user folder. It's for all the users and system things.
 
Nope Torres
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:I wouldn't say it was more portable.
You can't guarantee you can easily find out where the jar file is located.

I much prefer creating something in the user.dir like:
.mycompany/myapplication/myfile


Now, how do you like this approach? I am on this and when I have something, I will let you know.

 
Nope Torres
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And:
 
Nope Torres
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:I wouldn't say it was more portable.
You can't guarantee you can easily find out where the jar file is located.

I much prefer creating something in the user.dir like:
.mycompany/myapplication/myfile


Yes, my approach is working. I hope it can help anyone who's interested. At last it's something that we often use in Java desktop applications.

The complete code is here:




When running the jar the first time, we have this output:



Running it for the second time:




When writing, data are stored into a txt file named "inputData.txt" in the same folder where JAR is located. And when reading, data are read correctly.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!