0

I'm trying to programmatically find the full path of a jar file while it's running. I know there are a number of other questions about this, but none of them seem to work for me - most notably, I've stumbled across

MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().g­etPath()

a number of times. That particular method works for me when debugging in Eclipse, but once I compile to a jar, it returns a NullPointerException. Other methods have met similar problems after compiling.

I have a temporary workaround by using java.class.path, but that only returns the full path when I execute the jar from the GUI - in the terminal, it fails.

I should also note that the only system that I'm having this problem on is Linux. On Windows and Mac, I have no troubles.

Any help would be appreciated :)

Thanks!

Derek

EDIT: The jar is executable, if that changes anything.

Derek Redfern
  • 1,009
  • 12
  • 18

2 Answers2

2

You can't do it. There is no requirement for ClassLoaders to support this, and most don't.

Or, perhaps this formulation would be more helpful. Binary classes come into the JVM via ClassLoader objects. ClassLoader objects are not required to keep any track of the provenance of the classes they load. And they can load them from anywhere: a jar, over the web, a database, an old tin can.

So, if you want to always know the provenance of classes in your application, you have to always load code with a class loader that, indeed, does track provenance in a manner useful to you.

If you control the entire application, you can do that.

If you don't control the entire application, and are rather talking about an arbitrary jar loaded into an arbitrary class loader in an arbitrary app, you can't depend on learning its location.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • Thanks much! This is good to know. One other note in case it changes anything - I forgot to mention that this is an executable jar file. – Derek Redfern Apr 16 '11 at 18:14
  • If you are sure of that, then the system property java.class.path is your friend. Your class to be there. – bmargulies Apr 16 '11 at 18:21
2

The following works for me even when running from a jar file:

URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation();
String p = URLDecoder.decode(url.getFile(), "UTF-8");
File jarFile = new File(p);

Sending the path through the URLDecoder is important because otherwise a pathname with %20 in it will be created if the directory contains spaces.