开发者

How to access resources in jar where it can be present in multiple jar

I have a project where I generate lots of code against many XSD. To keep things separate each set of XSD are bundled together within a project. I have multiple project that will see XSD in resources and generate code against them.

My problem is when I try to access the XSD that are stored in the jar files I cannot get the code to access the XSD from a perticular jar. Instead it will access the first XSD that matches the criterion regardless of the jar.

Here is the code I use to list the ressources, All the jars have the same structure meaning the XSDs are always stored in the xsd folder at the root of the jar file. The code below lists the XSD in the folder.

URL dirURL = clazz.getClassLoader().getResource(path);
  System.out.println(dirURL.toURI());
  if (dirURL != null && dirURL.getProtocol().equals("file")) {
   /* A file path: easy enough */
   System.out.println(dirURL.toURI());
  return new File(dirURL.toURI()).list();
  }

  if (dirURL == null) {
   /* 
    * In case of a jar file, we can't actually find a directory.
    * Have to assume the same jar as clazz.
    */
   String me = clazz.getName().replace(".", "/") + ".class";
   dirURL = clazz.getClassLoader().getResource(me);
   System.out.println(dirURL.toURI());
   System.out.println(me);
  }

  if (dirURL.getProtocol().equals("jar")) {
   /* A JAR path */
   String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); //strip out only the JAR file
   System.out.println(jarPath);
   JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
   Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
   Set<String> result = new HashSet<String>(); //avoid duplicates in case it is a subdirectory
   String name = null;
   while (entries.hasMoreElements()) {
    name = entries.nextElement().getName();
    if (name.startsWith(p开发者_C百科ath)) { //filter according to the path
     String entry = name.substring(path.length());
     int checkSubdir = entry.indexOf("/");
     if (checkSubdir >= 0) {
      // if it is a subdirectory, we just return the directory name
      entry = entry.substring(0, checkSubdir);
     }
     result.add(entry);
    }
   }
   return result.toArray(new String[result.size()]);


I usually make it a rule to add a resource directory into each JAR with resources that are unique to that JAR held under it. For example (in the Maven structure)

module1/src/main/resources/module1/example.xsd
module2/src/main/resources/module2/example.xsd

The XSDs are then referenced using

InputStream module1XSD= SomeClass.class.getResourceAsStream("/module1/example.xsd");
InputStream module2XSD= SomeClass.class.getResourceAsStream("/module2/example.xsd");

so long as the JARs for module1 and module2 have been placed on the classpath of the application containing SomeClass.

Spring contexts would reference these as

classpath:module1/example.xsd,
classpath:module2/example.xsd

This does mean that you'll have to be able to move the location of XSDs in the JARs that you generate. Maybe even regenerating them through a build script.


If the XSDs all have the same name, you will need another criteria with knowledge of what the "right one" is. Can you embed some information in it (or with it, like a properties file or something) indicating its purpose?

And, a more convenient iterator to get them might be:

 getClass().getClassLoader().getResources("/file.xsd");

or something. (Relies on the classpath, whether it is on the file system or in a jar)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