使用Java Runtime类在Unix中查找Jar文件中的类

时间:2014-06-26 05:27:39

标签: java unix

我正在使用Java Runtime类编写一个程序来检查jar文件列表中的类文件。这是我的计划:

import java.io.*;

public class JavaRunCommand {

    public static void main(String args[]) {

        String 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);
        }
    }
}

当我运行此程序时,我收到错误消息:

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]**

如果我在我的unix命令行上直接运行命令find /home/user/lib/ -name \"*.jar\" | xargs grep MyClass.class");,请帮助我在此代码中缺少的内容,然后它正常工作。

另外,如果我用下面的行替换表达式,那么我的Java代码工作正常。

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

2 个答案:

答案 0 :(得分:1)

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

将其更改为

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

以便shell参与并扩展通配符。

但是你真的不需要在这里运行find,你可以通过递归调用的Files.listFiles()自己完成。

我有兴趣看看你接下来要做什么。我会这样做,通过定义一个用{JARs列表初始化的URLClassLoader然后用它来尝试加载类,而不是自己解压缩所有JAR。

答案 1 :(得分:1)

如果所有的jar都在类路径上:

    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

要参加的详细信息:false表示不会进行课程初始化。

否则只有一个文件列表,可以使用JarFile。在Java 8中,您甚至可以使用并行性。