Comment accéder aux ressources dans jar où il peut être présent dans plusieurs jar

j'ai un projet où je génère beaucoup de code contre beaucoup de XSD. Pour garder les choses séparées, chaque ensemble de XSD est regroupé au sein d'un projet. J'ai plusieurs projets qui vont voir XSD dans les ressources et générer du code contre eux.

mon problème est que lorsque j'essaie d'accéder au XSD qui est stocké dans les fichiers jar, Je ne peux pas obtenir le code pour accéder au XSD à partir d'un pot en particulier. Au lieu de cela, il accédera au premier XSD qui correspond au critère indépendamment de la pot.

voici le code que j'utilise pour lister les ressources, Toutes les jarres ont la même structure, ce qui signifie que les XSD sont toujours stockés dans le dossier xsd à la racine du fichier jar. Le code ci-dessous liste le XSD dans le dossier.

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()]);
4
demandé sur Newtopian 2010-10-25 22:45:05

2 réponses

d'habitude je fais une règle pour ajouter un répertoire de ressources dans chaque pot avec des ressources qui sont uniques à ce pot tenu sous elle. Par exemple (dans la structure Maven)

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

les XSD sont alors référencés en utilisant

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

aussi longtemps que les bocaux des modules1 ET2 ont été placés sur le chemin de classe de la demande contenant une classe.

les contextes de ressort les référeraient comme

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

cela signifie que vous devrez être en mesure de déplacer L'emplacement de XSDs dans les bocaux que vous générez. Peut-être même les régénérer à travers un script de construction.

2
répondu Gary Rowe 2010-10-25 20:28:19

si les XSDs ont tous le même nom, vous aurez besoin d'un autre critère avec la connaissance de ce qu'est le" bon". Pouvez-vous y inclure des informations (ou avec, comme un fichier de propriétés ou quelque chose) indiquant son but?

et, un itérateur plus pratique pour les obtenir pourrait être:

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

ou quelque chose comme ça. (S'appuie sur classpath, que ce soit sur le système de fichiers ou dans un jar)

1
répondu Nate 2010-10-25 18:59:50