alibaba/arthas · error · IllegalArgumentException

Can not find java/java.exe executable file under java home:

Error message

Can not find java/java.exe executable file under java home: {javaHome}

What it means

ProcessUtils.startArthasCore calls findJava(javaHome) to locate the java/java.exe executable. If findJava returns null (no bin/java or bin/java.exe under the resolved home), it throws IllegalArgumentException("Can not find java/java.exe executable file under java home: <home>").

Source

Thrown at boot/src/main/java/com/taobao/arthas/boot/ProcessUtils.java:285

                }

                throw new IllegalArgumentException("Can not find tools.jar under java home: " + javaHome
                        + ", please try to start arthas-boot with full path java. Such as /opt/jdk/bin/java -jar arthas-boot.jar");
            }
        } else {
            FOUND_JAVA_HOME = javaHome;
        }
        return FOUND_JAVA_HOME;
    }

    public static void startArthasCore(long targetPid, List<String> attachArgs) {
        // find java/java.exe, then try to find tools.jar
        String javaHome = findJavaHome();

        // find java/java.exe
        File javaPath = findJava(javaHome);
        if (javaPath == null) {
            throw new IllegalArgumentException(
                    "Can not find java/java.exe executable file under java home: " + javaHome);
        }

        File toolsJar = findToolsJar(javaHome);

        if (JavaVersionUtils.isLessThanJava9()) {
            if (toolsJar == null || !toolsJar.exists()) {
                throw new IllegalArgumentException("Can not find tools.jar under java home: " + javaHome);
            }
        }

        List<String> command = new ArrayList<String>();
        command.add(javaPath.getAbsolutePath());

        if (toolsJar != null && toolsJar.exists()) {
            command.add("-Xbootclasspath/a:" + toolsJar.getAbsolutePath());
        }

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Confirm $JAVA_HOME/bin/java (or java.exe) exists and is executable.
  2. Reset JAVA_HOME to the JDK root that contains bin/java.
  3. Reinstall/repair the JDK so the launcher is present.
  4. On Windows ensure the home has bin/java.exe (not just javaw.exe).

Example fix

# before
export JAVA_HOME=/opt/jdk/lib        # wrong: no bin/java

# after
export JAVA_HOME=/opt/jdk            # has bin/java
ls $JAVA_HOME/bin/java && java -jar arthas-boot.jar
Defensive patterns

Strategy: validation

Validate before calling

File j = new File(javaHome, "bin/java");
if (!j.isFile()) j = new File(javaHome, "bin/java.exe");
if (!j.isFile()) {
    throw new IllegalStateException("no java launcher under " + javaHome);
}

Type guard

static boolean hasJavaLauncher(String javaHome) {
    if (javaHome == null) return false;
    return new File(javaHome, "bin/java").isFile()
        || new File(javaHome, "bin/java.exe").isFile();
}

Try / catch

try {
    ProcessUtils.startArthasCore(pid, args);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("java/java.exe")) {
        // reset JAVA_HOME to a JDK that has bin/java
    } else throw e;
}

Prevention

When it happens

Trigger: javaHome resolves to a directory that lacks a bin/java (or bin/java.exe on Windows) entry — e.g. a JRE without java, a partial install, or a home path pointing at lib/ rather than the JDK root.

Common situations: Broken JDK install missing the bin/ launcher; JAVA_HOME pointing at a nested jre/ dir; container with only runtime files; Windows/Linux exe-name mismatch in a misconfigured environment.

Related errors


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/b5052439557a8c59. Report an issue: GitHub.