mirror of https://github.com/sbt/sbt.git
**Problem** After #9073, `consoleProject` starts a Scala 3 REPL successfully, but `currentState`, `extracted`, and `cpHelpers` show as `null` in the REPL. Reviewer eed3si9n reported this on the PR. Root cause: the Scala 3 REPL's `dotty.tools.repl.AbstractFileClassLoader` ends up defining a fresh copy of `sbt.internal.ConsoleProjectBindings` (and the other sbt classes referenced by the bindings) from the sbt module jars on `unit.classpath`, instead of delegating to sbt's own class loader via parent-first delegation. The two `Class` objects are distinct, so setting static fields on sbt's copy has no effect on the one the REPL compiles against. A strongly typed cast would additionally hit `LinkageError: loader constraint violation` on `sbt.State`. **Solution** Strip every jar shipping sbt core code from the runtime class loader used by the `consoleProject` REPL. The jars are detected by content — any jar that contains `sbt/State.class`, `sbt/Extracted.class`, `sbt/internal/ConsoleProjectBindings$.class`, or `sbt/internal/Load$.class` is considered an sbt module jar and filtered out. The full classpath is still passed to `Console` below, so the REPL's compile-time classpath (from the `-classpath` flag) is unchanged and the DSL types typecheck as before. Only the runtime URLClassLoader is affected, forcing `sbt.*` class references inside the REPL to resolve via parent delegation and reach sbt's own singleton copies. **Test** Update `project/scala3-console-project` to write a marker file from the REPL's `initialCommands` via `Files.writeString(path, currentState.toString.length.toString + ...)`. If any binding is null, the `toString` throws an NPE, the REPL swallows it, the marker is never written, and `$ exists` fails. The test now verifies the REPL actually sees non-null bindings, not just that `consoleProject` starts successfully. |
||
|---|---|---|
| .. | ||
| src | ||