cannot start jstatd due to permission error

JavaJvm

Java Problem Overview


I try to run jstatd jvm monitoring tool on linux machine

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

with following command:

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

jstatd.all.policy contents

grant codebase "file:${java.home}/../lib/tools.jar" {

   permission java.security.AllPermission;

};

Unfortunately I get following output:

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)

For some reason jstatd runs successfully on windows with the same command and policy file.

Linux java version:

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 version:

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)

Java Solutions


Solution 1 - Java

Just found following script to run jstatd. I managed to run jstatd with this script 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} &

Solution 2 - Java

This is what worked for me:

  1. Make sure that tools.jar file exists and the user running the jstatd command has permissions to read it.

  2. Make sure that the URL in the jstatd.all.policy that points to the tools.jar is correct and declares the protocol (file in this case). For example, depending on where the java.home variable points to, you may need to remove the ../ part in the path just like this (I had to):

     grant codebase "file:${java.home}/lib/tools.jar" {
        permission java.security.AllPermission;
     };
    
  3. Starting from Java 1.4 the policy file needs to be encoded in UTF-8 without BOM. The EOL (CRLF vs LF) shouldn't really matter. Please see "Default Policy Implementation and Policy File Syntax" document from Oracle, under "Changes" section for more information (link not provided because I don't have enough reputation points to post more than 2 links, but I'm sure you'll be able to find that document).

  4. Use an absolute path to the policy file when running the jstatd command, e.g.

     jstatd -p 12345 -J-Djava.security.policy=/absolute-path-to/jstatd.all.policy
    

EDIT: The -J parameter may no longer be required or supported in Java 1.8 so this command would be instead:

    jstatd -p 12345 -Djava.security.policy=/absolute-path-to/jstatd.all.policy

(thanks @lisak for pointing this out)

  1. Finally, once you pass this point you may find other problems (I did) and these posts pointed me in the right direction: Using VisualVM to monitor a remote JBoss instance and Remote Profiling of JBoss using VisualVM. Basically you may need to use the -p parameter to use a different port if 1099 is already in use and add some java options in the JBoss run.conf via JAVA_OPTS (assuming you are monitoring JBoss instance). All explained in more detail in the links provided.

EDIT:

Solution 3 - Java

A one liner using process substitution (though bashism):

jstatd -p 1099 -J-Djava.security.policy=<(echo 'grant codebase "file:${java.home}/../lib/tools.jar" {permission java.security.AllPermission;};')

Wrapped:

> jstatd -p 1099 -J-Djava.security.policy=<(echo 'grant codebase "file:${java.home}/../lib/tools.jar" {permission java.security.AllPermission;};')

As of jdk1.8.0_92, the java launcher option prefix -J is still required.

Note:

The original problem is more likely due to the tilde ~, in ~/jstatd.all.policy, isn't expanded hence not understood by java, meanwhile either absolute path or using ${HOME} instead should work.

Solution 4 - Java

I have the same problem and that what you should do:

  1. Make sure that javac is in your $PATH
  2. Specify full (absolute) path to the policy file when running jstatd
    jstatd -J-Djava.security.policy=/path/to/jstatd.all.policy

It helped for me.

Solution 5 - Java

Are you specifying your path wrong (i was)?

Try putting the policy in /tmp/jstatd.all.policy and then running:

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

Solution 6 - Java

Just an additional point about previous answers that cost me some minor time to figure out.
When I used relative path in the policy file ${java.home}/lib/tools.jar it actually pointed jstatd to JAVA_HOME/jre/ directory and since I had jdk installed I had to use ${java.home}/../lib/tools.jar instead to get to the right place.

EDIT I was running jstatd from within a docker container running ubuntu with jdk 8 (JAVA_HOME was set correctly).

Solution 7 - Java

if you are using Java 11, you need view this answer:Starting jstatd in Java 9+ - Stack Overflow
policy file is like this:

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

Solution 8 - Java

@michael nesterenko 's answer is all right.

But if sometimes you can't connect the server even if you have get the Jstatd up, u may try to assign the '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 &

the hostname shoule be assigned as the public ip if you want to connect via public network.

Solution 9 - Java

I created new policy with following content:

> grant codebase "file:/usr/java/latest/lib/tools.jar" { permission java.security.AllPermission; };

and then start jstatd with that policy with following command:

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

Solution 10 - Java

in addition to LightDye's answer, you can open required ports in your netfilter with this command :

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

Solution 11 - Java

Or you can use ejstatd instead of jstatd which automatically handles this problem: just run it using mvn exec:java inside ejstatd folder.

Disclaimer: I'm the author of this open source tool.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmichael nesterenkoView Question on Stackoverflow
Solution 1 - Javamichael nesterenkoView Answer on Stackoverflow
Solution 2 - JavaLightDyeView Answer on Stackoverflow
Solution 3 - JavaryenusView Answer on Stackoverflow
Solution 4 - JavaVadimView Answer on Stackoverflow
Solution 5 - JavatsterView Answer on Stackoverflow
Solution 6 - JavaMilos StojiljkovicView Answer on Stackoverflow
Solution 7 - Javapeter zhangView Answer on Stackoverflow
Solution 8 - JavaDai KaixianView Answer on Stackoverflow
Solution 9 - JavaNitin TaurView Answer on Stackoverflow
Solution 10 - JavaPHaroZView Answer on Stackoverflow
Solution 11 - JavaAnthony O.View Answer on Stackoverflow