由于权限错误无法启动jstatd

时间:2012-03-30 08:58:16

标签: java jvm

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

11 个答案:

答案 0 :(得分:63)

刚刚找到以下脚本来运行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} &

答案 1 :(得分:57)

这对我有用:

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

  2. 确保jstatd.all.policy中指向tools.jar的URL正确并声明协议(本例中为文件)。例如,根据java.home变量指向的位置,您可能需要删除路径中的../部分,就像这样(我必须):

    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个链接,但我确定你'我能找到那份文件。

  4. 运行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指出这一点)

  5. 最后,一旦你通过这一点,你可能会发现其他问题(我做过),这些帖子指出了我正确的方向:Using VisualVM to monitor a remote JBoss instanceRemote Profiling of JBoss using VisualVM。基本上,如果已经使用了1099,则可能需要使用-p参数来使用不同的端口,并通过run.conf在JBoss JAVA_OPTS中添加一些java选项(假设您正在监视JBoss实例)。所有链接中都有更详细的解释。

  6. 编辑: - 将死链接Using VisualVM to monitor a remote JBoss instance指向具有相同内容的其他页面。

答案 2 :(得分:17)

使用process substitution的一个班轮(虽然是bashism):

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}代替应该工作

答案 3 :(得分:2)

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

  1. 确保{$ 1}}在$ PATH
  2. 运行jstatd时指定策略文件的完整(绝对)路径 javac
  3. 这对我有帮助。

答案 4 :(得分:2)

你是否指定了你的路径(我是)?

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

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

答案 5 :(得分:2)

关于以前的答案,还有一点需要花费一些时间才能弄明白 当我在策略文件${java.home}/lib/tools.jar中使用相对路径时,它实际上将jstatd指向 JAVA_HOME/jre/ 目录,因为我安装了jdk,所以我必须使用${java.home}/../lib/tools.jar代替到了正确的地方。

编辑我在运行ubuntu的docker容器中使用jdk 8运行jstatd(JAVA_HOME设置正确)。

答案 6 :(得分:1)

我创建了包含以下内容的新政策:

  

授予代码库&#34;文件:/usr/java/latest/lib/tools.jar" {permission java.security.AllPermission; };

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

  

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

答案 7 :(得分:0)

除了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

答案 8 :(得分:0)

@michael nesterenko的回答没问题。

但是,如果有时你无法连接服务器,即使你已经获得了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 &

如果要通过公共网络连接,则将主机名shoule指定为公共IP。

答案 9 :(得分:0)

或者您可以使用ejstatd代替jstatd自动处理此问题:只需在ejstatd文件夹中使用mvn exec:java运行它。

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

答案 10 :(得分:0)

如果您使用的是Java 11,则需要查看以下答案:Starting jstatd in Java 9+ - Stack Overflow
策略文件是这样的:

grant codebase "jrt:/jdk.jstatd" {    
   permission java.security.AllPermission;    
};