I've been working on a Java program for a company over the summer and it is nearing completion. Being something of a novice programmer, I've never produced a program for use on other systems using files I've created. My program reads and writes to Excel using Apache Poi, and currently the Excel file being used lies in a specific directory specified by the program. The program also uses some images that lie in directories specified by the code.
How could I make this program runnable on other systems? Would it be possible to have the program create an Excel document whenever it is "installed" on another system?
Currently I'm using Eclipse and the systems are windows 7.
You can pack your application in a .jar, actually a zip file with inside .class files and resource files. Those resource files, like your images, can be taken with getClass().getResource("path/x.png") or getResourceAsStream. The path is either package relative or absolute: "/abc/def.jpg".
These resources must be read-only (as they are inside the .jar). However you may store an Excel template as resource, and copy that to the user's directory.
System.getProperty("user.home")
Will give the user's directory where you may copy your resource to.
Path appWorkspace = Paths.get(System.getProperty("user.home"), "myapp");
Files.createDirectories(appWorkspace);
Path xlsx = appWorkspace.resolve("untitled.xlsx");
Files.copy(getClass().getResourceAsStream("/data/empty.xlsx"),
xlsx);
Related
I'm trying to develop a cross-platform application that works on Desktop and Android as well using JavaFX and Gluon.
At runtime my code creates a serialized file in my resource folder. I also need to read and write serialized data from/to it.
I managed to work it on desktop, but not on android. Because it have a different file structure I guess.
That is why I try to get the file path dynamically.
Existing resource files, which are created before runtime (and not modified) seems to works fine on both platform.
I tried with new File("src/main/resources/folder/file.ser").getAbsolutePath(); and by trying to access it from my root folder like this: getClass.getResources("/folder/file.ser").getPath();. Both of them works fine on desktop (Windows) but unfortunately Android does not find the file by file path.
An other problem could be that I should not create runtime files in the resource folder but then where should I?
Any idea how can I read and write runtime created files that works both on android and desktop?
(If the information is not enough to help me, I try to reproduce my code in a minimal form and provide further details.)
I think you are on a completely wrong track. Creating or writing to files in the resource folder does not work in general. The idea is that files in the resource folder get packaged into jar files or are otherwise bundled with an application and are not writable at runtime.
What you should do is to create an application folder when your program is launched for the first time. A common practice on desktop is for example to create an invisible folder ".myApp" in the users home directory. On other platforms like Android there are other platform specific naming and location rules, but the concept is the same. At first launch time you can also copy necessary resources from your resource folder into this application folder so that you can edit them at runtime.
Resource files with a path on the class path, could be packed in a jar and should be considered read-only, especially as resources might be cached in some cases. They are not File. They can be captured by URL, URI, Path. The paths are case-sensitive and the path separator is /.
Hence resources can only be used as a template, an initial file. They should be copied to a real File, outside the application.
Path path = Paths.get(System.getProperty("user.home"), ".myapp/file.ser");
Files.createDirectories(path.getParent());
if (Files.exists(path)) {
URL url = MyClass.class.getResource("/folder/file.ser");
Path template = Paths.get(url.toURI());
Files.copy(template, path);
}
Furthermore .ser, a serialized java object, is not a good idea. I would suggest XML
using JAXB with annotations. More readable, maintainable, versionable. No clash between development JRE at your place and deployed JRE at the client.
So I've created just a simple application which I'm using to apply for a highschool internship. It was built using Eclipse.
I initially exported into a runnable .jar file, but the location I initially saved files, ("src/fileDirectories") didn't work on export.I then set the location to "./fileDirectories") which works and the app can actually run, however the .jar file creates the folder directory in the same folder as the .jar file.
This isn't too bad, as I can create a folder with the .jar and the saved files in it, which is fine, but similar to images, I'm wondering if there is a way to save .txt files in a directory to the .jar file so everything works with just the .jar application.
Assuming the files you want to access are static, and are not changed by the application, you can do this using the classpath.
When you access a file using new File("path"), Java will look for it in the file system, relative to the working directory (i.e. where the application was launched from.
An alternative way to access files is to look them up from the classpath - this is the list of locations Java searches for resources. It includes, among other things, the top level of your JAR archive. You can access this as follows:
this.getClass().getResourceAsStream("/my_file.txt")
Build tools will generally have preconfigured directories (e.g. src/main/resources) which get copied from your source tree into the JAR so they can be accessed in this way.
This is great if you have some static resources or config which you want to access at runtime, but don't want to have to pass around with your application.
However, if what you want is a working folder for files which your application will make changes to or create new instances of, like user documents, you don't want this to be editing the JAR - you'll need to make a separate folder for these.
I've got a Java program which stores/recalls data from a load of .txt files located in my C drive. Currently, the file path for these is hard-coded into my Java program.
I'm now looking to distribute this software and am wondering how can I make it so that the user can specify a file location during installation and then I can point my program to this location without having hard-coded it.
This is pretty standard functionality but I've struggled to find how to achieve it. Can I use relative file paths, i.e. have the .exe for the java program in the same folder as the .txt files, or do I have to use something like Windows registry paths?
Many thanks for your help.
Cheers,
Robin
Use the system property "user.home" as the root of your path. Most of the stuff installed these days use this system property as the parent dir and a predefined folder. These saves a lot of trouble. Combine that with the File.separator char to avoid further portability issues
I'm create an application that is going to be run on Windows, Mac OX and Linux. I have a properties file storing user settings which need to be read and changed on the fly.
A JAR file is compressed and is not meant to be changed on the fly which means I should write to an external file.
I'm using :
new FileInputStream("database")
new FileOutputStream("database")
How do I create a URL which is going to be consistent throughout all three operating systems. The JAR is run as an application on the desktop and I would like the file to be stored somewhere discrete.
I've tried reading from a local file in the same package as this class :
this.getClass().getResourceAsStream("database")
This works however I can't seem to create an output stream to write to the same file but this would be breaking the rule of changing a JAR file on the fly.
There are plenty of good reasons for which you should not do this, off the top of my head:
GetResourceAsStream does not necessarily get the file from the JAR itself. You coincidentally got it from there because the Jar was the first or the only element in the class path.
Writing a file in your own Jar could break the JAR signature if you are going to sign it.
The database could need to be backed up; in this case you may want to back it up separate from the code (the code could be upgraded when restoring the database).
Hope this helps.
I am working on a java project and I was wondering if it is possible to write a code that can create a txt file directly into the bin folder (for example the bin folder for eclipse, where I can use getClass() to access the txt files) so that the user will not be able to see the created txt files when using the program.
You can surely do this. But think again. User does not run program from Eclipse. User typically runs program packed in jar, so all class files are not in filesystem but into jar. Moreover the user even probably does not have rights to write into file system except special folders.
Bottom line: you you want to create application that stores some run-time data in file system you should either user user home or temporary directory or use java.util.prefs.Preferences that provide platform independent way to save and retrieve data using file system in unix and registry in windows.
If you choose to create file yourself you can retrieve use home and temporary directory using system properties user.home and java.io.tmpdir.