因此,我们希望使用随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。
答案 0 :(得分:1)
您只需要重定向System.out
和System.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");
}