繁体   English   中英

如何从类加载器加载的jar中获取系统控制台?

[英]How to get System out console from a jar loaded by a class loader?

我正在运行这样的外部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 

但是此代码将所有控制台消息保存到String中。 我不需要所有应用程序消息。 如何将仅插件消息重定向……此加载的jar中的消息到字符串中?

你不能做什么。 在此过程中,只有一个标准输出流,并且与插件代码和您的代码共享。

您可以将插件代码作为一个单独的过程运行,并捕获输出流。 您可以使用“ java.home”系统属性来找到启动您的进程的JRE的位置,并使用它来形成一个命令行来启动插件jar。

参见https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html

System.out是针对每个进程的,每个类加载器都无法拥有不同的流。 如果您迫切需要从插件中取出系统,则有两种选择:1.如果您有权访问其代码,则将输出流传递给您的插件,并使插件使用此流。 2.将插件作为外部进程运行。 这样,您将能够重定向其输出。 另一个选择:如果您可以区分插件输出,则可以实现自己的路由输出流并将其设置为系统输出。

我做了这个解决方法:

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添加一个前缀,以便它们可以正常执行。 没有前缀的插件(来自您的插件)直接进入已定义的输出流(在我的示例中为fileoutputstream)

它的用法如下:

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");

也许这会帮助您:)

编辑:我切换它,以便带有前缀的字符串进入正常的外流

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM