Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在大型Java程序中查找System.out的错误输出_Java_Console_Debugging - Fatal编程技术网

在大型Java程序中查找System.out的错误输出

在大型Java程序中查找System.out的错误输出,java,console,debugging,Java,Console,Debugging,我们有一个庞大的java代码库[~1M行] 代码库中的某个地方隐藏着一些我们想要删除的System.out的旧调试输出(它的混乱) 问题是:我们的代码库太大了,我们很难找到输出的来源。我们想要的是一种查看调用System.out.println的位置的方法(比如异常或类似事件的堆栈跟踪) 它不适合调试——错误的输出来自某个错误的线程等 关于如何追踪这个错误输出的来源有什么想法吗 PS:99.99%的System.out调用是合法的,我们有数千个这样的调用,所以简单地在代码库中搜索System.o

我们有一个庞大的java代码库[~1M行]

代码库中的某个地方隐藏着一些我们想要删除的System.out的旧调试输出(它的混乱)

问题是:我们的代码库太大了,我们很难找到输出的来源。我们想要的是一种查看调用System.out.println的位置的方法(比如异常或类似事件的堆栈跟踪)

它不适合调试——错误的输出来自某个错误的线程等

关于如何追踪这个错误输出的来源有什么想法吗


PS:99.99%的System.out调用是合法的,我们有数千个这样的调用,所以简单地在代码库中搜索System.out调用并不是一个解决方案

有一个
System.setOut()
方法。如果你真的很绝望,把它设置为真正的stdout的包装器,然后在你的包装器中做任何事情。例如,将写入的字符串与某个内容进行比较,如果输出错误,则抛出。

使用AspectJ,您可以轻松打印调用System.out的类的签名

下面是TraceSpect将提供的一个简单示例。重要的部分是该类位于演示包中,并调用System.out。该特性还将通知演示包任何深度的子包中所有类对System.out的所有调用

package demo;

public class DemoClass {

    public void demo() {
        System.out.println("inside demo method..");
    }

    public static void main(String[] args) {
        new DemoClass().demo();
    }
}
要在调用System.out之前打印包和类名,可以添加如下方面:

@Aspect
public class TraceAspect {

    @Pointcut("call(* java.io.PrintStream.*(..))")
    public void sysoutPointcut() {
    }

    @Pointcut("within(demo..*)")
    public void packagePointcut() {
    }

    @Before("sysoutPointcut() && packagePointcut()")
public void beforeSysoutCallInsideDemoPackage(JoinPoint joinPoint) {
    System.out.print(joinPoint.getThis().getClass().getName() + ":"
            + joinPoint.getSourceLocation().getLine() + " - ");
}
}
在DemoClass中执行main方法的输出为:

demo.DemoClass:6 - inside demo method..
使用Eclipse和AspectJ插件,您可以右键单击项目,然后单击配置-->转换为AspectJ项目。那么上面的代码就可以工作了


我已经用@AspectJ风格写了更多关于AspectJ的文章。

我认为这是完全正确的。创建自己的流,并在出现令人不快的消息时创建流。只需打印堆栈跟踪:new RuntimeException().printStackTrace();回答得好!它不需要真正的绝望-我认为它可以在几分钟内完成。@SvrGuy:您可以用适当的日志调用替换所有的System.out.println,这样您就知道它们是从哪里调用的。您还可以通过在System.out.println调用中添加类名来替换所有System.out调用。这两项都可以通过使用一些脚本语言轻松完成(一些脚本技能对于任何程序员来说都是必需的,但我离题了)。在那里,我已经完成了:我已经用一个100 KLOC Java代码库上的Un*x Bash shell脚本自动正确地记录来替换所有System.out.println。@SvrGuy:使用一个shell脚本,并结合使用诸如find、sed和awk之类的工具,这有点困难,但你可以控制一切都不会出错。基本上,我会使用find来查找每个.java文件,在每个文件中,我会用System.out.println(用System.out.println(“.java_file_name”)替换开始的行(忽略制表符/空格)“.见鬼,如果你使用的是很酷的DVCS,你可以在一瞬间克隆出大约1M的代码库,在fork中找到最坏的违规者,然后在“真实”代码库中删除最坏的违规者,确保你没有弄乱任何东西。”。