调用KeyTool,重定向System.out无效

时间:2014-03-31 15:45:11

标签: java keytool

因此,我们希望使用随JRE一起提供的bog标准keytool实用程序。但是,不是经历找到正确的路径和可执行扩展,产生子进程和运行可执行文件的麻烦,我们总体上有一个好主意("记住,我们没有人像我们所有人一样愚蠢!& #34;)直接调用KeyTool' main()。它是用Java代码实现的,也随JRE一起提供,并包含标准"类路径" GPL的例外,所以我们可以链接它。

看看KeyTool的来源,甚至还有一些针对这类事情做出的规定:有一些评论,比如"如果你直接在你的电话中调用KeyTool.main()自己的Java程序,然后是[有用的提醒]" ,顶级main()能够将异常传播到调用代码而不是仅仅使用System.exit()死亡。能够只构建相同的命令行参数数组并运行KeyTool.main(stuff)而不必混淆平台差异似乎是一个非常Java的事情,对吗?

在实践中,奇怪的事情发生了,我们不知道为什么。

我们希望捕获运行KeyTool的任何输出,它从这样开始:

// jdk/src/share/classes/sun/security/tools/KeyTool.java, line 331:
public static void main(String[] args) throws Exception {
    KeyTool kt = new KeyTool();
    kt.run(args, System.out);
}

private void run(String[] args, PrintStream out) throws Exception {
    // real code here, sends to 'out'
}

KeyTool入口点不允许我们传递PrintStream,它已硬编码以使用System.out。这应该没问题,感谢System.setOut。我们有一个OutputStream子类,它提供给JTextComponent,但是对于初始编码,重定向到文本文件很好。所以我们的代码

PrintStream orig = System.out;
try {
    System.out.println("This is the last visible console line");
    System.setOut(new PrintStream("redirect_test.txt"));
    System.out.println("This is now redirected!");
    KeyTool.main(keytool_argv);  // "-help" and "-debug" for now
}
catch all the myriad ways things might go wrong { ... }
finally {
    System.setOut(orig);
    System.out.println("Back to normal console output");
}

但是当我们运行代码时,redirect_test.txt文件只包含"现在重定向!"。 keytool" -help"的输出仍显示在控制台上,以及之前和之后的println调用。

在直接调用KeyTool时还有其他一些奇怪之处,比如Java 7和Java 8之间的包和类名已经改变,但通过反射很容易处理。 (Java 8中的KeyTool源代码中的注释仍然是指Java 7的名称,呵呵。)唯一奇怪的是它的" System.out"奇怪的是,不会受到在其他地方工作的相同重定向的影响。 (不,没有奇怪的导入语句带来特殊的系统替换。)

如果你碰巧没有OpenJDK坐在那里,那么an online copy of Java 7's KeyTool.java

1 个答案:

答案 0 :(得分:1)

您只需要重定向System.outSystem.err,因为使用说明会打印到标准错误流而不是标准输出流。试试这个:

PrintStream original = System.out;
PrintStream redirected = new PrintStream("redirect_test.txt")
try {
    System.out.println("This is the last visible console line");
    System.setOut(redirected);
    System.setErr(redirected);
    System.out.println("This is now redirected!");
    KeyTool.main(keytool_argv);  // "-help" and "-debug" for now
}
catch all the myriad ways things might go wrong { ... }
finally {
    System.setOut(original);
    System.setErr(original);
    System.out.println("Back to normal console output");
}