我正在运行这样一个外部jar插件:
Class<?> pluginClass = pluginLoader.loadClass(".......");
Method main = pluginClass.getMethod("main", String[].class);
main.invoke(null, new Object[] { new String[0] }); 效果很好。现在需要将插件控制台消息保存到字符串中。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos); // how to indicate System.out coming from JAR plugin
System.setOut(ps);
// how to connect ps with plugin only 但这段代码将所有控制台消息保存到字符串中。我不需要所有的应用程序消息。如何将来自这个加载jar的插件 messages......messages重定向到字符串中?
发布于 2019-09-14 18:41:34
我想出了解决办法:
public class CustomPrintStream extends PrintStream {
private String prefix;
public CustomPrintStream(String prefix, OutputStream out) {
super(out);
this.prefix = prefix;
}
@Override
public void println(String s) {
if(s.startsWith(prefix))
super.println(s);
else {
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
System.out.println(s);
System.setOut(this);
}
}
}这为您提供了在每个主程序的System.out.printlns中添加一个前缀的可能性,以便它们能够正常执行。没有前缀的(从您的插件)直接进入定义的外流(在我的例子中文件输出流)
它是这样使用的:
System.setOut(new CustomPrintStream("test", new FileOutputStream("C:\\out.txt"))); //Of course you can also use ByteArrayOutputStream, as you did before
System.out.println("test 1"); //this goes into the standard outstream
System.out.println("2"); //and this goes into the fileoutputstream
System.out.println("test 3");也许这会帮到你:)
编辑:,我把它转换成带前缀的字符串进入正常的外部流
发布于 2019-09-14 18:37:04
你不能按你的要求去做。流程中只有一个标准输出流,它与插件代码和代码共享。
您可以将插件代码作为一个单独的进程运行,并捕获输出流。您可以使用"java.home“系统属性查找启动进程的JRE的位置,并使用它形成命令行来启动插件jar。
请参阅https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html
发布于 2019-09-14 18:31:38
System.out是每个进程,没有办法在每个类加载程序中有不同的流。如果您迫切需要从插件中取出系统,有两个选项: 1.如果您对插件代码有访问权限,并使插件使用此流,则将输出流传递给您的插件。2.将插件作为外部进程运行。这样,您就可以重定向它的输出。另一种选择:如果您能够区分插件输出,您可以实现自己的路由输出流,并将其设置为系统输出。
https://stackoverflow.com/questions/57937898
复制相似问题