使用System.out.println语句检测java源文件?

时间:2009-06-02 14:51:43

标签: java debugging

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

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

提前致谢, PD

5 个答案:

答案 0 :(得分:6)

这是Aspect Oriented Programming的一个很好的用例。

答案 1 :(得分:1)

您可能没有找到太多内容,因为使用System.out将是一种非常可怕的方法来检测应用程序。

您打算做什么 - 分析性能,代码覆盖率等?如果是这样,那么有很多工具可供选择。

答案 2 :(得分:0)

我已经完成了之前遇到没有其他工作的情况。我实际上已经进入并且每当其他行使用正确的方法时插入一个sysout。

(例如,我刚刚在一个JVM上工作,其中RMI调用抛出一个异常被静默吃掉,调用线程无限期挂起!哦,当然,我们不能使用调试器。你怎么办?找到??)

无论如何,只运行一个在任何地方插入调试输出的程序都无济于事。分析输出页面时你会迷路。而是尝试将问题括起来并在那里手动插入输出线。

如果你的线程“消失”在一条线上或意外转弯,那么将该线分成最小的可运行部分,弄清楚哪一块失败,然后深入研究并重复 - 没有太多其他事情可做。

顺便说一句,另一个有用的工具 - 即使是在一个非常古老的JVM上,你可以随时抛出一个“(新的Exception())。printStackTrace();”在不影响程序流的情况下转储堆栈。如果你发现自己在某个地方并且不知道如何到达那里,这可能有所帮助。

最后,如果你想要非常懒,你可以使用一个静态方法来完成所有调试输出(一个只委托给System.out.println),并添加几行来获取堆栈跟踪,抓取只有“调用”行/方法并在调试语句之前将其打印出来,为您提供穷人的日志记录实用程序。

我从多年来在嵌入式平台上弄乱旧版Java的过程中学到的一些手动调试技巧。

答案 3 :(得分:0)

我同意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注释引用了切入点,并指定了一堆你想在函数周围执行的代码。在您的情况下,如果您只想登录正在调用的函数,则可以使用@Before或@AfterReturning替换@Around,具体取决于您希望记录的位置。如果您正在进行应用程序的所有构建,则需要“编译时编织”而不是加载时间。它降低了应用程序的运行时要求。

答案 4 :(得分:0)

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

查看http://www.slf4j.org/extensions.html#javaagent