I'm trying to write a converter for specific file formats. The converted files should be filtered using a configuration file. Everything works great so far, but I have a problem concerning the reading of a file in a packaged jar.
I have the following structure for my files (Windows):
converter/src/main/resources/files/AStoXES.properties (there are 3 more property files)
If I'm executing this code in Netbeans everything works fine and the file will be read:
this.fileConfig = new PropertiesConfiguration(new File(testing.class.getClassLoader().getResource("files/AStoXES.properties").toURI()));
But if I'm packaging the jar with Apache Maven doing a clean install and run the whole program I'll get a java.lang.IllegalArgumentException: URI is not hierarchical.
After hours of spending time with Google I have found many threads with the same problem and tested lots of things but none of those proposals helped me out of this problem.
I NEED the contents of the file as a java.io.File, so using Inputstream with getResourceAsStream(argument) won't help me out, because I need to work with the properties in there.
Someone knows how to figure this one out?
Solved it by following the link (Loading a properties file from Java package) AndréStannek provided.
This way it could be read. Didn't know that PropertiesConfiguration accepts InputStreams as well.
InputStream in = testing.class.getClassLoader().getResourceAsStream("files/AStoCSV.properties");
this.fileConfig = new PropertiesConfiguration();
this.fileConfig.load(in);
try {
in.close();
} catch (IOException ex) {
Logger.getLogger(ConverterControl.class.getName()).log(Level.SEVERE, null, ex);
}
Thanks to all.
Try to get the runnig jar file, and access it as a zip file.
This may help:
How to get the path of a running JAR file?
As a solution/hack, you may create a temporary File (and an OutputStream corresponding to this File) then "write" your input stream into your output stream. You'll end up with a copy of your original File.
Related
I'm just getting into using "Java Resource Files" and i have a few questions...
I am hoping to distribute my program to others and I'm assuming JAR file isn't the best way. I'd probably go about it by "converting to exe" is this good practice? what are the limitations?
If I convert to an exe does it keep the resource files?
I'm actually just trying to use a resource file. This file is a text file and will just save the users directories for certain files so they don't need set them up every time they open the program. is this even the best way to go about it?
how do you reference the resource file in the code itself?
Here is what I've done.
created a new resource file and since I'm using Netbeans I can see its location under the files tab in the navigator it looks like this:
Mainproject
build
classes
myclass
resources
directories.txt
here is how i'm trying to access it but when i debug it is coming back null.
private void getPaths()//todo
{
try
{
InputStream is = getClass().getResourceAsStream("/resources/directories.txt");
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
br.close();
isr.close();
is.close();
}
catch(Exception e)
{
}
}
"Converting to EXE" is just a fancy way of saying "wrapping the Jar files into an executable container"
"I'm assuming JAR file isn't the best way" not really. It's nice to provide a OS specific means for launching the program at times, but it's not always the best solution.
"what are the limitations?". Well, to start with, you're limiting your self to a single platform. For Mac's you need to bundle the application into a "app" bundle. For linux, I think most people provide scripts to launch their code.
You could also be limiting your self to particular bit depth. If all you supply is a x32 bit executable, then you'll only ever run within a x32 bit environment. This may not be an issue, but you're limiting the available memory to start with...
So yes, generally, your resource files will be safe.
A resource file is generally embedded. What you're describing in part 3 is more akin to a configuration file. This file needs to be stored on the file system (out side of your exe/jar) so it can easily be updated.
"how do you reference the resource file in the code itself?"
For embedded resources you will need to start by using getClass().getResource(...). For you configuration file, I'd say just like any other file...
I would also have a look at Deployment some ideas on the suggest mechanisms for deploying Java programs,
Jar is a perfect format for distribution. You can convert to exe , but the user will still need the JVM installed to run it. Jars are executed with a doubleclick if the JVM is installed AND the jar has a properly formed manifest file.
You can open any file from the JVM, text, binary, XML, property file etc.
To save user settings a good choice is a property file - see http://www.mkyong.com/java/java-properties-file-examples/
InputStream inp = new FileInputStream("src/main/resources/ExportHour.xls");
I have a file in the src/main/resources folder of my Java Spring project.
I am attempting to create an inputstream in one of my Controllers, however I always get a file not found exception. When I change the path location to point specifically to the file on my machine, it works fine.
Any way I can make it so the file can be found within the java project?
Try with spring ClassPathResource.
InputStream inp = new ClassPathResource("ExportHour.xls").getInputStream();
That is because the resources folder in maven is put in your jar file directly i.e. the ExportHours.xls file is put inside your jar in the root directory.
It sounds like you could just change the working directory of your process - it's not where you think it is, I suspect. For example, I suggest you write
File file = new File("src/main/resources/ExportHour.xls");
and then log file.getAbsolutePath(), to see what exact file it's using.
However, you should almost certainly not be using a FileInputStream anyway. It would be better to use something like:
InputStream inp = Foo.class.getResourceAsStream("/ExportHour.xls");
... for some class Foo which has a classloader which includes the resources you need.
(Or possibly /resources/ExportHour.xls", depending on your build structure.)
That way even when you've built all of this into a jar file, you'll still be able to open the resource.
I'm trying to use Java class Properties for saving the settings for my application between executions. Afterwards I would like to export my application into runnable JAR file and keep everything needed in this one file to provide portability. So my application has to find the properties file, load it and then save new settings into it on exit.
The loading works fine:
Properties prop = new Properties().load(this.getClass().getResourceAsStream("properties.cfg"));
But for storing I need to find the same file and overwrite it. The method Properties.store() needs an OutputStream but getResourceAsStream returns an InputStream therefore I cannot find the file and access it.
It should be always located with the *.class file. I found many solutions that work before exporting into JAR but none that would work after exporting. Thanks for any suggestions.
You can't rewrite your jar (or rather, it's complicated and not a good idea).
A preferable solution would be to read the properties from:
a directory on your machine
the .jar file
Initially location 1 wouldn't have a property file and you'd fall back to your .jar file. When you write the properties you'd write them to the nominated directory, and then on the next read you'd read your properties from this location. This would survive restarts etc.
Note that libraries such as Apache Commons Configuration automatically support this tiered properties location mechanism and may save you some time/grief in writing your own solution.
take spring's IO infrastructure (ClasspathResource)
try {
ClassPathResource r = new ClassPathResource("bdd.properties");
Properties properties = new Properties();
properties.load(r.getInputStream());
} catch (IOException e) {
Throwables.propagate(e);
}
this is real simplification.
For this kind of scenario the best approach is to add the properties file to the classpath and load it using something like ResourceBundle.
private static ResourceBundle _properties = ResourceBundle.getBundle("sample.properties");
String sampleProperty = _properties.getString(propertyKey);
How to execute :
Suppose your jar file is MyJar.jar and property file is called sample.properties
then u should write a batch or sh file around it
eg: run.sh
java -cp MyJar.jar:conf "Class with main Method"
I had problems while finding the path of file(s) in Netbeans..
Problem is already solved (checked answer).
Today I noticed another problem: When project is finished,
I have to execute the generated .jar to launch the program, but it doesn't work because an error occurs: NullPointer (where to load a file) when accessing/openning jar outside Netbeans.
Is it possible to open a file with the class file in Java/Netbeans which works in Netbeans and even in any directory?
I've found already some threads about my problem in site but none was helpful.
Code:
File file = new File(URLDecoder.decode(this.getClass().getResource("file.xml").getFile(), "UTF-8"));
The problem you have is that File only refer to files on the filesystem, not files in jars.
If you want a more generic locator, use a URL which is what getResource provides. However, usually you don't need to know the location of the file, you just need its contents, in which case you can use getResourceAsInputStream()
This all assumes your class path is configured correctly.
Yes, you should be able to load a file anywhere on your file system that the java process has access to. You just need to have the path explicitly set in your getResource call.
For example:
File file = new File(URLDecoder.decode(this.getClass().getResource("C:\\foo\\bar\\file.xml").getFile(), "UTF-8"));
I'm new to help file creation in java. I have created a help file "sample.chm" with a 3rd party tool, added it to a java program with package name as "help" calling with runtime class and build the jar. When I run the jar file it is giving me an error that the "file cannot be found, null pointer Exception". I have given a relative path to identify the file like "../help/sample.chm" still it is not working and I tried with various classes to ientify the path. But still the same error.
Request you to please help me in fixing it.
The jar can be placed in different systems and should open this help file with out any issues.
I hope my explanation is sufficient you to identify the problem.
Regards,
Chandu
If you have a file inside a jar, you can't access it as you normally would. You can access it like this:
URL helpFile=Thread.currentThread().getContextClassLoader().getResource("help/sample.chm");
The method used above (getResource) will return a URL; if you want, you can get it as an InputStream as well by using getResourceAsStream instead.
At least a workaround unless a better solution pops up. Use the this.getClass().getClassLoader().getResource way to get an inputstream to the help file inside the jar.
Copy the bytes to a new help file in the target systems temp folder and use this extracted file with the external help file viewer.