Skip to main content

Command Palette

Search for a command to run...

Mission 2 - JDK scouting

Published
4 min read
I

From Java I feel the need The need for speed

During this mission we will scout all executables which are located in JDK bin\ folder. Let's turn and burn!

First let's launch some simple Java app, which will be doing some dummy job, but stay always running, so we have material to work with.

package org.jtopgun;

public class Main {
    public static void main(String[] args) throws InterruptedException {
       Thread newThread = new Thread(() -> {
            while (true) {
                ClassWithoutFinalizer fast = new ClassWithoutFinalizer();
                System.out.println(fast.hashCode());
            }
        });
        newThread.start();
    }
}

Now let's start with commands

JINFO

#First let's find our process
./jps

My Main process have id 25368. Further all examples will be with this id, use your own. Let's get system properties of our JVM.

./jinfo 25368
#to print only jvm flags
./jinfo -flags 25368
#to print only jvm system properties
./jinfo -sysprops 25368
#to print only one flag
./jinfo -flag UseG1GC 25368

With jinfo we can also enable or disable a flag, or set up a value.

The trick is that not all flags can be dynamically set or enabled/disabled after JVM has started. Some of them are set during the initialization of JVM and cannot be changed. Let's see how to define if we can change the value of the flag. For this let's use java command.

java -XX:+PrintFlagsFinal -version

Now you will see the full list of JVM flags available for your version of JVM. First column is type of the flag (int, bool etc.), then name and value of the flag. Last column says if this flag has default value, or it is calculated ergonomically. The column which contains "product" (same for all platforms), "pd product" (default value is platform dependent), "C2 diagnostic" (provides diagnostic output). And the last value here is "manageable" - this is exactly the flags which could be changed during runtime. Let's try to change some manageable and product flags

#first let's switch some manageable flag
#display value
$ ./jinfo -flag ShowCodeDetailsInExceptionMessages 25368
-XX:+ShowCodeDetailsInExceptionMessages
#now switch
./jinfo -flag -ShowCodeDetailsInExceptionMessages 25368
#display again
$ ./jinfo -flag ShowCodeDetailsInExceptionMessages 25368
-XX:-ShowCodeDetailsInExceptionMessages
#the value was switched successfully

#now let's try to switch some not manageable flag and see the result
$ ./jinfo -flag -UseTLAB 25368
Exception in thread "main" com.sun.tools.attach.AttachOperationFailedException: flag 'UseTLAB' cannot be changed
        at jdk.attach/sun.tools.attach.VirtualMachineImpl.execute(VirtualMachineImpl.java:128)
        at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.executeCommand(HotSpotVirtualMachine.java:313)
        at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.setFlag(HotSpotVirtualMachine.java:286)
        at jdk.jcmd/sun.tools.jinfo.JInfo.flag(JInfo.java:156)
        at jdk.jcmd/sun.tools.jinfo.JInfo.main(JInfo.java:127)

JSTAT

jstat provides information about class loading activities and GC. The official documentation is here: https://docs.oracle.com/javase/9/tools/jstat.htm#JSWOR734

#getting all available options
./jstat -options
#information about JIT tasks
./jstat -compiler 25368
#information about GC and memory status
./jstat -gc 25368
#information about memory pool generation and space capacities
./jstat -gccapacity 25368
#information about GC
./jstat -gcutil 25368
./jstat -gccause 25368

JCMD

The jcmd utility is used to send diagnostic command requests to the JVM

https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html

Let's see what we could do with it:

./jcmd 25368 command

This will list all available commands for your running JVM. Now let's experiment with them.

#start JFR recording
./jcmd 25368 JFR.start
#check the status of the recording
./jcmd 25368 JFR.check
#dump recording to file
./jcmd 25368 JFR.dump
#the output will show you the name of the file and path to it
#stop the recording
./jcmd 25368 JFR.stop name=1

JSTACK

JStack allows to take thread dump of your running JVM

./jstack 25368

JMAP

JMap is needed for taking thread dumps of the application

 ./jmap -histo:all,file=/c/Soft/histo.data 32716

There are a lot of options to the command, try to play with this command and see what information you could extract using different options

OTHER JDK UTILITIES

The other jdk utilities are not that important, so we will give just brief description here.

jabswitch - to enable or disable Java Access Bridge in order to work with java acceessibility API https://docs.oracle.com/javase/7/docs/technotes/guides/access/jaapi.html

jaccessinspector - You use the javaaccessinspector accessibility evaluation tool for the Java Accessibility Utilities API to examine accessible information about the objects in the Java Virtual Machine.

jar - for manipulating jar archives

jarsigner - for signing jar archives and for verification of jar archives signatures

java - for starting new virtual machine

javac - for compilation of source code into bytecode

javadoc - for generating documentation

javap - for viewing bytecode of .class files. With -c option the output is more detailed

javaw - (Java windowed) application executor not associated with console. So no display of output/errors. It can be used to silently push the output/errors to text files. It is mostly used to launch GUI-based applications.

jdb - simple debugger

jdeprscan - You use the jdeprscan tool as a static analysis tool that scans a jar file (or some other aggregation of class files) for uses of deprecated API elements.

jdeps - class dependency analyzer

and others

https://jdk.java.net/jmc/8/

https://visualvm.github.io/download.html

https://techcrunch.com/2023/01/25/atomicjar-opens-public-beta-of-testcontainers-cloud-cloud-version-of-open-source-testing-tool/