Getting the directory path of a given class file

I came across code that tries to read some configuration files from the same directory where the .class file is for the class itself:

File[] configFiles = new File(
    this.getClass().getResource(".").getPath()).listFiles(new FilenameFilter() {
        public boolean accept(File dir, String name) {
            return name.endsWith(".xml");
        }
});

This seems to work in some cases (perhaps when running the code inside Resin), but for me, when launching Tomcat, it just fails with NPE because it getClass().getResource(".")returns null.

A colleague suggested creating another configuration file containing a list of all the ".xml" configuration files (which will really work here, since it remains fairly static), and that you should not try to do something like this in Java,

However, I am wondering if there is any good way that works everywhere to get the path to the directory where the given .class file is located? I think you could get it along the path of the .class file itself as follows:

new File(this.getClass().getResource("MyClass.class").getPath()).getParent()

... but is this the only / cleanest way?

Change . To clarify, suppose we know that this is used in an application deployed in such a way that MyClass.class will always be read from the .class file on disk, and the resources will be there in the same directory.

+3
source share
5 answers

, , Google, . , . , , , , , null . "", , . . , , .

/**
 * Returns the container url for this class. This varies based on whether or
 * not the class files are in a zip/jar or not, so this method standardizes
 * that. The method may return null, if the class is a dynamically generated
 * class (perhaps with asm, or a proxy class)
 *
 * @param c The class to find the container for
 * @return
 */
public static String GetClassContainer(Class c) {
    if (c == null) {
        throw new NullPointerException("The Class passed to this method may not be null");
    }
    try {
        while(c.isMemberClass() || c.isAnonymousClass()){
            c = c.getEnclosingClass(); //Get the actual enclosing file
        }
        if (c.getProtectionDomain().getCodeSource() == null) {
            //This is a proxy or other dynamically generated class, and has no physical container,
            //so just return null.
            return null;
        }
        String packageRoot;
        try {
            //This is the full path to THIS file, but we need to get the package root.
            String thisClass = c.getResource(c.getSimpleName() + ".class").toString();
            packageRoot = StringUtils.replaceLast(thisClass, Pattern.quote(c.getName().replaceAll("\\.", "/") + ".class"), "");
            if(packageRoot.endsWith("!/")){
                packageRoot = StringUtils.replaceLast(packageRoot, "!/", "");
            }
        } catch (Exception e) {
            //Hmm, ok, try this then
            packageRoot = c.getProtectionDomain().getCodeSource().getLocation().toString();
        }
        packageRoot = URLDecoder.decode(packageRoot, "UTF-8");
        return packageRoot;
    } catch (Exception e) {
        throw new RuntimeException("While interrogating " + c.getName() + ", an unexpected exception was thrown.", e);
    }
}
+3

, ?

:

  • jar

URL-, , file://, ... .

+2

, .class, getResourceAsStream.

this.getClass().getResourceAsStream( "filename.xml" )

, , "" (, jarfile)

+2

, Java . Sun Facelets , , URL- , . , getResource, , . , , getClass(). GetProtectionDomain(). GetCodeSource(). GetLocation(), URL-, ( ). URL-to-File, . .

, getResource URL, , getPath() . , , , . (URL.toURI()).

+1
0

Source: https://habr.com/ru/post/1713661/


All Articles