How to Trace JVM Filesystem Accesses Using Java
Use a custom security manager as a low-overhead alternative to native tracers.
Join the DZone community and get the full member experience.Join For Free
For tracing filesystem accesses of Java applications, native tracing facilities are always the first choice. On Windows, use Process Monitor to trace I/O. On Linux, use strace. Other platforms provide similar facilities.
By tracing directly in Java, you can work around environment limitations. For example, strace is unavailable in a container that lacks the
CAP_SYS_PTRACE capability and the container host is not always accessible. Also, a potentially lighter-weight tracing mechanism comes handy for tracing in production environments.
To go the Java route, you can implement your own security manager by extending
java.lang.SecurityManager. This class provides
checkDelete methods that get called as soon as code attempts corresponding accesses.
A sample implementation:
For testing the sample, we use the Java compiler as our test subject. To enable the trace security manager, we set the appropriate system property and execute the command with a valid Java source file
The trace implementation works. We can even see class loading attempts. However, javac fails because permissions are missing. The reason is that, with the installation of the security manager via the system property, the default Java security policy is active and does not grant the required permission. To work around that, you can either provide a minimal custom policy or you can override the
checkPermission method with an empty implementation. In this case, I chose the minimal policy:
With the policy in place, we can retest:
This time around, we got a full filesystem access trace of javac. The security manager can also be enabled at runtime, which is useful if you cannot control the Java command line for whatever reason:
In that particular case, a custom policy is not necessary because the default policy is not active.
Using a security manager to trace filesystem accesses is certainly not the best option as details are missing that might be relevant to your debugging scenario, but it's a good compromise if you're out of alternatives and need to get things done or if low-overhead tracing is required.
Published at DZone with permission of George R. See the original article here.
Opinions expressed by DZone contributors are their own.