共计 3871 个字符,预计需要花费 10 分钟才能阅读完成。
应用自定义平安管理器作为本机跟踪程序的低开销代替办法。
对于跟踪 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.java
Read: /home/user/com/sun/tools/javac/resources/spi/compilerProvider.class
Read: /home/user/com/sun/tools/javac/resources/compiler_en.properties
Read: /home/user/com/sun/tools/javac/resources/compiler_en_US.properties
Exception 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.java
Read: /home/user/com/sun/tools/javac/resources/spi/compilerProvider.class
Read: /home/user/com/sun/tools/javac/resources/compiler_en.properties
Read: /home/user/com/sun/tools/javac/resources/compiler_en_US.properties
Read: Test.java
Read: Test.java
Read: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/modules
Read: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/modules
Read: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/jfxrt.jar
Read: /home/user/META-INF/services/java.nio.file.spi.FileSystemProvider
Read: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/modules
Read: /usr/lib/jvm/java-11-openjdk-11.0.10.0.9-1.el7_9.x86_64/lib/modules
Read: Test.java
Read: /home/user/Test.java
Read: ./.bash_logout
Read: /home/user/.bash_logout
Read: ./.bash_profile
Read: /home/user/.bash_profile
Read: ./.bashrc
Read: /home/user/.bashrc
[...]
Read: /home/user/com/sun/tools/javac/resources/spi/ctProvider.class
Read: /home/user/com/sun/tools/javac/resources/ct_en.properties
Read: /home/user/com/sun/tools/javac/resources/ct_en_US.properties
Read: /home/user/TraceSecurityManager.class
Read: /home/user/Test.class
Read: /home/user
Write: /home/user/Test.class
Read: Test.java
这次,咱们取得了残缺的 javac 文件系统拜访跟踪。还能够在运行时启用安全性管理器,如果因为某种原因而无法控制 Java 命令行,这将十分有用:
System.setSecurityManager(new TraceSecurityManager());
在这种特定状况下,因为默认策略未处于活动状态,因而不须要自定义策略。
学习材料收费支付群:3907814
应用平安管理器来跟踪文件系统拜访必定不是最好的抉择,因为可能短少与调试计划相干的详细信息,然而如果您没有其余抉择并且须要实现工作或开销很小,则这是一个很好的折衷方案。跟踪是必须的。