应用自定义平安管理器作为本机跟踪程序的低开销代替办法。

对于跟踪Java应用程序的文件系统拜访,本机跟踪工具始终是首选。在Windows上,应用Process Monitor跟踪I / O。在Linux上,应用strace。其余平台也提供相似的性能。

通过间接在Java中进行跟踪,您能够解决环境限度。例如,在短少该CAP_SYS_PTRACE性能的容器中strace不可用,并且容器主机并非始终可拜访。此外,潜在的更轻量的跟踪机制可不便地在生产环境中进行跟踪。

要走Java路线,您能够通过扩大来实现本人的平安管理器java.lang.SecurityManager。此类提供了checkRead,checkWrite和checkDelete办法,一旦代码尝试进行相应的拜访,它们就会被调用。

一个示例实现:

public class TraceSecurityManager extends SecurityManager {  public void checkRead(String file) {    System.out.println("Read: " + file);    super.checkRead(file);  }  public void checkRead(String file, Object context) {    System.out.println("Read: " + file);    super.checkRead(file, context);  }  public void checkWrite(String file) {    System.out.println("Write: " + file);    super.checkWrite(file);  }  public void checkDelete(String file) {    System.out.println("Delete: " + file);    super.checkDelete(file);  }}

为了测试样本,咱们应用Java编译器作为测试对象。为了启用跟踪平安管理器,咱们设置适当的零碎属性,并应用无效的Java源文件执行命令Test.java:

$ java -Djava.security.manager=TraceSecurityManager com.sun.tools.javac.Main Test.javaRead: /home/user/com/sun/tools/javac/resources/spi/compilerProvider.classRead: /home/user/com/sun/tools/javac/resources/compiler_en.propertiesRead: /home/user/com/sun/tools/javac/resources/compiler_en_US.propertiesException in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getenv.JDK_JAVAC_OPTIONS")        at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)        at java.base/java.security.AccessController.checkPermission(AccessController.java:897)        at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:322)        at java.base/java.lang.System.getenv(System.java:999)        at jdk.compiler/com.sun.tools.javac.main.CommandLine.appendParsedEnvVariables(CommandLine.java:252)        at jdk.compiler/com.sun.tools.javac.main.CommandLine.parse(CommandLine.java:99)        at jdk.compiler/com.sun.tools.javac.main.CommandLine.parse(CommandLine.java:123)        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:215)        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:170)        at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:57)        at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:43)

跟踪实现无效。咱们甚至能够看到类加载尝试。然而,javac失败,因为短少权限。起因是,通过system属性装置平安管理器后,默认的Java安全策略处于活动状态,并且未授予所需的权限。要解决此问题,您能够提供起码的自定义策略,也能够checkPermission应用空的实现笼罩该办法。在这种状况下,我抉择了最小策略:

grant {  permission java.security.AllPermission "", "";};

有了适当的政策,咱们能够从新测试:

$ java -Djava.security.policy=test.policy -Djava.security.manager=TraceSecurityManager com.sun.tools.javac.Main Test.javaRead: /home/user/com/sun/tools/javac/resources/spi/compilerProvider.classRead: /home/user/com/sun/tools/javac/resources/compiler_en.propertiesRead: /home/user/com/sun/tools/javac/resources/compiler_en_US.propertiesRead: Test.javaRead: Test.javaRead: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/modulesRead: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/modulesRead: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/jfxrt.jarRead: /home/user/META-INF/services/java.nio.file.spi.FileSystemProviderRead: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/modulesRead: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/modulesRead: Test.javaRead: /home/user/Test.javaRead: ./.bash_logoutRead: /home/user/.bash_logoutRead: ./.bash_profileRead: /home/user/.bash_profileRead: ./.bashrcRead: /home/user/.bashrc[...]Read: /home/user/com/sun/tools/javac/resources/spi/ctProvider.classRead: /home/user/com/sun/tools/javac/resources/ct_en.propertiesRead: /home/user/com/sun/tools/javac/resources/ct_en_US.propertiesRead: /home/user/TraceSecurityManager.classRead: /home/user/Test.classRead: /home/userWrite: /home/user/Test.classRead: Test.java

这次,咱们取得了残缺的javac文件系统拜访跟踪。还能够在运行时启用安全性管理器,如果因为某种原因而无法控制Java命令行,这将十分有用:

System.setSecurityManager(new TraceSecurityManager());

在这种特定状况下,因为默认策略未处于活动状态,因而不须要自定义策略。
学习材料收费支付群:3907814
应用平安管理器来跟踪文件系统拜访必定不是最好的抉择,因为可能短少与调试计划相干的详细信息,然而如果您没有其余抉择并且须要实现工作或开销很小,则这是一个很好的折衷方案。跟踪是必须的。