我正在学习如何使用btrace。为此,我创建了一个包含以下代码的spring-boot项目。
@Controller
public class MainController {
private static Logger logger = LoggerFactory.getLogger(MainController.class);
@ResponseBody
@GetMapping("/testFile")
public Map<String, Object> testFile() throws IOException {
File file = new File("/tmp/a");
if (file.exists()) {
file.delete();
}
file.createNewFile();
return ImmutableMap.of("success", true);
}
}
然后,我使用mvn spring-boot:run
开始了该项目,然后编写了btrace脚本,如下所示。
import com.sun.btrace.annotations.*;
import com.sun.btrace.BTraceUtils;
@BTrace
public class HelloWorld {
@OnMethod(clazz = "java.io.File", method = "createNewFile")
public static void onNewFileCreated(String fileName) {
BTraceUtils.println("New file is being created");
BTraceUtils.println(fileName);
}
}
如您所见,该脚本应在调用java.io.File#createNewFile
时打印一些内容,而上述控制器正是这样做的。然后,使用以下代码将btrace附加到正在运行的spring-boot项目中。
btrace 30716 HelloWorld.java
30716是正在运行的spring-boot项目的PID。然后,我尝试访问http://localhost:8080/testFile
,然后从正在运行的spring-boot项目中获得以下额外输出。
objc[30857]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/java (0x10e2744c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1145e24e0). One of the two will be used. Which one is undefined.
2019-01-04 11:24:49.003 INFO 30857 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-01-04 11:24:49.003 INFO 30857 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-01-04 11:24:49.019 INFO 30857 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 16 ms
我期望它输出New file is being created
,但没有。为什么?我做错什么了吗?
答案 0 :(得分:0)
您的跟踪方法onNewFileCreated(String fileName)
不能用于截获java.io.File.createNewFile()
,因为签名不同意(createNewFile()
不接受任何参数,而onNewFileCreated()
具有一)。如果trace方法中有参数(除非它们具有BTrace批注),则BTrace将尝试将其“绑定”到截获方法中的参数。如果无法这样做,将无法成功拦截该方法。
尝试
@OnMethod(clazz = "java.io.File", method = "createNewFile")
public static void onNewFileCreated() {
BTraceUtils.println("method createNewFile called");
}
或
@OnMethod(clazz = "java.io.File", method = "createNewFile")
public static void onNewFileCreated(@ProbeMethodName String methodName) {
BTraceUtils.println("method " + methodName + " called");
}
更新1:
首先,您正在使用什么版本的JDK? BTrace似乎不支持JDK> 8(https://github.com/btraceio/btrace/issues/292)。
第二,您可以尝试运行此跟踪脚本吗?
import com.sun.btrace.annotations.*;
import com.sun.btrace.BTraceUtils;
@BTrace
public class TracingScript {
@OnMethod(clazz = "java.io.File", method = "createNewFile")
public static void onNewFileCreated(@ProbeMethodName String methodName) {
BTraceUtils.println("method " + methodName + " called");
}
}
针对一个简单的测试应用程序:
import java.io.File;
public class FileCreator {
public static void main(String[] args) throws Exception{
for(int i = 0; i < 250; i++) {
File file = new File("C://Temp//file" + i);
if (file.exists()) {
file.delete();
}
file.createNewFile();
Thread.sleep(10000);
}
}
}
这对我来说适用于BTrace 1.3.11.3(以及通过BTrace Workbench JVisualVM插件0.6.8,这是我通常使用的BTrace)。