尽管如此,应用程序开发人员似乎喜欢在各个地方使用 System.out.println 和 e.printStackTrace 调用,使得在运行容器时无法保持干净的控制台。
我该如何防止这些应用程序污染 System.out 和 System.err?
实现注意事项:
- 应用程序使用 Log4j 进行日志记录; - 容器也使用控制台进行日志记录,但严格保留用于生命周期事件和问题,因此我仍然需要控制台; - 应用程序使用自定义类加载器加载,但不应用任何安全检查。
更新:
简单地重定向 System.out 并不能起到作用,因为它会重定向所有输出,所以像这样的方式会失败:
System.setOut(new PrintStream(new OutputStream() {
@Override
public void write(int b) {
throw new Error("Not on my watch you don't");
}
}));
Logger logger = Logger.getLogger(Runner.class);
logger.info("My log message");
这应该会成功。
更新2:
类似以下代码的代码加载和配置应用程序:
App app = new UrlClassLoader(...).loadClass(className)).newInstance();
app.setLogger(loggerForClass(app));
Log4j是从系统类加载器中加载的。
System.out
(替换为log.debug()
),搜索System.err
(替换为log.info()
),搜索printStackTrace
(删除)。我甚至认为这可能已经自动化了,例如 svn(不确定如何实现,但我认为可以)。 - laurafork()
,重定向子进程的标准输出和标准错误,然后再使用exec()
,但我不确定在 Java 类加载器中的等效方法是什么。你能详细说明一下你是如何加载应用程序的吗? - Ted Kaplanlog4j
。 - Robert Munteanu