由于权限错误,无法启动jstatd

我尝试在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) 

这对我来说是有效的:

  1. 确保tools.jar文件存在,运行jstatd命令的用户有权读取它。

  2. 确保指向tools.jar的jstatd.all.policy中的URL是正确的,并声明协议(本例中为文件)。 例如,根据java.homevariables指向的地方,你可能需要像这样删除path中的../部分(我必须):

     grant codebase "file:${java.home}/lib/tools.jar" { permission java.security.AllPermission; }; 
  3. 从Java 1.4开始,需要使用UTF-8编码策略文件, 而不使用BOM 。 EOL(CRLF vs LF)应该不重要。 请参阅Oracle的“默认策略实施和策略文件语法”文档,在“更改”一节中获取更多信息(未提供链接是因为我没有足够的信誉点来发布超过2个链接,但是我相信,将能够find该文件)。

  4. 运行jstatd命令时,使用绝对path到策略文件,例如

     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指出这一点)

  5. 最后,一旦你通过这一点,你可能会发现其他问题(我做了),这些post指出我正确的方向: 使用VisualVM监视远程JBoss实例和使用VisualVM远程分析JBoss 。 基本上你可能需要使用-p参数来使用不同的端口,如果1099已经在使用,并通过JAVA_OPTS (假设你在监视JBoss实例)在JBoss run.conf添加一些java选项。 所有在所提供的链接中更详细地解释。

编辑: – 指向死链接使用VisualVM监视一个远程JBoss实例到另一个页面具有相同的内容。

刚刚find下面的脚本来运行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} & 

一个使用stream程replace (尽pipebashism)的class轮:

 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不能理解,同时要么使用绝对path,要么使用${HOME}来代替。

我有同样的问题,你应该做什么:

  1. 确保javac在你的$ PATH中
  2. 运行jstatd时,指定策略文件的完整(绝对)path
    jstatd -J-Djava.security.policy=/path/to/jstatd.all.policy

这对我有帮助。

你是否指定你的path错误(我是)?

尝试将策略放在/tmp/jstatd.all.policy中,然后运行:

 jstatd -J-Djava.security.policy=/tmp/jstatd.all.policy 

关于以前的答案只是额外的一点,我花了一些小的时间来弄清楚。
当我在策略文件${java.home}/lib/tools.jar使用相对path时,它实际上将jstatd指向了JAVA_HOME/jre/目录,并且因为我安装了jdk,所以必须使用${java.home}/../lib/tools.jar而不是去正确的地方。

编辑我正在运行jdk 8(JAVA_HOME被设置正确)的Docker容器内运行jstatd。

除了LightDye的回答,你可以使用这个命令在你的netfilter中打开所需的端口:

 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 

@迈克尔·内斯特伦连科的回答是没问题的。

但是,如果有时即使你已经获得了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.xx & 

如果您想通过公共networking连接,则将主机名称分配为公共IP。

或者你可以使用ejstatd而不是自动处理这个问题的jstatd :只需使用mvn exec:java在ejstatd文件夹中运行它。

免责声明:我是这个开源工具的作者。

我制定了以下内容的新政策:

授予codebase“文件:/usr/java/latest/lib/tools.jar”{permission java.security.AllPermission; };

然后用以下命令启动该策略的jstatd:

jstatd -J-Djava.security.policy = / usr / java / jstatd.all.policy&