简体   繁体   中英

How can I debug resources path loading or the ClassLoader in general?

I've read up some questions by people having problems loading resources. I have followed the instructions they've got (though these instructions actually differ which means either were incorrect - I tried all).

I created enum to load the resources for me when needed. It's long but I'll share it in case somebody came here from google and could make use of it:

package cz.autoclient.GUI;
/**
 * Enum of resources used for GUI. These resources are packed in .jar and are for internal use.
 * Provides lazy-loaded Image and ImageIcon for comfort.
 * @author Jakub
 */
public enum ImageResources {
  ICON("IconHighRes.png");
  //So according to [this guy](https://stackoverflow.com/a/17007533/607407) I
  //  should enter classpath beginning with slash to make sure it's absolute path from
  //  the root of my .jar
  public static final String basepath = "/cz/autoclient/resources/";
  //Cache everything to have less letters to write
  public static final ClassLoader loader = ImageResources.class.getClassLoader();
  public static final Class leclass = ImageResources.class;
  //String is immutable so it's ok to make it a public constant
  public final String path;
  //These will fill up on demand when needed
  private ImageIcon icon;
  private Image image = null;
  //If image has failed, we'll not try to load it again and will return null straight away
  private boolean image_failed = false;
  //Constructor concatenates the individual path with the global path
  ImageResources(String path) {
    this.path = basepath+path;
  }

  /** Loads, or just retrieves from cache, the image.
   *  @return Image (not necesarily a BufferedImage) or null on failure
  */
  public Image getImage() {
    //Lazy load...
    if(image==null) {
      //Since the .jar is constant (it's packed) we can
      //Remember the image is unavailable
      if(image_failed)
        return null;
      //Use whatever is stored in Icon if we have it
      if(icon!=null) {
        image = icon.getImage();
      }
      //Load from .jar
      else {
        try {
          image = ImageIO.read(leclass.getResourceAsStream("/images/grass.png"));
        }
        //While only IOException is reported it also can throw InvalidArgumentException
        // when read() argument is null
        catch(Exception e) {
          image_failed = true;
        }
      }
    }
    return image;
  }
}

Full version on GitHub. Can be subject to change.

Since this code doesn't work (due to invalid base path) I want to know a general way to find why are the resources not loading and where is the ClassLoader looking .

For example when I had problems loading normal file from filesystem, I could do this:

File relativePath = new File("../my_test_image.png");
System.out.println(relativePath.getAbsolutePath());

And I could immediately see where's Java looking and what should I change. If I as well as others know a simple way to do this with resources, all these questions wouldn't need to be asked:

So is there a way to print what does my resource path translate to?

What I tried:

So it seems you can always get the current path by this statement:

System.out.println("  Path: \""+loader.getResource(".")+"\"");

For me, this gives:

  Path: "file:/C:/... path to project .../PROJECT_NAME/target/test-classes/"

This is a path of the test class running the test, not the actual class loader it has been created for. I do not think this is a bug.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM