【问题标题】:Console output not working after method call方法调用后控制台输出不起作用
【发布时间】:2014-01-20 20:45:34
【问题描述】:

我目前正在开发一个基于某些模板文件生成和验证 .xml 文件的应用程序。

我调用生成这些文件的方法如下:

FtlProcessingController ctrl = new FtlProcessingController();
ctrl.process(TEMPLATES, OUTPUT_DIRECTORY, root, metadata);

我不是这个FtlProcessingController类的作者,但是process方法基本上是从TEMPLATES目录中获取模板文件,填充它们与 root 对象(Answer 对象的树)和 metadata 对象(附加数据的映射)中的内容,并将 .xml 文件输出到 OUTPUT _ 目录

简单来说,主要代码如下:

// Prepare files and data

FtlProcessingController ctrl = new FtlProcessingController();
ctrl.process(TEMPLATES, OUTPUT_DIRECTORY, root, metadata);

// Validate XML files

问题是process调用后的任何控制台输出都不起作用;控制台中没有任何显示。

我尝试使用一些测试输出来围绕呼叫并保存 PrintStream 以进行重置:

System.out.println("Console");
PrintStream stdOut = System.out;

FtlProcessingController ctrl = new FtlProcessingController();
ctrl.process(TEMPLATES, OUTPUT_DIRECTORY, root, metadata);

// Test Exception was thrown here.

System.setOut(stdOut);
System.out.println("Console again");

但我只得到:

控制台

我确定在此调用中没有无限循环System.exit(),因为文件已成功生成。我什至尝试在调用后立即抛出 Exception 以确认这一点,并且异常被正常抛出。

我的问题是:独立于 process 方法对 System.out 做什么或不做什么,我不应该这样做吗?可以在System.setOut(stdOut) 调用后在控制台上再次打印吗?

什么可能会弄乱标准输出,导致保存的 PrintStream 不起作用?

谢谢!

完整的主要代码,好奇的人:

public static void main(String[] args) {
    try {
        // Parse answers
        Answer root = AnswerUtils.fromJSON(JSON_FILE, Answer.class);

        ModuleInfo manager = new SimpleModuleInfo(MODULE_MANAGER_ID, MODULE_MANAGER_CATEGORY, MODULE_MANAGER_NAME,
                MODULE_MANAGER_VERSION, MODULE_MANAGER_VERSION);
        ModuleInfo module = new SimpleModuleInfo(MODULE_ID, MODULE_CATEGORY, MODULE_NAME, MODULE_VERSION, INSTANCE);

        List<ModuleInfo> info = new ArrayList<ModuleInfo>();
        info.add(manager);
        info.add(module);
        if (DEPENDENCIES_FILES != null) {
            // property file, with all dependencies as a comma-separated value under the 'dependencies' key
            Properties props = new Properties();
            InputStream in = null;
            try {
                in = new FileInputStream(DEPENDENCIES_FILES);
                props.load(in);
            } finally {
                IOUtils.closeQuietly(in);
            }
            String[] values = StringUtils.split(props.getProperty("dependencies"), ',');
            if (values != null) {
                for (String value : values) {
                    ModuleDependency dep = new ModuleDependency(StringUtils.trim(value));
                    info.add(new SimpleModuleInfo(dep.getIdentifier(), "Category", WordUtils.capitalizeFully(
                            dep.getIdentifier(), new char[] { '-' }), dep.getVersion().toString(), dep
                            .isInstanceDependency() ? module.getInstance() : "Default"));
                }
            }
        }
        Map<String, Object> metadata = getMetadata(HOME, os, arch, module, info.toArray(new ModuleInfo[info.size()]));

        System.out.println("Console");
        PrintStream stdOut = System.out;

        FtlProcessingController ctrl = new FtlProcessingController();
        ctrl.process(TEMPLATES, OUTPUT_DIRECTORY, root, metadata);

        System.setOut(stdOut);
        System.out.println("Console again");

        // Validate XML
        Collection<File> xmlFiles = FileUtils.listFiles(OUTPUT_DIRECTORY, OUTPUT_FILES_EXTENSIONS, WITH_SUBDIRECTORIES);
        for (File file : xmlFiles) {
            System.out.println(file.getAbsolutePath());
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(false);
            factory.setNamespaceAware(true);
            factory.setFeature(FACTORY_DTD_FEATURE, false);

            SAXParser parser = factory.newSAXParser();

            XMLReader reader = parser.getXMLReader();
            reader.setErrorHandler(new SPErrorHandler());
            reader.parse(file.getAbsolutePath());
        }
        if(true)
            throw new IOException();
    } catch (SAXException se) {
        se.printStackTrace();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    } catch (ParserConfigurationException pce) {
        pce.printStackTrace();
    }
}

【问题讨论】:

  • 如果在打印“Console again”后刷新输出流会发生什么?
  • 如果不了解FtlProcessingController 的更多信息,将很难提供帮助。
  • 您调用的方法可能会重新分配 System.out 流。如果是这种情况并且输出在 Java 控制台中不再可见,则输出可能已写入日志文件。然而,这种记录日志的方法是一个非常糟糕的主意,不应该这样做。一个比这更糟糕的想法是实际关闭 System.out 流。您是否可以访问 FtlProcessingController 类的源代码?
  • @Kallja 我刚刚和我的同事一起潜入了 FtlProcessingController,我们实际上发现 System.out 在里面的某个地方被关闭了,就像你说的那样。我什至不知道这样的事情是可能的,现在合作起来很尴尬......
  • @AlexisLeclerc 好吧,那么我将发表我的评论作为答案,如果您不介意,您可以接受。我内心的业力-wh ***得到快乐上床睡觉。 :)

标签: java console output printstream


【解决方案1】:

您调用的方法可能会重新分配System.out 流,这可以通过System.setOut(PrintStream) 方法完成。

如果是这种情况并且输出在 Java 控制台中不再可见,则可能是输出已写入日志文件。然而,这种记录日志的方法是一个非常糟糕的主意,不应该这样做,尤其是在其他人可能最终使用的库中。

一个比这更糟糕的想法是实际关闭System.out 流。我想不出有什么场景可以证明这样做是合理的。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-19
  • 1970-01-01
相关资源
最近更新 更多