Utilisation de la classe Java Runtime pour trouver une classe dans un fichier Jar sous Unix

J’utilise la classe Java Runtime pour écrire un programme qui recherche un fichier de classe dans une liste de fichiers jar. Voici mon programme:

import java.io.*; public class JavaRunCommand { public static void main(Ssortingng args[]) { Ssortingng s = null; try { Process p = Runtime.getRuntime().exec("find /home/user/lib/ -name \"*.jar\" | xargs grep MyClass.class"); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); // read the output from the command System.out.println("Here is the standard output of the command:\n"); while ((s = stdInput.readLine()) != null) { System.out.println(s); } // read any errors from the attempted command System.out.println("Here is the standard error of the command (if any):\n"); while ((s = stdError.readLine()) != null) { System.out.println(s); } System.exit(0); } catch (IOException e) { System.out.println("exception.."); e.printStackTrace(); System.exit(-1); } } } 

Lorsque je lance ce programme, je reçois un message d’erreur comme suit:

 Here is the standard output of the command: Here is the standard error of the command (if any): **find: paths must precede expression: | Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]** 

Aidez-moi s’il vous plaît ce qui me manque dans ce code, si je lance directement la commande find /home/user/lib/ -name \"*.jar\" | xargs grep MyClass.class"); find /home/user/lib/ -name \"*.jar\" | xargs grep MyClass.class"); sur ma ligne de commande unix, cela fonctionne correctement.

De plus, si je remplace l’expression par la ligne ci-dessous, mon code Java fonctionne correctement.

 Process p1 = Runtime.getRuntime().exec(new Ssortingng[] { "/bin/sh", "-c", "cd /home/user/lib/ && find . -name \"*.jar\" | xargs grep MyClass.class" }); 

 Process p = Runtime.getRuntime().exec("find /home/user/lib/ -name \"*.jar"); 

Changer cela pour

 Process p = Runtime.getRuntime().exec("sh -c find /home/user/lib/ -name \"*.jar"); 

pour que le shell intervienne et développe le caractère générique.

Mais vous n’avez pas vraiment besoin de lancer la find ici, vous pouvez le faire vous-même avec Files.listFiles() appelé récursivement.

Je serais intéressé de voir ce que vous faites ensuite. Je le ferais en définissant un URLClassLoader initialisé avec cette liste de JAR, puis en l’utilisant pour essayer de charger la classe, plutôt que de décompresser tous les JAR moi-même.

Si tous les jars sont sur le chemin de classe:

  Class klazz = Class.forName("sun.security.ec.SunEC", false, ClassLoader.getSystemClassLoader()); CodeSource codeSource = klazz.getProtectionDomain().getCodeSource(); URL url = codeSource.getLocation(); System.out.println(url.toExternalForm()); file:/C:/Program%20Files/Java/jre7/lib/ext/sunec.jar 

Le détail à suivre: false signifie qu’aucune initialisation de classe n’a lieu.

Sinon, avec juste une liste de fichiers, on pourrait utiliser JarFile. Dans Java 8, vous pourriez même utiliser le parallélisme.