So i'm running into trouble with my little property-file loading method.
It goes much like you've probably seen out there (since I think I 'borrowed' it originally from the net...)
But, as you might guess, I can't use this method from a static context because of Class.getResourceAsStream(fileName);
So what is the alternate, that still ensure my app will be able to find the file? And oh yes, it's actually a servlet and the whole thing might be inside a jar file (the whole point of using the getResourceAsStream()). There probably isn't something I can use with static contexts, that still *absolutely* guarantees the JVM will find the properties file, right?
I'm posting it here, as opposed to Servlets, because I'm curious in general... Why isn't there a static method on the java.lang.Class object to obtain a hmm... 'static class loader'. I'm sure something in that quoted bit should clue me in... Surely *something* has to "load" the static class.
Using it from a static context is irrelevant. It's getResourceAsStream() that's not static on the Class class. The code you've posted wouldn't even compile. You need an instance of the Class class. That is, an object of type Class. (Yes, that's a bit confusing, but you'll get the hang of it.) There are several ways to get such an object. For example, you could say: Object.class.getResourceAsStream(...); You could also say, this.getClass().getResourceAsStream(...); However, that will only work when "this" has meaning ... so not from a static method. The class you use is important, because its package will be used to find your file. For example, Object is in the java.lang package, so the loader will look for your file at java/lang/filename.file. If you want to look at the root level along the classpath, then just make sure your file name starts with a slash /.
And further... because this is 'actually' a Servlet question in disguise, my property files are all here:
which is in the class loading path of the web application.
and all my file names that I send to this method do indeed start with a '/'. So I really don't care WHAT object I'm using.. I'd just like a reference to the classloader.. hard to get (apparently) from a static context.. and I guess that's kinda why I posted in this forum... I was more confused about why I couldn't get one, than why this particular code doesn't work. I know that I'll probably have to break down and use File I/O for my InputStream. But I'd really like it to be portable.
Hmmm, here's how I loaded property files, but into PropertyResourceBundle class. Is there some reason you're not just using java.io classes? Like, something dumb about what I did? (This was in like my first week of using Java, BTW)
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
There's nothing dumb with your approach at all. But what value is in the variable aFileId ?
The reason I have to use a classloader to get at this file is because my application is actually a web-application. So it might be running from a jar file. In which case an absolute filepath through JavaI/O won't work (or will it?). Anyone care to prove that wrong?
So replace "" with an instance of the class in which I'm using this method and it's all happy.
You actually don't need to create an instance of the class. You can use the special ".class" syntax. That was my point with: Object.class.getResourceAsStream(...); String.class.getResourceAsStream(...); also works. However, as you point out, you need to work with a class with the right classloader, so something like: MyServlet.class.getResourceAsStream(...); would work for you.
Joined: Jan 29, 2003
Back a step or two ... aFileId is a string name of a properties file minus the ".properties" extension. This thing reads one properties file which must be in a known location. That file contains a list of directories which contain more properties files. The program goes to each directory in order and reads all the properties files it can find. It keeps the bundles in a hashmap keyed by filename. If it finds the same name twice, the second one replaces the first one. A little like overriding inherited values. The idea was to deploy an identical set of files to all servers - windows, unix, development, staging, qa, production, etc - except for that first one with the list of directories. The directories correspond to different environments, and have names like windows, unix, development, um, you get the idea. A call like ResourceMgr.getString("partnerapp1","url") would get the URL for development, qa, staging, etc. depending on that first list of directories. I thought it was cute at the time. As I recall it made the version control system happier to have exactly the same files on all machines - except the one file that we managed separately and rarely changed.
From the documentation for Class.getClassLoader(): Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.