Skip to content

ADFA-1980 | JVM-Tools: run Java and Kotlin programs with a main-class picker - #124

Open
Daniel-ADFA wants to merge 1 commit into
mainfrom
feat/ADFA-1980-jvm-tools
Open

Daniel-ADFA wants to merge 1 commit into
mainfrom
feat/ADFA-1980-jvm-tools

Conversation

@Daniel-ADFA

@Daniel-ADFA Daniel-ADFA commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

ADFA-1980

Adds JVM-Tools: run Java and Kotlin programs the way a desktop IDE does. In a folder of .java/.kt files with no Gradle build:

  • Run compiles every source on the device (the bundled Kotlin compiler, then javac) and runs the chosen main class. Output goes to Build Output; Cancel Run stops it.
  • Run configuration picks the main class and program arguments, saved per project. Material dialog shown through PluginWindows.
  • A Java/Kotlin Program template.

Gradle actions and Quick Build are hidden in these projects, as in Python-Tools. Requires CoGo 26.37. Programs can't read keyboard input; plugin commands have no stdin.

Verified on an emulator: Kotlin, Java and mixed projects, arguments, cancel, unsaved edits, tooltips and help page, 2x font, and Android projects left unchanged.

… picker

CoGo could not run a plain Java or Kotlin program: Quick Run builds and
installs an Android app. JVM-Tools adds, for a folder of .java/.kt files
with no Gradle build:

- Run: compiles every source on the device (kotlin-compiler-embeddable
  from the IDE's local Maven repository for Kotlin, then the JDK's javac,
  so Java and Kotlin can use each other) and execs java on the chosen
  main class. Output streams to Build Output; Cancel Run stops the JVM.
  Unsaved Java/Kotlin buffers are written before compiling.
- Run configuration: lists every class with a main (Java static main,
  Kotlin top-level main as its FileNameKt facade, @JvmStatic main in an
  object or companion) and takes program arguments with shell-style
  quoting. It is a Material dialog built on the IDE activity and shown
  through PluginWindows, so it matches the IDE's dialogs. Saved per
  project in the plugin directory.
- A Java/Kotlin Program template.

The Gradle actions and Quick Build are hidden in these projects, as in
Python-Tools. Requires 26.37 for PluginWindows. Programs
cannot read stdin: plugin commands have no input stream.
@Daniel-ADFA
Daniel-ADFA requested a review from a team October 6, 2026 22:49
private fun javaMainClasses(code: String): List<String> {
val pkg = JAVA_PACKAGE.find(code)?.groupValues?.get(1)
return JAVA_MAIN.findAll(code)
.mapNotNull { main -> JAVA_TYPE.findAll(code.substring(0, main.range.first)).lastOrNull()?.groupValues?.get(1) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

main is attributed to the last class/interface/enum/record declared anywhere before it in the file, so a nested type declared above main takes the name.

Example:

public class Main {
    record Point(int x, int y) {}
    public static void main(String[] args) {}
}

This yields Point, so the script runs java -cp … Point and fails with "Could not find or load main class Point". A main inside a static nested class is likewise run under its simple name rather than Outer$Inner.

The Kotlin @JvmStatic path (ownerOf, line 70) has the same issue with nested objects. No test in MainClassFinderTest covers nested types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants