javajava-9jstatd

Starting jstatd in Java 9+


In the past, I have started jstatd via a security policy file, as suggested here: https://stackoverflow.com/a/14930180/1294116

However, in Java 9+, they have removed the tools.jar file, which means that this solution no longer works. Does anyone know how to get around this? (Currently I am back to getting the error java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.rmi.server.ignoreSubClasses" "write") ...)


Solution

  • Java 19 Update: Release Notes - jstatd No Longer Requires a SecurityManager (JDK-8272317)

    jstatd no longer requires a Security Manager and policy file. Running with -Djava.security.policy= to set a policy has no effect.

    Internally to jstatd, an ObjectInputFilter is used to allow only essential classes to be deserialized over the RMI connection.


    Solution

    The following policy file should work for you (at least under Java 11):

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

    Thanks to Sebastian S for pointing out jdk.internal.jvmstat also needed to be granted the appropriate permission and for confirming the above works. Thanks to Gili for the latter as well.

    As shown below, the tools.jar file was removed and everything in it was split up into modules. The jstatd tool now resides in the jdk.jstatd module. I couldn't find documentation regarding how it was determined which tool(s) went into which module, though the Javadoc does tell you after-the-fact. Just note that some modules contain the code for a single tool while other modules contain the code for multiple tools.


    Documentation

    From the Policy File Syntax documentation:

    If you are using a modular runtime image (see the jlink tool), you can grant permissions to the application and library modules in the image by specifying a jrt URL as the codeBase value in a policy file. See JEP 220: Modular Run-Time Images for more information about jrt URLs.

    The following example grants permission to read the foo property to the module com.greetings:

    grant codeBase "jrt:/com.greetings" {
       permission java.util.PropertyPermission "foo", "read";
    };
    

    From JEP 200: The Modular JDK:

    Design principles

    The modular structure of the JDK implements the following principles:

    • Standard modules, whose specifications are governed by the JCP, have names starting with the string "java.".
    • All other modules are merely part of the JDK, and have names starting with the string "jdk.".

    [...]

    From JEP 220: Modular Run-Time Images:

    Summary

    Restructure the JDK and JRE run-time images to accommodate modules and to improve performance, security, and maintainability. Define a new URI scheme for naming the modules, classes, and resources stored in a run-time image without revealing the internal structure or format of the image. Revise existing specifications as required to accommodate these changes.

    [...]

    Removed: rt.jar and tools.jar

    The class and resource files previously stored in lib/rt.jar, lib/tools.jar, lib/dt.jar, and various other internal JAR files are now stored in a more efficient format in implementation-specific files in the lib directory. The format of these files is not specified and is subject to change without notice.

    The removal of rt.jar and similar files leads to three distinct problems:

    1. [...]

    2. The java.security.CodeSource API and security-policy files use URLs to name the locations of code bases that are to be granted specified permissions. Components of the run-time system that require specific permissions are currently identified in the lib/security/java.policy file via file URLs. The elliptic-curve cryptography provider, e.g., is identified as

      file:${java.home}/lib/ext/sunec.jar
      

      which, obviously, has no meaning in a modular image.

    3. [...]

    New URI scheme for naming stored modules, classes, and resources

    To address the above three problems a new URL scheme, jrt, can be used to name the modules, classes, and resources stored in a run-time image without revealing the internal structure or format of the image.

    A jrt URL is a hierarchical URI, per RFC 3986, with the syntax

    jrt:/[$MODULE[/$PATH]]
    

    where $MODULE is an optional module name and $PATH, if present, is the path to a specific class or resource file within that module. The meaning of a jrt URL depends upon its structure:

    • [...]

    • jrt:/$MODULE refers to all of the class and resource files in the module $MODULE.

    • [...]

    These three forms of jrt URLs address the above problems as follows:

    1. [...]

    2. Security-policy files and other uses of the CodeSource API can use jrt URLs to name specific modules for the purpose of granting permissions. The elliptic-curve cryptography provider, e.g., can now be identified by the jrt URL

      jrt:/jdk.crypto.ec
      

      Other modules that are currently granted all permissions but do not actually require them can trivially be de-privileged, i.e., given precisely the permissions they require.

    3. [...]

    Both JEP 200 and JEP 220 were part of Project Jigsaw.