I needed this for a kind of dynamic class loader, where the binary name of the package of an object was required. What made it more complex is that the classpath of the object is not the local filesystem path, where the java executable was invoked (such as 'bin' in an eclipse project)
I searched the forum, and didn't find a solution that addresses all of these problems. Finally I came up with my own solution, and I'll share it with you (also because there might be some bright minds who can tell me it can be done much simpler (which I hope))
@SuppressWarnings("null")
public static String getPathFromClass(Class< ? > rootClass) throws FileNotFoundException
{
String rootPath;
{
// These are all the possible directories where the package root
// exists (relative to where the java executable might be invoked).
String systemPaths[] = {"bin", "."};
File root = null;
for (String systemPath : systemPaths)
{
root = new File(systemPath);
if (root.exists())
{
break;
}
}
if (!root.exists() || !root.isDirectory())
{
throw new FileNotFoundException("No package root found");
}
rootPath = root.getAbsolutePath();
}
String localPath;
try
{
localPath = new File(rootClass.getResource(".").toURI()).getPath();
}
catch (URISyntaxException e)
{
// Should never happen; Hack to prevent unjust error.
localPath = "";
}
if (!localPath.startsWith(rootPath))
{
// What's going on ??
throw new FileNotFoundException("Class' local path not inside package root");
}
return localPath.substring(rootPath.length() + 1).replace(File.separatorChar, '.');
}
Example:
main class is in c:\projects\test\bin\test\mj\foo\Main.class (package declaration sais "test.mj.foo".)
java.exe is executed from c:\projects\test\
calling this method with an instance of the Main class returns: "test.mj.foo".