Finding Out Where Your Class Files Are
Sometimes, when you are writing a program, you need to install data (e.g. by unzipping example files) or to find additional data (e.g. plugins). If you know the location of your class files, you can put the data close to them or start your search there. Your program will usually be packaged as a JAR file, so this scheme allows you to keep everything in the same directory. But any solution should also work for unarchived files, because you want to test while developing your (un-jarred) code. Until now, I’ve always used hacks involving Class.getResource() and looking for exclamation marks in the returned URL to find out if the program is currently running from a JAR. Recently, I’ve discovered a simpler solution (source):
ProtectionDomain protectionDomain = HyenaDesk.class.getProtectionDomain();
File codeLoc = new File(protectionDomain.getCodeSource().getLocation().getFile());
For example, this code computes the following two values for codeLoc.
- Unarchived: /home/rauschma/workspace/hyena_desk/bin
- JAR: /home/rauschma/workspace/hyena_desk/build/hyena_desk.jar
From http://2ality.blogspot.com/2010/04/finding-out-where-your-class-files-are.html
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
Mladen Girazovski replied on Fri, 2010/04/30 - 2:58am
Hi Axel,
Class.getRessource is not a hack.
If you're using a proper build tool like Maven, then there is no need for this kind of workaround, or "hack" ;)
Roger Lindsjö replied on Fri, 2010/04/30 - 10:12am
in response to: mgira
Artur Biesiadowski replied on Sat, 2010/05/01 - 1:34am
in response to: rl29140
Following the maven argument, I expect following comments to appear soon
- if you follow TDD, you won't have such problems, because it will be covered by test case before you hit it
- in Clojure, it is a lot shorter, just write (whereIsMyClass HyenaDesk). Attach following library of utility functions to your code (but they don't count as lines of code, because they are utility)
- groovy version looks a lot better, codeLoc =HyenaDesk.class.protectionDomain.codeSource.location.file; it doesn't matter that it is 100 times slower, because fortune 500 companies use groovy and it is not performance critical part of the code anyway
- groovy++ version looks same good as groovy, but is same fast as java - and we will release groovy++ very soon
- you are doing it wrong, with OSGi you won't have this issue - you can't play with physical locations of code there and it is a proper way to solve this problem
- it is sooo hardcoded, you should use DI, get CodeLocator interface injected and pass class to it; actually, you should not pass a class there, but make this entire call in spring xml and just inject final code location to your class; it will help you with tests in case you don't have classloaders or classes in your program
Few years ago it would be also about webservices, agile methods and having garbage-free method for that in Javolution, but I don't see that stuff so often anymore.
For people with no sense of humor - I know that 80% of the information above is wrong, but please think about other 20% when you post the answers about your favorite silver bullet next time ;)
Mladen Girazovski replied on Sat, 2010/05/01 - 2:32am
in response to: rl29140
Maven helps you to avoid such differences between a packaged app and an app in an IDE or if the unit tests are being run, after all, why should my code bother how it's being run, this isn't it's responsibility.
It's merely a question of dependencies, the classpath and resources in it.
Steven Baker replied on Sat, 2010/05/01 - 5:33pm
Axel Rauschmayer replied on Mon, 2010/05/03 - 9:05am
in response to: mgira
William Houghtaling replied on Mon, 2011/07/04 - 5:43am