To the best of my knowledge, Class.getResourceAsStream() gets an InputStream directed at a file within the .jar file? If I'm wrong about this, please correct me.
Is there any way to temporarily 'load' an external file into the .jar, so that the getResourceAsStream() method can retrieve it?
For example loading C:/folder/file.txt into the .jar so that MyClass.class
.getResourceAsStream("file.txt") would return a working InputStream to the file, or at least a copy of it that has been 'loaded' temporarily into the .jar.
I'm sorry I've worded this so badly, I hope you can understand what I'm trying to do, wasn't quite sure how to explain it simply.
Nope, the getResourceAsStream() method gets a file from the classpath. That includes anything that is specified like this on the command line (windows version, linux uses ':' as delimiter):
java -cp "path;path2;path3;path4/some.jar" your.main.Clazz
Related
I have following code block in my application;
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(FilePath);
Here 'FilePath' is an absolute path of the file.
Above code works fine in linux and in windows when i run the application in normal mode.(ie: in command prompt)
But this is NOT working, when I run the application as a windows service. I get input stream as 'null'.
Anyone encountered such issue before? I could not find any information regarding this other than java classloaders . Here we use "ContextClassLoader", which is the right classloader to be used..
Any clue on this?
I think this happens because you have "." (the current folder) on the classpath. That is a) a bad idea and b) makes your app break in odd ways.
What you need to understand is the difference between a file and a resource. A file is something outside of the classpath.
You should use File and FileReader to access them.
A resource is something on the classpath. Paths for resources always use / as file separator and not File.separator.
Another way to fix this is to add $HOME/repository/ (Linux) or %HOME%/repository/ to the classpath and load the resource using "resources/api_templates/api.xml". for this to work, resources must be a folder in $HOME/repository/.
If you don't do this, then all files in your home directory (or whatever directory you happen to start the application in) are added as resources to the classpath.
I just want to read a file into my program. The file is located one directory above the working directory at "../f.fsh". So the following code runs correctly when I run it in the IDE
String name="../f.fsh";
InputStream is = getClass().getResourceAsStream(name);
InputStreamReader isreader=new InputStreamReader(is);//CRASHES HERE WITH NULL POINTER EXCEPTION
BufferedReader br = new BufferedReader(isreader);
but when I create a JAR file that has f.fsh zipped inside of it and run it, it crashes when creating the InputStreamReader, because the InputStream is null.
I've read a bunch of answers to questions about input streams and JAR files, and what I got out of it is that I should be using relative paths, but I am already doing that. From what I understand getResourceAsStream() can find files relative to the root of the project, that is what I want. Why does it not work in the JAR? What is going wrong, how can I fix it?
Does it have to do with the classpath? I thought that was only for including files external to the jar being run.
I have also tried, but still fail, when putting a slash in:
InputStream is = getClass().getResourceAsStream("\\"+name);
I looked at: How to get a path to a resource in a Java JAR file andfound that contents of a JAR may not necesarily be accesible as a file. So I tried it with copying the file relative to the jar (one directory up from the jar), and that still fails. In any case I'd like to leave my files in the jar and be able to read them there. I don't know what's going wrong.
You can't use .. with Class.getResourceAsStream().
To load a resource f.fsh in the same package as the class, use SomeClass.class.getResourceAsStream("f.fsh")
To load a resource f.fsh in a sub-package foo.bar of the package of the class, use SomeClass.class.getResourceAsStream("foo/bar/f.fsh")
To load a resource f.fsh in any package com.company.foo.bar, use SomeClass.class.getResourceAsStream("/com/company/foo/bar/f.fsh")
This is described in the javadoc of the getResource() method, although it lacks examples.
If .. works in Class.getResourceAsStream() while running from Eclipse, it's a bug in Eclipse. Eclipse and other IDEs implement custom class loaders to fetch resources from the project at runtime. It looks like the class loader implementation in Eclipse isn't performing all the necessary validations on input to getResourceAsStream() method. In this case the bug is in your favor, but you will still need to rethink how you structure your resources for your code to work in all cases.
it's mandatory that the name of the file is CASE SENSITIVE
it's mandatory to refresh (F5) the project explorer if the file is moved or copied outside Exclipse
How would I access a picture in a different folder in Java? I have a series of pictures and they change based on user input, which is what x is for.
picture.setIcon(new ImageIcon("\\resources\\icons\\pictures\\"+x+".png"));
The images are located (from the .class files) in resources/icons/pictures, but the above code doesn't work. The value of x isn't the problem since it works as it should. Am I calling the pictures the right way?
Am I calling the pictures the right way?
Probably not. If they are (embedded) application resources they will typically be in a Jar and unavailable via the String based constructor of the ImageIcon (which expects the String equates to a File path).
For an embedded resources, access them by URL.
URL urlToImg = this.getClass().
getResource("/resources/icons/pictures/"+x+".png");
picture.setIcon(new ImageIcon(urlToImg));
You should be using forward slashes instead of backslashes I believe.
new ImageIcon("/resources/icons/pictures/"+x+".png")
This is the standard Java cross-platform way of denoting resource file paths. It still works on Windows - the Java runtime library handles the transaltion for you.
The images are located (from the .class files) in resources/icons/pictures
That's a problem. The system isn't interested in where the class file is, but from where you invoke a program.
Specifying a resource folder via command line,
java -jar myJar.jar C:\\home\\of\\the\\images
or via a property
java -jar myJar.jar -DImageHome=/foo/bar/images
or from a properties file is most flexible.
If you like to put the images into the jar, use Andrews suggestion, getClass ().getRessource ("...");
Btw: I know for sure, that forward slashes are portable. Backslashes, afaik, aren't.
My Java program references a lot of data files. I put them in a top level directory called data/, along with src/ and bin/. In Eclipse, references to data/ and ../data/ both seem to work. When I run it from the command line, only ../data/ works.
When I put the bin/ and data/ directories in a jar and correctly set the entry point, it doesn't seem to know that I want it to access the data/ directory inside the jar. The only way I've been able to get it to work is by setting the references to ../data/ and placing the jar in the bin directory. This obviously doesn't do me any good, because it's not self-contained.
What do I need to do to the references to make them work?
Thanks
I'd recommend you access the files in a classpath-relative way, whether in Eclipse or in a compiled JAR.
There are a few ways you might go about it, but a basic JDK-only approach would be to use Class's getResourceAsStream() method, giving you access to an InputStream object that you can read in.
If your resources are in a jar file, consider using this method to read them:
class Class {
InputStream getResourceAsStream(String name)
}
This looks for the resource relative to a class (which may be in a jar), rather than relative to the working directory.
Thanks for pointing me down this path, guys. I ended up doing a really hacked up workaround because I'm not very good with IO yet. I used getClass() to construct a URL:
http://forums.sun.com/thread.jspa?threadID=5258488
Then made a new File object from this string (new File(file)):
String file = url.toString().replaceFirst("file:", "");
This allowed me to keep the same code that referenced the file objects.
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.