• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

Loading properties from a static class

 
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Sheriff
Posts: 3064
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 /.
 
Mike Curwen
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think I must have copy and pasted that when I was in the middle of trying something. Indeed, my actual code uses getClass().getResourceAsStream(). I *do* have the hang of at least that much.

And like you said.. it has no meaning in a static context.

So how *do* I load a properties file when it's a static context?
 
Mike Curwen
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And further... because this is 'actually' a Servlet question in disguise, my property files are all here:

WEB-INF/classes

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.
 
Mike Curwen
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
:roll:


This seems like such a cheat. hehe. But a pretty obvious solution when I thought of it! Like duh! What prevents you from making an object in the static context, and using that object?
 
Mike Curwen
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, small tweak.

The first compiled, but didn't load the file. Because "" is loaded by a different classloader.

So replace "" with an instance of the class in which I'm using this method and it's all happy.
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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)
 
Mike Curwen
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Greg Charles
Sheriff
Posts: 3064
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mike Curwen:

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.
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Mike Curwen
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This has bit me in the butt again!



What am I doing wrong?
 
Ranch Hand
Posts: 1056
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Mike Curwen
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Ron,

So I might resonably expect this to work fine in a servlet container, where each webapp is several steps removed from the bootstrap loader.

I'll just add a check for null, I guess.
 
Politics n. Poly "many" + ticks "blood sucking insects". Tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic