JDK Safari: How To Find Hidden Tools in the JDK

We all have some hobby, be it sports, fishing, playing games or building compilers.

One of my hobbies is regularly searching the JDK for new Java classes with executable main methods.

How come?

Many years ago, during my forays through the JDK sources, I first encountered a class with a main-method I didn’t know about. That was in 2007 (oh boy).

The class was Class2HTML from the BCEL (Bytecode Engineering Library) library embedded in the JDK back then.

With this class, you could create a clear HTML representation of the bytecode of a class. Click here for an example.

Of course, that was many moons ago, in the meantime, BCEL has been replaced in the JDK by the ASM bytecode analysis library.

Since then, I’ve been looking for new unknown tools and possibilities in the JDK :).

Available Tools in the JDK

Many binary tools from the $JDK_HOME/bin directory are, in fact, only wrappers around corresponding classes with main methods, which can also be executed directly.
An example is the tool jcmd, which is based on the class sun.tools.jcmd.JCmd, and can alternatively be called via java -m jdk.jcmd/sun.tools.jcmd.JCmd.

In addition to these programs, however, many other small executable programs in the JDK have no direct equivalent in the $JDK_HOME/bin directory.

How to find hidden Tools in the JDK?

There are different approaches to searching the JDK for classes with main methods.
For example, one could try to open all JDK libraries (jar’s) as JarFile and then analyze all it’s classes with dynamic class-loading and reflection. Although, this approach would work to some degree (reading .jmods this way would not work), it would be very inefficient and slow due to expensive class-loading and memory usage.

My alternative approach combines a fast-analysis technique with low memory consumption and provides compatibility across different JDK (bytecode) versions.

Instead of reflection, I use ASM to scan the classes for executable main-method signatures.
Using the ForkJoin framework and RecursiveAction to analyze JDK libraries in parallel.
Using FileSystem.provider().newInputStream(…) to read from both .jar and .jmod (Java Modules) archives.

Here is a small program I use for this. The program works with Java 11 and above and can parse JDK versions >= 8. The program can analyze the current or a different JDK and print an appropriate command-line for the java launcher to execute the found classes with main-methods.

Note that the following classes can be copied into a single file MainMethodFinder.java for ease of use.

MainMethodFinder

The class MainMethodFinder is the main driver of our scanning tool. It detects the current execution environment and checks if the current JDK or a different JDK should be analyzed. The Path of the current JDK is derived via ProcessHandle.current().info().command().

It uses a MainMethodReportingVisitor, to recursively analyze the libraries of a given JDK. The actual “class with main method”-search is performed by a MainMethodVisitor. The found main method locations are reported as instances of the MainMethod data-holder class.

import jdk.internal.org.objectweb.asm.*;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Consumer;

public class MainMethodFinder {

private static final boolean VERBOSE = Boolean.getBoolean(“verbose”);

// hack to determine if we are running as GRAAL VM native-image
private static final boolean IS_NATIVE_IMAGE = System.getProperty(“org.graalvm.nativeimage.imagecode”) != null;

private static final boolean SHOW_COMMAND = Boolean.getBoolean(“showCommand”);

public static void main(String[] args) throws IOException {

long time = System.nanoTime();
try {

boolean customJdkPathProvided = args.length > 0;
if (!customJdkPathProvided && IS_NATIVE_IMAGE) {
System.err.println(“MainMethodFinder: Missing path operand.”);
System.err.println(“Usage: MainMethodFinder /path/to/jdk”);
System.exit(-1);
return;
}

var jdkHomePath = customJdkPathProvided ? Path.of(args[0]) : detectCurrentJdkPath();

if (VERBOSE) {
System.out.printf(“Scanning Java Installation: %s%n”, jdkHomePath);
}

MainMethodReportingVisitor visitor = new MainMethodReportingVisitor();
Files.walkFileTree(jdkHomePath, visitor);

Consumer<MainMethod> printMainMethodInfo = mainMethod -> {

String libraryFileName = mainMethod.library.getName();
if (libraryFileName.endsWith(“.jar”)) {
libraryFileName = jdkHomePath.relativize(mainMethod.library.toPath()).toString();
}
String mainClassName = mainMethod.className;
String libraryName = libraryFileName.replaceAll(“\.jmod”, “”);

if (SHOW_COMMAND) {
String launchCommand = generateLaunchCommand(!customJdkPathProvided, jdkHomePath, libraryFileName, mainClassName, libraryName);
System.out.printf(“%s%n”, launchCommand);
} else {
System.out.printf(“%s %s%n”, libraryName, mainClassName);
}
};

var mainMethods = visitor.waitForCompletionAndReturnMainMethods();
mainMethods.forEach(printMainMethodInfo);
} finally {
time = System.nanoTime() – time;
if (VERBOSE) {
System.out.printf(“time = %dms%n”, TimeUnit.NANOSECONDS.toMillis(time));
// System.out.printf(“ForkJoin Pool Stats: %s%n”, ForkJoinPool.commonPool());
}
}
}

private static String generateLaunchCommand(boolean useCurrentJdk, Path jdkHomePath, String libraryFileName, String mainClassName, String libraryName) {

var launchCommand = (useCurrentJdk ? “” : jdkHomePath.toFile().getAbsolutePath() + “/bin/”) + “java”;

if (libraryFileName.endsWith(“.jmod”)) {
launchCommand += (useCurrentJdk ? “” : ” –module-path ” + jdkHomePath.toFile().getAbsolutePath() + “/jmods”);
launchCommand += ” -m ” + libraryName + “/” + mainClassName;
} else if (libraryFileName.endsWith(“.jar”)) {
launchCommand += ” -cp ” + jdkHomePath.toFile().getAbsolutePath() + “/” + libraryFileName;
launchCommand += ” ” + mainClassName;
} else {
launchCommand = String.format(“Could not generate launch command for: %s %s”, libraryFileName, mainClassName);
}

return launchCommand;
}

private static Path detectCurrentJdkPath() {
return Paths.get(ProcessHandle.current().info().command().orElseThrow()).resolve(“../..”).normalize();
}
}

MainMethod

The class MainMethod is a data-holder class that captures the name of a found Class with a main-method and the library containing it.

Allthough this class could be a record, we use a normal class to be able to run the tool also with JDKs < 14.

class MainMethod {

final File library;

final String className;

public MainMethod(File library, String className) {
this.library = library;
this.className = className;
}
}

MainMethodVisitor

The class MainMethodVisitor is an ASM ClassVisitor which analyzes the class byte code to detect executable main methods. An executable main-Method obviously has the name “main” and is public static and has a String[] as single parameter.

Fun fact: With Java 21 and the introduction of JEP 445 Unnamed Classes and Instance Main Methods (Preview) the ways to declare main-methods got extended, therefore the detection rule above will no longer catch all main-method variants. If you are curious to see what’s possible, just take a look at JEP 445.

The MainMethodVisitor uses the FileSystem#provider().newInputStream(..) method in the tryGetClassBytes method to load class bytes from a .jar and .jmod files. The FileSystem instance is created via FileSystems.newFileSystem(…) with a Path to a .jar or .jmod file.

Note that we deliberately duplicate the ASM version constants, to be able to run the tool with older JDK versions.

class MainMethodVisitor extends ClassVisitor {

// Adapted from Opcodes.ASM* to be usable across jdk versions.
private static final int ASM6 = 6 << 16;

private static final int ASM7 = 7 << 16;

private static final int ASM8 = 8 << 16;

private static final int ASM9 = 9 << 16;

private static final String JAVA_VERSION_STRING = System.getProperty(“java.version”);

private static final int ASM_API_VERSION =
// not using Opcodes.* constants to support running on Java11-21
JAVA_VERSION_STRING.startsWith(“11.”) //
? ASM6 //
: JAVA_VERSION_STRING.startsWith(“15.”) //
? ASM7 //
: JAVA_VERSION_STRING.startsWith(“20.”) //
? ASM8 //
: ASM9;

private final File library;

private final FileSystem fileSystem;

private final Consumer<MainMethod> mainMethodConsumer;

private final ThreadLocal<String> currentInternalClassName;

public MainMethodVisitor(File library, Consumer<MainMethod> mainMethodConsumer, FileSystem fileSystem) {
super(ASM_API_VERSION);
this.library = library;
this.fileSystem = fileSystem;
this.mainMethodConsumer = mainMethodConsumer;
this.currentInternalClassName = new ThreadLocal<>();
}

@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
currentInternalClassName.set(name);
super.visit(version, access, name, signature, superName, interfaces);
}

@Override
public void visitEnd() {
super.visitEnd();
currentInternalClassName.remove();
}

@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
if (isRunnableMainMethod(access, name, descriptor)) {
mainMethodConsumer.accept(new MainMethod(library, currentInternalClassName.get().replace(‘/’, ‘.’)));
}
return super.visitMethod(access, name, descriptor, signature, exceptions);
}

private boolean isRunnableMainMethod(int access, String name, String descriptor) {
return “main”.equals(name) && (access & Opcodes.ACC_STATIC) != 0 && “([Ljava/lang/String;)V”.equals(descriptor);
}

void scanClassForMainMethod(Path pathToLibraryClass) {
tryGetClassBytes(pathToLibraryClass, fileSystem).ifPresent(this::visitClassBytes);
}

private void visitClassBytes(byte[] classBytes) {
new ClassReader(classBytes).accept(this, 0);
}

private Optional<byte[]> tryGetClassBytes(Path nestedFilePath, FileSystem fileSystem) {

// use filesystem to access .jar and .jmod file contents
try (var is = fileSystem.provider().newInputStream(nestedFilePath)) {
return Optional.of(is.readAllBytes());
} catch (IOException e) {
e.printStackTrace();
}
return Optional.empty();
}
}

MainMethodReportingVisitor

The actual scanning of JDK .jar-Files and .jmods is performed by the MainMethodReportingVisitor class, which is a SimpleFileVisitor used in combination with Files.walkFileTree(jdkHomePath, visitor) in the MainMethodFinder main-method.

To speed up the scanning we spawn and enqueue a new RecursiveAction in the visitFile(..) method with the ForkJoin infrastructure. The method waitForCompletionAndReturnMainMethods(..) waits for all spawned scanning actions to complete and returns the List of detected MainMethods to the MainMethodFinder which eventuelly prints command-lines to execute the all detected main-methods.

class MainMethodReportingVisitor extends SimpleFileVisitor<Path> {

private final CopyOnWriteArrayList<MainMethod> mainMethods = new CopyOnWriteArrayList<>();

private final Queue<RecursiveAction> outstanding = new ConcurrentLinkedQueue<>();

@Override
public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) {
var maybeJdkLibrary = filePath.toFile();
if (isJdkLibrary(maybeJdkLibrary.getName())) {
var action = new RecursiveAction() {
protected void compute() {
scanLibraryForMainClasses(maybeJdkLibrary);
}
};
action.fork();
outstanding.add(action);
}
return FileVisitResult.CONTINUE;
}

public List<MainMethod> waitForCompletionAndReturnMainMethods() {

for (RecursiveAction action; (action = outstanding.poll()) != null; ) {
action.join();
}

List<MainMethod> result = new ArrayList<>(this.mainMethods);
this.mainMethods.clear();

var cmp = Comparator.comparing((MainMethod left) -> left.library.getName()).thenComparing((MainMethod left) -> left.className);
result.sort(cmp);

return result;
}

private boolean isJdkLibrary(String maybeJdkLibraryName) {
return maybeJdkLibraryName.endsWith(“.jar”) || maybeJdkLibraryName.endsWith(“.jmod”);
}

private void scanLibraryForMainClasses(File library) {
// Using FileSystems.newFileSystem(library.toPath(), (ClassLoader)null) for Java 11 compatibility
try (var fileSystem = FileSystems.newFileSystem(library.toPath(), (ClassLoader) null)) {
var root = fileSystem.getRootDirectories().iterator().next();
var visitor = new MainMethodVisitor(library, mainMethods::add, fileSystem);
try (var files = Files.walk(root).parallel().filter(this::isClassFile)) {
files.forEach(visitor::scanClassForMainMethod);
}
} catch (Exception e) {
System.err.println(“Could not scan library: ” + library.getAbsolutePath());
e.printStackTrace();
}
}

private boolean isClassFile(Path nestedFilePath) {
return nestedFilePath.toString().endsWith(“.class”);
}
}

If you want to try it yourself, take a look at this Github Gist which combines everything in one file for your convenience.

Now let’s see the tool in action!

Detected Tools in JDK 21

Thanks to the support for single-file source-code programs from Java 11 onwards, we can call the tool with the following command without explicitly compiling the example first.

java –show-version -DshowCommand=true –add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED MainMethodFinder.java

Running the command with JDK 21-ea+27-2343 yields the following output:

$ java –show-version -DshowCommand=true –add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED MainMethodFinder.java
openjdk 21-ea 2023-09-19
OpenJDK Runtime Environment (build 21-ea+27-2343)
OpenJDK 64-Bit Server VM (build 21-ea+27-2343, mixed mode, sharing)
java -m java.base/java.lang.foreign.snippets.Snippets$ArenaSnippets
java -m java.base/java.util.regex.PrintPattern
java -m java.base/jdk.internal.org.objectweb.asm.util.ASMifier
java -m java.base/jdk.internal.org.objectweb.asm.util.CheckClassAdapter
java -m java.base/jdk.internal.org.objectweb.asm.util.Textifier
java -m java.base/sun.launcher.LauncherHelper$FXHelper
java -m java.base/sun.security.provider.PolicyParser
java -m java.base/sun.security.tools.keytool.Main
java -m java.desktop/sun.java2d.loops.GraphicsPrimitiveMgr
java -m java.prefs/java.util.prefs.Base64
java -m java.rmi/sun.rmi.registry.RegistryImpl
java -m java.scripting/com.sun.tools.script.shell.Main
java -m java.xml/com.sun.org.apache.xalan.internal.xsltc.ProcessorVersion
java -m java.xml/com.sun.org.apache.xerces.internal.impl.Constants
java -m java.xml/com.sun.org.apache.xerces.internal.impl.xpath.XPath
java -m java.xml/com.sun.org.apache.xerces.internal.impl.xpath.regex.REUtil
java -m jdk.compiler/com.sun.tools.javac.Main
java -m jdk.compiler/com.sun.tools.javac.launcher.Main
java -m jdk.compiler/sun.tools.serialver.SerialVer
java -m jdk.hotspot.agent/com.sun.java.swing.ui.TabsDlg
java -m jdk.hotspot.agent/com.sun.java.swing.ui.WizardDlg
java -m jdk.hotspot.agent/sun.jvm.hotspot.CLHSDB
java -m jdk.hotspot.agent/sun.jvm.hotspot.DebugServer
java -m jdk.hotspot.agent/sun.jvm.hotspot.HSDB
java -m jdk.hotspot.agent/sun.jvm.hotspot.HelloWorld
java -m jdk.hotspot.agent/sun.jvm.hotspot.ObjectHistogram
java -m jdk.hotspot.agent/sun.jvm.hotspot.SALauncher
java -m jdk.hotspot.agent/sun.jvm.hotspot.StackTrace
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.bsd.BsdAddress
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.dummy.DummyAddress
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.linux.LinuxAddress
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.posix.elf.ELFFileParser
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.remote.RemoteAddress
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.win32.coff.DumpExports
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.win32.coff.TestDebugInfo
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.win32.coff.TestParser
java -m jdk.hotspot.agent/sun.jvm.hotspot.debugger.windbg.WindbgAddress
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.ClassLoaderStats
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.FinalizerInfo
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.FlagDumper
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.HeapDumper
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.HeapSummary
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.JInfo
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.JMap
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.JSnap
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.JStack
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.ObjectHistogram
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.PMap
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.PStack
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.StackTrace
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.SysPropsDumper
java -m jdk.hotspot.agent/sun.jvm.hotspot.tools.jcore.ClassDump
java -m jdk.hotspot.agent/sun.jvm.hotspot.ui.AnnotatedMemoryPanel
java -m jdk.hotspot.agent/sun.jvm.hotspot.ui.CommandProcessorPanel
java -m jdk.hotspot.agent/sun.jvm.hotspot.ui.DebuggerConsolePanel
java -m jdk.hotspot.agent/sun.jvm.hotspot.ui.HighPrecisionJScrollBar
java -m jdk.hotspot.agent/sun.jvm.hotspot.ui.ObjectHistogramPanel
java -m jdk.hotspot.agent/sun.jvm.hotspot.utilities.PlatformInfo
java -m jdk.hotspot.agent/sun.jvm.hotspot.utilities.RBTree
java -m jdk.httpserver/sun.net.httpserver.simpleserver.JWebServer
java -m jdk.httpserver/sun.net.httpserver.simpleserver.Main
java -m jdk.internal.le/jdk.internal.org.jline.terminal.impl.Diag
java -m jdk.jartool/sun.security.tools.jarsigner.Main
java -m jdk.jartool/sun.tools.jar.Main
java -m jdk.javadoc/jdk.javadoc.internal.doclint.DocLint
java -m jdk.javadoc/jdk.javadoc.internal.tool.Main
java -m jdk.jcmd/sun.tools.jcmd.JCmd
java -m jdk.jcmd/sun.tools.jinfo.JInfo
java -m jdk.jcmd/sun.tools.jmap.JMap
java -m jdk.jcmd/sun.tools.jps.Jps
java -m jdk.jcmd/sun.tools.jstack.JStack
java -m jdk.jcmd/sun.tools.jstat.Jstat
java -m jdk.jconsole/sun.tools.jconsole.JConsole
java -m jdk.jdeps/com.sun.tools.javap.Main
java -m jdk.jdeps/com.sun.tools.jdeprscan.Main
java -m jdk.jdeps/com.sun.tools.jdeps.Main
java -m jdk.jdeps/com.sun.tools.jdeps.Profile
java -m jdk.jdi/com.sun.tools.example.debug.expr.ExpressionParser
java -m jdk.jdi/com.sun.tools.example.debug.tty.TTY
java -m jdk.jfr/jdk.jfr.internal.tool.Main
java -m jdk.jfr/jdk.jfr.snippets.Snippets
java -m jdk.jfr/jdk.jfr.snippets.Snippets$ConfigurationOverview
java -m jdk.jfr/jdk.jfr.snippets.Snippets$Example
java -m jdk.jfr/jdk.jfr.snippets.consumer.Snippets$EventStreamMetadata
java -m jdk.jfr/jdk.jfr.snippets.consumer.Snippets$PackageOverview
java -m jdk.jlink/jdk.tools.jimage.Main
java -m jdk.jlink/jdk.tools.jlink.internal.Main
java -m jdk.jlink/jdk.tools.jmod.Main
java -m jdk.jpackage/jdk.jpackage.main.Main
java -m jdk.jshell/jdk.internal.jshell.tool.JShellToolProvider
java -m jdk.jshell/jdk.jshell.execution.RemoteExecutionControl
java -m jdk.jstatd/sun.tools.jstatd.Jstatd
java -m jdk.security.auth/com.sun.security.auth.module.Crypt
java -m jdk.zipfs/jdk.nio.zipfs.ZipInfo

The listed classes contain the known tools from the $JDK_HOME/bin directory and many small debugging tools and test programs. Just have a look for yourself

Did you ever want to know how the pattern node tree looks for a compiled regex pattern? Just run:

$ java -m java.base/java.util.regex.PrintPattern “^[w-.]+@([w-]+.)+[w-]{2,4}$”

Pattern: ^[w-.]+@([w-]+.)+[w-]{2,4}$
0: <Begin>
1: <BmpCharPropertyGreedy java.util.regex.Pattern$Lambda/0x800000033@5ca881b5+>
2: <BmpCharProperty>
3: <Prolog>
4: <Loop + >
5: <Group.head 1>
6: <BmpCharPropertyGreedy java.util.regex.Pattern$Lambda/0x800000033@2ff4acd0+>
7: <BmpCharProperty>
8: </Group.tail 1> (=>4)
</Loop>
9: <Curly GREEDY {2, 4}>
10: <BmpCharProperty>
</Curly>
11: <Dollar>
12: <END>

Another tool that many Java developers are not familiar with is the HotSpot Debugger UI, which allows you to look and poke at some JVM internals. The tool itself is actually not so hidden, as it can be started via jhsdb hsdb, but I discovered it a few years ago by scanning for main methods.

You can also start the hsdb ui via: java -m jdk.hotspot.agent/sun.jvm.hotspot.HSDB.

