我尝试在linux机器上运行jstatd jvm监控工具
jboss@hostAddr:/usr/java/jdk1.6.0_18/bin> uname -a
Linux hostAddr 2.6.16.60-0.34-smp #1 SMP Fri Jan 16 14:59:01 UTC 2009 x86_64 x86_64 x86_64 GNU/Linux
使用以下命令:
jstatd -J-Djava.security.policy=~/jstatd.all.policy
jstatd.all.policy 内容
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
不幸的是我得到以下输出:
Could not create remote object
access denied (java.util.PropertyPermission java.rmi.server.ignoreSubClasses write)
java.security.AccessControlException: access denied (java.util.PropertyPermission java.rmi.server.ignoreSubClasses write)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.System.setProperty(System.java:725)
at sun.tools.jstatd.Jstatd.main(Jstatd.java:122)
由于某种原因,jstatd 使用相同的命令和策略文件在 Windows 上成功运行。
Linux java 版本:
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)
Windows java 版本:
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
刚刚找到以下脚本来运行
jstatd
。我设法用这个脚本运行 jstatd
https://gist.github.com/nicerobot/1375032
#!/bin/sh
policy=${HOME}/.jstatd.all.policy
[ -r ${policy} ] || cat >${policy} <<'POLICY'
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
POLICY
jstatd -J-Djava.security.policy=${policy} &
这对我有用:
确保tools.jar文件存在并且运行jstatd命令的用户有权限读取它。
确保
jstatd.all.policy
中指向tools.jar的URL正确并声明协议(在本例中为文件)。例如,根据 java.home
变量指向的位置,您可能需要像这样删除路径中的 ../
部分(我必须这样做):
grant codebase "file:${java.home}/lib/tools.jar" {
permission java.security.AllPermission;
};
从 Java 1.4 开始,策略文件需要以无 BOM 的 UTF-8 编码。 EOL(CRLF 与 LF)应该并不重要。请参阅 Oracle 的“默认策略实施和策略文件语法”文档,在“更改”部分下了解更多信息(未提供链接,因为我没有足够的声誉点来发布 2 个以上的链接,但我确信您会这样做)将能够找到该文档)。
运行 jstatd 命令时使用策略文件的绝对路径,例如
jstatd -p 12345 -J-Djava.security.policy=/absolute-path-to/jstatd.all.policy
编辑:Java 1.8 中可能不再需要或支持
-J
参数,因此此命令将改为:
jstatd -p 12345 -Djava.security.policy=/absolute-path-to/jstatd.all.policy
(感谢@lisak指出这一点)
最后,一旦您通过了这一点,您可能会发现其他问题(我就是这样做的),这些帖子为我指明了正确的方向:使用 VisualVM 监视远程 JBoss 实例和使用 VisualVM 对 JBoss 进行远程分析。基本上,如果 1099 已在使用中,您可能需要使用 -p 参数来使用不同的端口,并通过
run.conf
在 JBoss JAVA_OPTS
中添加一些 java 选项(假设您正在监视 JBoss 实例)。所有内容均在提供的链接中进行了更详细的解释。编辑: - 指向死链接使用 VisualVM 监视远程 JBoss 实例到具有相同内容的另一个页面。
正如其他人指出的,自 JDK 9 起,tools.jar 和 rt.jar 已被删除,请参阅 在 Java 9+ 中启动 jstatd
使用流程替换的单行(尽管很严厉):
jstatd -p 1099 -J-Djava.security.policy=<(echo 'grant codebase "file:${java.home}/../lib/tools.jar" {permission java.security.AllPermission;};')
包裹:
jstatd -p 1099 -J-Djava.security.policy=<(echo 'grant codebase "file:${java.home}/../lib/tools.jar" {permission java.security.AllPermission;};')
使用
jdk1.8.0_92
,仍然需要 java 启动器选项前缀 -J
。
最初的问题更可能是由于
~
中的波形符 ~/jstatd.all.policy
未展开,因此 java 无法理解,同时绝对路径或使用 ${HOME}
应该可以工作。
如果您使用的是 Java 11,则需要查看此答案:Starting jstatd in Java 9+ - 堆栈内存溢出
策略文件是这样的:
grant codebase "jrt:/jdk.jstatd" {
permission java.security.AllPermission;
};
确保
javac
jstatd -J-Djava.security.policy=/path/to/jstatd.all.policy
尝试将策略放入 /tmp/jstatd.all.policy 然后运行:
jstatd -J-Djava.security.policy=/tmp/jstatd.all.policy
但是如果有时即使你已经启动了Jstatd也无法连接服务器,你可以尝试分配'rmi.server.hostname'
#!/bin/sh
policy=${HOME}/.jstatd.all.policy
[ -r ${policy} ] || cat >${policy} <<'POLICY'
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
POLICY
jstatd -J-Djava.security.policy=${policy} -J-Djava.rmi.server.hostname=192.168.x.x &
如果您想通过公共网络连接,主机名应指定为公共IP。
授予代码库“文件:/usr/java/latest/lib/tools.jar”{权限java.security.AllPermission; };
然后使用以下命令使用该策略启动 jstatd:
jstatd -J-Djava.security.policy=/usr/java/jstatd.all.policy &
${java.home}/lib/tools.jar
它实际上将 jstatd 指向
JAVA_HOME/jre/
目录,并且由于我安装了 jdk,所以我必须使用
${java.home}/../lib/tools.jar
才能到达正确的位置。编辑
我从一个使用jdk 8运行ubuntu的docker容器中运行jstatd(JAVA_HOME设置正确)。
for port in `netstat -nlp | grep jstatd | sed -r 's/^.*\:([0-9]{4,}).*$/\1/'`; do iptables -I INPUT 1 -p tcp --dport $port -j ACCEPT -m comment --comment jstatd; done
尝试将以上内容添加到
“C:\Program Files\Java\jdk-18.0.2.1\lib\security{policyFile}”