I tried to create an InputStream pointing at an .ico file, which is in a directory in the src directory. I also create an InputStream for a different jar file in my src.
InputStream inIco = Installer.class.getResourceAsStream("/res/" + iconName + ".ico");
InputStream inApp = Installer.class.getResourceAsStream("/res/" + applicationName + ".jar");
that is how I tried to load it. The inputstream for the jar file works, but the other one is null.
Edit: Sorry for the confusion guys. I didn't build the jar, I just ran it from my editor, which obviously gives me different results, now it is working. Thanks for your answers.
getResourceAsStream (gRAS) loads from the same place java loads class files. That's great - it means you can ship your app as a jar and put these resources inside. If it's not working for you, you've misconfigured your build. Specifically, java is first going to determine the classpath root of your Installer.class file and looks there. If you're not sure what that is, run this code:
System.out.println(Installer.class.getResource("Installer.class"));
which will print something like jar:file:/Users/carlos/projects/FooBar/dist/foobar.jar!com/foo/Installer.class
and this tells you that gRAS is going to look in that foobar.jar file.
From there, the resource is loaded relatively to the root (because of that leading slash): Within that jar, it will look for /res/app.ico. Without it, it loads relative to the same dir/package of Installer class (in this example above, gRAS("hello.txt") is the same as gRAS("/com/foo/hello.txt").
To make this work out, your build system is responsible. For maven and gradle, have src/main/java/com/foo/Installer.java along with src/main/resources/res/icon.ico and all should be well. If this is not working out, explain how you've set up your environment because something is misconfigured if this isn't working. If you're using another build tool (such as perhaps ant, sbt, or relying on your IDE to take care of it), name the tool and perhaps we can help address the misconfiguration.
Related
Using the following code to set a system property:
ClassLoader classLoader = StartMain.class.getClassLoader();
URL resource = classLoader.getResource("com/myname/lib/chromedriver/chromedriver.exe");
File f = new File("Driver");
if (!f.exists()) {
f.mkdirs();
}
File chromeDriver = new File("Driver" + File.separator + "chromedriver.exe");
if (!chromeDriver.exists()) {
chromeDriver.createNewFile();
org.apache.commons.io.FileUtils.copyURLToFile(resource, chromeDriver);
}
This works perfectly when I run my application configuration in my IDE, IntelliJ. However, when I build a JAR and attempt to use this outside of IntelliJ, the resource URL returns as null. Why is this so?
Going via your classloader is risky. It probably doesn't explain your problem but it might; in any case, this alternative way to do it is shorter, simpler, more idiomatic, works in all places your take works, and works in more places to boot:
The best way to fetch resources like this is like so:
StartMain.class.getResource("/com/myname/lib/chromedriver/chromedriver.exe");
Note that this one starts with a slash! This style goes relative to your own class file location (your package, basically) if you don't.
Either form will look for the entry:
/com/myname/lib/chromedriver/chromedriver.exe
inside the same jar that StartMain.class lives. If it is not there, then this obviously won't work - fix your build so that it is included. At 'runtime' some folder may be on the classpath that would resolve this file; if that folder is then not folded into you jar during the build, that would explain why it works within the IDE but not elsewhere.
NB: You generally don't need any apache utils. For example, there's InputStream's transferTo which can make this a one-liner too (fetch getResourceAsStream instead).
I have tried many variants but I cant find correct.
I have something like
Inside my jar, which created by Maven I can see that
That is my folder with classes. And, by the way, If I start my program in IDEA, not from Console, there is not any exception with paths
Here, I am in debug mode start my jar trying to see, where is the problem.
If I do 'file.exists()' it would be false but file inside. I think, that problem because of '.jar!\' in the path, but I don`t know how to remove that.
Anyway I've tried absolute and relative path, I've tried
Thread.getCurrentThread.getContextLoader.getResource()
GUI.class.getResource()
GUI.class.getClassLoader.getResource()
Nothing help
You can't use File to open resources inside a jar file. File can only be used with normal files and directories.
Note: using File works fine within in the IDE, since all files are not packaged in a jar file yet. But the program will break after you package it.
Once you locate the resource eg. URL res = GUI.class.getResource("/rxtx64/myres.dll") , you can open that resource as a stream InputStream is = res.openStream(); .
See also related answers Utils to read resource text file to String (Java) and How to read a text-file resource into Java unit test?
I want to get the path to a resource for ImageIO to read out a BufferedImage from some .png s.
While developing the project I use a relative path to "/bin/stuff/icons/image.png" , but this will definetly not work when I put everything together into a .jar file, so I need a way to get the path to these resources both while testing in eclipse and when later running it within a .jar .
After a lot of trying out both finding the file and getting the input stream to the file I came to the conclusion that this approach works every time:
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(path)
BufferedImage image = ImageIO.read(in)
Where path is
"projectName/resourceFolder/" + nameOfResource.stuff
as found in the src directory of the eclipse project.
E.g.
"myProject/images/icon.png"
When getting only the resource and then getting the path of the resource to link to a file, you will get FileNotFoundExceptions when using a .jar (but not while testing with eclipse, so one should be warned to think that his code works).
And - no - I don't save images in the bin/ - but they are copied to this directory and thus I find them there while testing. Now everything seems to be working.
Don't put anything under the bin directory in Eclipse: if you run a clean on the project it will be erased.
What you can do is to define a new source folder like resources, and put the image there. This way it will be automatically copied to the bin folder.
If you include the resources folder into the Jar, it will be available in both environments by using something like:
ImageIO.read( getClass().getResource("/image.png") )
PS: You can evade using a different resources folder but mixing the sources and images will quickly pollute your source folder.
I'm trying to read from a text file in Netbeans. In the top level of my project directory I have foo.txt. Then in my code I have:
File file = new File("foo.txt");
It throws a FileNotFoundException, however. It's a Java web application using Spring and Tomcat, but I'm not sure if those details matter since I'm running the whole thing inside Netbeans. Basically, I just want to know where I need to put the file so Netbeans will read it.
Update - good call guys, it's looking in Tomcat's bin directory. Now this may be a stupid question but, how would I go about getting it to look in my top level project directory? I feel like dropping text files into tomcat's bin would be innapropriate.
You can try printing the absolute path of the File object to see where it is looking on the filesystem.
System.out.println(file.getAbsolutePath());
I would use the following to figure out where to put the file:
System.out.println(System.getProperty("user.dir"));
To directly answer your question, If you're running an application on Tomcat, files will be opened from the current working directory. That will likely be the bin/ folder in your tomcat directory.
You can find out for sure where your program is looking by examining the result of file.getAbsolutePath().
However, for web applications, I would suggest putting files you need to read in your classpath so you don't have to depend on a certain file structure when you deploy your web application.
try System.getProperty("user.dir") to get current working directory
BufferedImage = ImageIO.read(getClass().getResourceAsStream("/Images/player.gif"));
First of all, yes I did add the image folder to my classpath.
For this I receive the error java.lang.IllegalArgumentException: input == null!
I don't understand why the above code doesn't work. From everything I read, I don't see why it wouldn't. I've been told I should be using FileInputStream instead of GetResourceAsStream, but, as I just said, I don't see why. I've read documentation on the methods and various guides and this seems like it would work.
Edit: Okay, trying to clear some things up with regards to what I have in the classpath.
This is a project created in Eclipse. Everything is in the project folder DreamGame, including the "Images" folder. DreamGame is, of course, in the classpath. I know this works because I'm reading a text file in /Images with info on the gif earlier on in the code.
So I have: /DreamGame/Images/player.gif
Edit 2: The line that's currently in the original post is all that's being passed; no /DreamGame/Images/player.gif, just /Images/player.gif. This is from a method in the class ImagesLoader which is called when an object from PlayerSprite is created. The main class is DreamGame. I'm running the code right from Eclipse using the Run option with no special parameters
Trying to figure out how to find which class loader is loading the class. Sorry, compared to most people I'm pretty new at this.
Okay, this is what getClassLoader() gets me: sun.misc.Launcher$AppClassLoader#4ba778
getClass().getResource(getClass().getName() + ".class") returns /home/gixugif/Documents/projects/DreamGame/bin/ImagesLoader.class
The image file is being put in bin as well. To double check I deleted the file from bin, cleaned the project, and ran it. Still having the same problem, and the image file is back in bin
Basically, Class.getResourceAsStream doesn't do what you think it does.
It tries to get a resource relative to that class's classloader - so unless you have a classloader with your filesystem root directory as its root, that won't find the file you're after.
It sounds like you should quite possibly really have something like:
BufferedImage = ImageIO.read(getClass().getResourceAsStream("/Images/player.gif"))
(EDIT: The original code shown was different, and had a full file system path.)
and you make sure that the images are copied into an appropriate place for the classloader of the current class to pick up the Images directory. When you package it into a jar file, you'd want the Images directory in there too.
EDIT: This bit may be the problem:
First of all, yes I did add the image folder to my classpath.
The images folder shouldn't be in the classpath - the parent of the Images folder should be, so that then when the classloader looks for an Images directory, it will find it under its root.
If you use resourceAsStream "/" referes to the root of the classpath entry, not to the root of the file system. looking at the path you are using this might be the reason.
If you load something from some home path you probably should use a FileInputStream. getResourceAsStream is for stuff that you deploy with your app.