我正在寻找一种简单的方法(例如,单个脚本/批处理文件或简单程序)来检测一组Java源文件,以便每个方法在进入和退出时都添加了一个System.out.println语句。
我找不到这样的实用工具。我需要这个(以及为什么它必须处理源文件而不是.class文件)的原因是目标系统是嵌入式Java系统..
提前致谢, PD
答案 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发送记录器调用很简单。)