Skip to content

Java main runnable uses mvn exec:java instead of launching a standalone JVM #284

Description

@Roter-S

What happened?

Summary

Clicking the inline Play button for a main method in a Maven project runs the application through mvn ... exec:java. The exec:java goal runs the main class inside Maven's JVM and on a plugin-managed thread instead of launching a normal standalone Java process.

This produces observably different runtime semantics from VS Code's Java runner, Zed's Java debugger, or java -cp ... Main. In our case, a library performs resource discovery from the application's stack trace. Under Zed's generated task, the last stack frame is Maven's worker thread, so resource lookup returns null and the application fails before it can start.

Generated command

The Java extension's java-main task currently reaches:

mvn clean compile exec:java \
  -Dexec.mainClass="com.example.Main" \
  -Dexec.classpathScope=runtime

Minimal reproduction

package com.example;

public class Main {
    public static void main(String[] args) {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        System.out.println("thread = " + Thread.currentThread().getName());
        System.out.println("last frame = " + stack[stack.length - 1]);
    }
}
  1. Put the class in a Maven project.
  2. Click the inline Play button next to main.
  3. Compare the output with a standalone launch using java -cp ... com.example.Main.

With exec:java, the bottom frame belongs to the Maven/plugin worker thread rather than Main.main.

Workaround

A global java-main task that compiles with Maven, builds the dependency classpath, and then executes java -cp ... Main works correctly.

Suggested fix

Launch the main class in a separate JVM. Possible approaches include:

  • use Maven only to compile/resolve the classpath, then execute java directly;
  • use exec:exec with java as the executable and %classpath;
  • use the classpath already resolved by the Java language/debug tooling.

The inline Run action should have the same process/thread semantics as a normal Java launch.

What did you expect to happen?

Clicking Play next to a Java main method should launch that class in a standalone JVM with normal java process semantics.

Maven can still be used to compile the project and resolve dependencies, but the application itself should not run inside Maven's JVM through exec:java.

Environment

Zed: 1.10.3 (build 20260713.002323)
Java extension: 6.8.21
Platform: macOS 26.5.2 (Apple Silicon)
JDK: Amazon Corretto 21.0.11
Maven: 3.9.16
Project type: Maven

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions