使用System.out.println语句插入java源文件?

使用System.out.println语句插入java源文件?,java,debugging,Java,Debugging,我正在寻找一种简单的方法(例如,一个脚本/批处理文件或一个简单的程序)来插入一组Java源文件,以便每个方法在入口和出口都有一个添加的System.out.println语句 我找不到这样的实用工具。我需要它的原因(以及它必须处理源文件而不是.class文件的原因)是目标系统是嵌入式Java系统 提前感谢,, pd您可能没有找到太多,因为使用System.out对应用程序进行检测是一种非常可怕的方法 您想做什么-分析性能、代码覆盖率等?如果是这样的话,这两者都有很多工具 这是一个非常好的使

我正在寻找一种简单的方法(例如,一个脚本/批处理文件或一个简单的程序)来插入一组Java源文件,以便每个方法在入口和出口都有一个添加的System.out.println语句

我找不到这样的实用工具。我需要它的原因(以及它必须处理源文件而不是.class文件的原因)是目标系统是嵌入式Java系统

提前感谢,,
pd

您可能没有找到太多,因为使用
System.out
对应用程序进行检测是一种非常可怕的方法

您想做什么-分析性能、代码覆盖率等?如果是这样的话,这两者都有很多工具


这是一个非常好的使用案例。

我以前在遇到其他方法都不起作用的情况时做过。实际上,一旦我找到了正确的方法,我每隔一行插入一个sysout

(例如,我刚刚在一个JVM上工作,其中引发异常的RMI调用被默默地吃掉,而调用线程只是无限期地挂起!哦,当然,我们不能使用调试器。你怎么会发现呢??)

无论如何,仅仅运行一个在任何地方插入调试输出的程序都不会有帮助。您将无法分析输出页面。相反,尝试将问题放在括号内,并手动在那里插入输出行

如果你的线程在一条线上“消失”了,或者发生了一个意外的转折,把这条线分成最小的可运行的部分,找出哪一部分失败了,然后潜入其中并重复——没什么别的事可做

顺便说一句,另一个有用的工具——即使在非常旧的JVM上,也可以在任何时候抛出“(new Exception()).printStackTrace();”,以转储堆栈而不影响程序流。如果你发现自己身处某个地点,却不知道自己是如何到达那里的,这会有所帮助

最后,如果你真的想变得懒惰,你可以使用一个静态方法来完成所有的调试输出(一个只委托给System.out.println的方法),并添加几行代码来获得堆栈跟踪,只抓取“调用”行/方法,在调试语句给你一个穷人的日志工具之前将其打印出来


这是我多年来在嵌入式平台上使用java旧版本所学到的一些手动调试技巧。

我同意Kees的观点,您应该使用面向方面的编程来自动将日志添加到每个函数中。我使用以下代码执行类似的计时操作:

import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.StopWatch;

@Aspect
public class ProfilingAspect {

    @Around("methodsToBeProfiled()")
    public Object profile(ProceedingJoinPoint pjp) throws Throwable {
        StopWatch sw = new StopWatch(pjp.getSignature().getClass().getSimpleName());
        try {
            sw.start(pjp.getSignature().getName());
            return pjp.proceed();
        } finally {
            sw.stop();
            LogFactory.getLog(pjp.getSignature().getClass()).debug(sw.shortSummary());
        }
    }

    @Pointcut("execution(public * *.*(..))")
    public void methodsToBeProfiled(){}
}

这几乎是您可以添加的最简单的方面。关键部分是切入点注释,它声明您希望将此方面应用于每个包中每个公共类的每个公共方法,无论其返回类型或输入参数如何。你可能想说得更具体些。@Around注释引用了切入点,并指定了一组您希望“围绕”函数执行的代码。在您的情况下,如果您只想在被调用的函数上进行日志记录,则可以根据您希望日志记录的位置,将@Around替换为@Before或@AfterReturning。如果您正在进行应用程序的所有构建,那么将目标定为“编译时编织”,而不是加载时。它降低了应用程序的运行时要求。

我已经为slf4j编写了一个扩展,它提供了您正在寻找的功能(除了作为记录器调用而不是System.out,但是向System.out发送记录器调用很简单)


看一看

我正在尝试对一个棘手的bug进行第一阶段分析-首先获取覆盖率信息,然后在相关位置添加更多打印输出,以查看其中的结果。我应该提到的是,我目前无法使用调试器单步执行代码(系统的调试支持暂时中断),因此必须依赖打印输出。我很清楚这是一种可怕的方法,但我还是想尝试一下。在这种情况下,也许您可以在每次方法调用时使用某种AOP来交织建议,以便在之前/之后打印语句?不确定这是否是嵌入式设备的一个选项。在这种情况下,您仍然应该查看log4j,而不是System.out.println()。不会帮助您自动插入,但一旦这些行出现,您将获得更多的控制权。。。与日志(log4j)一起使用,而不是使用“System.out.println”