HotSpot Debugger UI

Detected Tools in JDK 8

Tip: If we want to analyze an older JDK, e.g., JDK8 we can do it like this:

java -DshowCommand=true –add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED MainMethodFinder.java /path/to/jdk

Note an easy way to install and manage different JDKs for experiments is sdkman

Output:

$ java –show-version -DshowCommand=true –add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED MainMethodFinder.java ~/.sdkman/candidates/java/8.0.282.hs-adpt
openjdk 21-ea 2023-09-19
OpenJDK Runtime Environment (build 21-ea+27-2343)
OpenJDK 64-Bit Server VM (build 21-ea+27-2343, mixed mode, sharing)
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/jconsole.jar sun.tools.jconsole.JConsole
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/jfr.jar jdk.jfr.internal.tool.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/ext/nashorn.jar jdk.nashorn.tools.Shell
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.activation.ORBD
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.activation.RepositoryImpl
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.activation.ServerMain
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.activation.ServerTool
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.naming.cosnaming.TransientNameServer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.naming.pcosnaming.NameServer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.util.JDKBridge
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.util.ORBProperties
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.impl.util.Version
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.internal.CosNaming.BootstrapServer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.corba.se.spi.orbutil.fsm.FSMTest
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.java.util.jar.pack.Driver
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xalan.internal.xslt.EnvironmentCheck
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xalan.internal.xsltc.ProcessorVersion
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xalan.internal.xsltc.cmdline.Compile
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xalan.internal.xsltc.cmdline.Transform
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xerces.internal.impl.Constants
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xerces.internal.impl.Version
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xerces.internal.impl.xpath.XPath
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xerces.internal.impl.xpath.regex.REUtil
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.org.apache.xml.internal.security.keys.storage.implementations.CertsInFilesystemDirectoryResolver
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.security.auth.module.Crypt
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.FI_DOM_Or_XML_DOM_SAX_SAXEvent
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.FI_SAX_Or_XML_SAX_DOM_SAX_SAXEvent
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.FI_SAX_Or_XML_SAX_SAXEvent
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.FI_SAX_XML
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.FI_StAX_SAX_Or_XML_SAX_SAXEvent
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.PrintTable
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.XML_DOM_FI
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.XML_DOM_SAX_FI
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.XML_SAX_FI
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar com.sun.xml.internal.fastinfoset.tools.XML_SAX_StAX_FI
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar java.util.prefs.Base64
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar jdk.internal.org.objectweb.asm.util.ASMifier
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar jdk.internal.org.objectweb.asm.util.CheckClassAdapter
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar jdk.internal.org.objectweb.asm.util.Textifier
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.applet.AppletViewer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.applet.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.java2d.loops.GraphicsPrimitiveMgr
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.launcher.LauncherHelper$FXHelper
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.net.NetworkServer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.rmi.registry.RegistryImpl
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.rmi.server.Activation
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.rmi.server.ActivationGroupInit
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.rmi.transport.proxy.CGIHandler
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.security.provider.PolicyParser
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.security.tools.keytool.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.security.tools.policytool.PolicyTool
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/rt.jar sun.tools.jar.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar com.sun.java.swing.ui.TabsDlg
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar com.sun.java.swing.ui.WizardDlg
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.DebugServer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.HSDB
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.HelloWorld
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.ObjectHistogram
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.StackTrace
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.bsd.BsdAddress
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.dummy.DummyAddress
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.linux.LinuxAddress
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.posix.elf.ELFFileParser
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.proc.ProcAddress
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.remote.RemoteAddress
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.win32.coff.DumpExports
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.win32.coff.TestDebugInfo
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.win32.coff.TestParser
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.debugger.windbg.WindbgAddress
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.jdi.SADebugServer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.ClassLoaderStats
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.FinalizerInfo
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.FlagDumper
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.HeapDumper
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.HeapSummary
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.JInfo
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.JMap
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.JSnap
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.JStack
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.ObjectHistogram
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.PMap
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.PStack
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.StackTrace
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.SysPropsDumper
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.jcore.ClassDump
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.soql.JSDB
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.tools.soql.SOQL
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.ui.AnnotatedMemoryPanel
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.ui.CommandProcessorPanel
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.ui.DebuggerConsolePanel
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.ui.HighPrecisionJScrollBar
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.ui.ObjectHistogramPanel
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.utilities.PlatformInfo
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/sa-jdi.jar sun.jvm.hotspot.utilities.RBTree
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.corba.se.idl.Compile
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.corba.se.idl.toJavaPortable.Compile
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.doclint.DocLint
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.example.debug.expr.ExpressionParser
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.example.debug.tty.TTY
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.extcheck.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.hat.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.internal.jxc.SchemaGenerator
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.internal.jxc.SchemaGeneratorFacade
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.internal.ws.WsGen
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.internal.ws.WsImport
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.internal.xjc.Driver
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.internal.xjc.XJCFacade
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.internal.xjc.reader.xmlschema.parser.SchemaConstraintChecker
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.internal.xjc.util.MimeTypeRange
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.javac.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.javac.sym.CreateSymbols
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.javac.sym.Profiles
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.javac.util.Bits
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.javadoc.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.javah.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.javap.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.jdeps.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.jdeps.Profile
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.tools.script.shell.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.xml.internal.rngom.digested.DXMLPrinter
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.xml.internal.rngom.digested.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar com.sun.xml.internal.rngom.xml.util.EncodingMap
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.applet.AppletViewer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.applet.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.rmi.rmic.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.rmi.rmic.iiop.StaticStringsHash
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.rmi.rmic.newrmic.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.security.tools.jarsigner.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.jar.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.javac.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.jcmd.JCmd
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.jinfo.JInfo
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.jmap.JMap
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.jps.Jps
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.jstack.JStack
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.jstat.Jstat
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.jstatd.Jstatd
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.native2ascii.Main
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/lib/tools.jar sun.tools.serialver.SerialVer
/home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/bin/java -cp /home/tom/.sdkman/candidates/java/8.0.282.hs-adpt/jre/lib/ext/zipfs.jar com.sun.nio.zipfs.ZipInfo

Conclusion

In this article we have learned that the JDK contains many more programmes than the $JDK_HOME/bin directory would suggest at first glance. We also learned about efficient ways to analyse Java classes with ASM.

I hope you discovered some new things in the article and have fun with your JDK Safari!

The post JDK Safari: How To Find Hidden Tools in the JDK appeared first on foojay.