Java 如何访问jar中可以存在于多个jar中的资源

Java 如何访问jar中可以存在于多个jar中的资源,java,jar,Java,Jar,我有一个项目,我针对许多XSD生成了大量代码。为了使事情保持独立,每个XSD集都被捆绑在一个项目中。我有多个项目可以在参考资料中看到XSD,并根据它们生成代码 我的问题是,当我试图访问存储在jar文件中的XSD时,我无法获得从特定jar访问XSD的代码。相反,它将访问与标准匹配的第一个XSD,而不考虑jar 下面是我用来列出ressources的代码,所有jar都具有相同的结构,这意味着xsd总是存储在jar文件根目录下的xsd文件夹中。下面的代码列出了文件夹中的XSD URL dirURL =

我有一个项目,我针对许多XSD生成了大量代码。为了使事情保持独立,每个XSD集都被捆绑在一个项目中。我有多个项目可以在参考资料中看到XSD,并根据它们生成代码

我的问题是,当我试图访问存储在jar文件中的XSD时,我无法获得从特定jar访问XSD的代码。相反,它将访问与标准匹配的第一个XSD,而不考虑jar

下面是我用来列出ressources的代码,所有jar都具有相同的结构,这意味着xsd总是存储在jar文件根目录下的xsd文件夹中。下面的代码列出了文件夹中的XSD

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(path)) { //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()]);
URL dirURL=clazz.getClassLoader().getResource(路径);
System.out.println(dirURL.toURI());
if(dirURL!=null&&dirURL.getProtocol().equals(“文件”)){
/*文件路径:非常简单*/
System.out.println(dirURL.toURI());
返回新文件(dirURL.toURI()).list();
}
if(dirURL==null){
/* 
*对于jar文件,我们实际上找不到目录。
*必须假设与clazz相同的罐子。
*/
字符串me=clazz.getName().replace(“.”,“/”)+“.class”;
dirURL=clazz.getClassLoader().getResource(me);
System.out.println(dirURL.toURI());
System.out.println(me);
}
if(dirURL.getProtocol().equals(“jar”)){
/*罐子路径*/
String jarPath=dirURL.getPath().substring(5,dirURL.getPath().indexOf(!”);//只去掉JAR文件
System.out.println(jarPath);
JarFile jar=新的JarFile(urldecker.decode(jarPath,“UTF-8”);
枚举条目=jar.entries();//给出jar中的所有条目
Set result=new HashSet();//如果是子目录,请避免重复
字符串名称=null;
while(entries.hasMoreElements()){
name=entries.nextElement().getName();
if(name.startsWith(path)){//根据路径进行筛选
String entry=name.substring(path.length());
int checkSubdir=entry.indexOf(“/”);
如果(checkSubdir>=0){
//如果它是一个子目录,我们只返回目录名
entry=entry.substring(0,checkSubdir);
}
结果。添加(条目);
}
}
返回result.toArray(新字符串[result.size()]);

如果XSD都有相同的名称,您将需要了解“正确的一个”是什么的另一个条件。您可以在其中嵌入一些指示其用途的信息(或使用它,如属性文件或其他内容)吗

更方便的迭代器可能是:

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

(取决于类路径,无论是在文件系统中还是在jar中)

我通常会将资源目录添加到每个jar中,其中包含该jar所特有的资源。例如(在Maven结构中)

然后使用

InputStream module1XSD= SomeClass.class.getResourceAsStream("/module1/example.xsd");
InputStream module2XSD= SomeClass.class.getResourceAsStream("/module2/example.xsd");
只要module1和module2的jar被放置在包含SomeClass的应用程序的类路径上

Spring上下文将这些引用为

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

这意味着您必须能够在生成的jar中移动XSD的位置。甚至可以通过构建脚本重新生成它们。

我这里最大的问题是,我没有访问XSD的权限(它们是提供的,所以我必须按原样使用它们)。而且,在许多情况下,xsd确实有相同的名称。我认为,通过提供一个我知道与所需xsd位于同一jar文件中的类,我将能够获取在该特定jar上的类加载器,但毫无用处。
classpath:module1/example.xsd,
classpath:module2/example.xsd