[英]How to get System out console from a jar loaded by a class loader?
I am running an external jar plugin like this: 我正在运行这样的外部jar插件:
Class<?> pluginClass = pluginLoader.loadClass(".......");
Method main = pluginClass.getMethod("main", String[].class);
main.invoke(null, new Object[] { new String[0] });
It works great. 效果很好。 Now need to save the plugin console messages into a String
现在需要将插件控制台消息保存到字符串中
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
But this code saves ALL console messages into String. 但是此代码将所有控制台消息保存到String中。 I don't need all application messages.
我不需要所有应用程序消息。 How to redirect plugin only messages......messages coming from this loaded jar into the string?
如何将仅插件消息重定向……此加载的jar中的消息到字符串中?
You can't do what you are asking. 你不能做什么。 There is only one standard output stream in the process and it is shared with the plugin code and your code.
在此过程中,只有一个标准输出流,并且与插件代码和您的代码共享。
You could instead run the plugin code as a separate process and capture the output stream. 您可以将插件代码作为一个单独的过程运行,并捕获输出流。 You can use the "java.home" System Property to find the location of the JRE that launched your process and use that to form a command line to launch the plugin jar.
您可以使用“ java.home”系统属性来找到启动您的进程的JRE的位置,并使用它来形成一个命令行来启动插件jar。
See https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html 参见https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html
System.out is per process, no way to have different stream per class loader. System.out是针对每个进程的,每个类加载器都无法拥有不同的流。 If you desperately need to get the system out from plugin there are 2 options : 1. Pass output stream to your plugin if you have acces to its code and make plugin use this stream.
如果您迫切需要从插件中取出系统,则有两种选择:1.如果您有权访问其代码,则将输出流传递给您的插件,并使插件使用此流。 2. Run your plugin as external process.
2.将插件作为外部进程运行。 This way you will be able to redirect its output.
这样,您将能够重定向其输出。 Another option : if you can differentiate the plugins output, you can implement your own routing output stream and set it as system out.
另一个选择:如果您可以区分插件输出,则可以实现自己的路由输出流并将其设置为系统输出。
I made this workaround: 我做了这个解决方法:
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);
}
}
}
This offers you the possibility to add a prefix to each of you main program's System.out.printlns, so that they get executed normally. 这使您可以为每个主程序的System.out.printlns添加一个前缀,以便它们可以正常执行。 The ones without the prefix (from your plugin) get directly into the defined out-stream (in my example the fileoutputstream)
没有前缀的插件(来自您的插件)直接进入已定义的输出流(在我的示例中为fileoutputstream)
It is used like this: 它的用法如下:
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");
Maybe this will help you :) 也许这会帮助您:)
Edit: I switched it around so that the string with prefix goes into the normal outstream 编辑:我切换它,以便带有前缀的字符串进入正常的外流
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.