ResouceUtils. getFile () cannot obtain the source code Summary of Chinese source files in Jar,

Source: Internet
Author: User

ResouceUtils. getFile () cannot obtain the source code Summary of Chinese source files in Jar,

Spring provides a tool class that can load files under classpath. In general, there is no problem, however, when it is used as a tool in the common jar package to load files in the jar package, an error is reported that the file cannot be found.

Click to see the source code of this tool class ResouceUtils. getFile:

public static File getFile(String resourceLocation) throws FileNotFoundException {        Assert.notNull(resourceLocation, "Resource location must not be null");        if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) {            String path = resourceLocation.substring(CLASSPATH_URL_PREFIX.length());            String description = "class path resource [" + path + "]";            ClassLoader cl = ClassUtils.getDefaultClassLoader();            URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path));            if (url == null) {                throw new FileNotFoundException(description +                        " cannot be resolved to absolute file path because it does not exist");            }            return getFile(url, description);        }        try {            // try URL            return getFile(new URL(resourceLocation));        }        catch (MalformedURLException ex) {            // no URL -> treat as file path            return new File(resourceLocation);        }    }

After reading the code structure, the logic is simple and clear, and there may be two problems: marked red. here, my first impression is that the class loader did not load resources. debug cl. the Class Loader used for getResource (path) is

WebAppClassLoader: I want to take a look at the internal implementation, but I won't go in here. Then Baidu finds that this is Jetty's own ClassLoader, intercepting some key loading source code:

public void addJars(Resource lib)  {      if (lib.exists() && lib.isDirectory())      {          String[] files=lib.list();        for (int f=0;files!=null && f<files.length;f++)  {              try {                  Resource fn=lib.addPath(files[f]);                String fnlc=fn.getName().toLowerCase();                  if (fnlc.endsWith(".jar") || fnlc.endsWith(".zip"))  {                      String jar=fn.toString();                        jar=StringUtil.replace(jar, ",", "%2C");                      jar=StringUtil.replace(jar, ";", "%3B");                      addClassPath(jar);                  }              }  catch (Exception ex) {                  Log.warn(Log.EXCEPTION,ex);              }          }      }  } 

The above section adds the jar and zip path to some source code in the class loader path. Continue to debug to get

URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path));

The above url result:

 

Actually, the file path to be loaded is obtained. Because the protocol field in the jar package is identified as jar. it does not appear that the classloader causes file loading failure. so proceed to debug and look at the source code of getFile:

public static File getFile(URL resourceUrl, String description) throws FileNotFoundException {        Assert.notNull(resourceUrl, "Resource URL must not be null");        if (!URL_PROTOCOL_FILE.equals(resourceUrl.getProtocol())) {  //URL_PROTOCOL_FILE="file"            throw new FileNotFoundException(                    description + " cannot be resolved to absolute file path " +                    "because it does not reside in the file system: " + resourceUrl);        }        try {            return new File(toURI(resourceUrl).getSchemeSpecificPart());        }        catch (URISyntaxException ex) {            // Fallback for URLs that are not valid URIs (should hardly ever happen).            return new File(resourceUrl.getFile());        }    }

This is a bit speechless. The red text above actually determines whether the resource path protocol is file. Because in the jar package, the Protocol is jar, therefore, an exception not found in the file is directly thrown here,

I suddenly felt so stupid. After debugging for so long, I had to handle the class loading process again. In fact, the problem was a very simple problem, ResouceUtils. getFile () is a dedicated resource used to load non-compressed and Jar package file types, so it does not

To load the files in Jar, you only need to load the files in Jar by reading the files in jar, such as xx. class. getClassLoader (). getResouceAsStream () is a stream-based file reading method.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.