I am writing a simple JSF application and am trying to get a resource (database.properties file) using Class, ClassLoader, and URL that is not working. url is null and I don't know why. I have done a lot of research but without success.
Code:
Class cls = Class.forName("<packagename>.SimpleDataSource");
ClassLoader cLoader = cls.getClassLoader();
URL url = cLoader.getResource(fileName); // fileName = "database.properties" w/o the double quote
FileInputStream in = new FileInputStream(url.getFile());
Thanks for your comment Sandeep, it was helpful. I found out that my properties file was in the wrong place. I then moved it inside my src folder under the java resources folder and now my properties file gets loaded in. I have a new problem now but will start a new thread if I can't figure it out.
Once you have a URL you can get an InputStream from it using url.openStream(), or you can simply use cLoader.getResourceAsStream(...) in the first place. Your current approach of
FileInputStream in = new FileInputStream(url.getFile());
will work on some platforms but not all, and only when your application is running from a directory on disk. It will fail if your classes and resources are packed up into a JAR, but if you use getResourceAsStream it will work from a JAR as well as an unpacked directory.
Related
I am implementing a Branch Predictor for one of my classes and I am trying to read files from my src folder in Eclipse but for some reason it is not able to open the files. I have done this before with the exact same process so I'm not sure what is different.
traceFile is set from the command line and if I print "input", it will print out the correct file path and I have confirmed it is there manually.
ClassLoader loader = BiModalPredictor.class.getClassLoader();
File input = new File(loader.getResource(traceFile).getFile());
Scanner fin = new Scanner(input);
Is there any insight as to why this might be happening? I've tried restarting Eclipse, refreshing the files, and I've also tested it on another program which worked. No idea why it can't find this file.
Resources on the classpath, i.e. available through the classloaders getResource method, will not be files on the file system when your application is deployed as a jar file, or deployed in general. Do not use File with such resources, instead use getResourceAsStream to access the resource content.
Besides, your code is wrong. getResource() returns a URL. If you want a File object from a URL, you should use new File(uri), where the URI is obtained by calling url.toURI().
File input = new File(loader.getResource(traceFile).toURI());
I would like to know how to add files to my NetBeans project and then access them via getResource or getResourceAsStream. But apparently I can't figure out where my problem lies.
I added some xml file into the root folder of the project and when I try to access it via
InputStream is = this.getClass().getClassLoader().getResourceAsStream("some_file.xsd");
I get null as a result.
Make sure the some_file.xsd is present in the classpath, then also verify if the path to the file is proper.
If not you can instead just read it using FileInputStream. Something like this:-
InputStream fileStream = new FileInputStream(filePath);
and make sure that filePath is a proper relative URL.
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.
In my Maven project, I have the following code in the main method:
FileInputStream in = new FileInputStream("database.properties");
but always get a file not found error.
I have put the file in src/main/resources and it is properly copied to the target/classes directory (I believe that is the expected behavior for Maven resources) but when actually running the program it seems it can never find the file. I've tried various other paths:
FileInputStream in = new FileInputStream("./database.properties");
FileInputStream in = new FileInputStream("resources/database.properties");
etc. but nothing seems to work.
So what is the proper path to use?
Based on "disown's" answer below, here was what I needed:
InputStream in = TestDB.class.getResourceAsStream("/database.properties")
where TestDB is the name of the class.
Thanks for your help, disown!
You cannot load the file directly like that, you need to use the resource abstraction (a resource could not only be in the file system, but on any place on the classpath - in a jar file or otherwise). This abstraction is what you need to use when loading resources. Resource paths are relative to the location of your class file, so you need to prepend a slash to get to the 'root':
InputStream in = getClass().getResourceAsStream("/database.properties");
I have problems with class loaders.
Sometimes it works, sometimes it doesn't work.
When I started, I have tested this works but not from *.jar:
URL url = AcAnalyzer.class.getResource("../stuff/resource");
// and this works even from jar file:
URL url = Acnalyzer.class.getResource("/stuff/resource");
URL url = AcAnalyzer.class.getClassLoader().getResource("stuff/resource");
// But I got into the problem with tomcat..when I need to deploy it into the tomcat I had to do this:
URL url = Thread.currentThread().getContextClassLoader().getResource("something.xml");
where something.xml has to be in WEB-INF/classes/
... url.getFile();
The problem is that most of the time it has to work within and not within jar at the same time. Now I have test where my class is getting resource, and the jar file is used in some project deployed under the tomcat.. and somehow it doesn't want to work anymore:
I'm bit puzzled about class loaders. How to get this resource? And and the same time have working test.
URL url = Thread.currentThread().getContextClassLoader().getResource("com/st/resource");
FileInputStream inputStream = new FileInputStream(url.getFile());
java.io.FileNotFoundException: file:/home/aaa/.m2/repository/com/st/module-1.1-SNAPSHOT.jar!/com/st/resource (No such file or directory)
I'm not sure exactly what the question is in the first part, although I'd advise not using "../" in a resource path.
For the second part, if you want to load a resource you shouldn't use FileInputStream - you should use getResourceAsStream() instead of getResource().getFile(). Just load from that InputStream - there won't always be an individual file that you can load with FileInputStream.
EDIT: The two ways of referring to a resource are ClassLoader.getResource and Class.getResource (and the equivalents with the AsStream suffix). The difference between them (the only difference that I'm aware of, although there may be others) is that Class.getResource treats the given path as being relative to the package of the class that you call it on. So
ClassLoader.getResource("foo/bar/baz/test.xml")
is equivalent to
foo.bar.SomeClass.class.getResource("baz/test.xml");
As for the difference between Class.getClassLoader() and Thread.getContextClassLoader() I won't claim to have a good understanding - I suggest you ask that as a separate question.