This is an automated email from the ASF dual-hosted git repository.

mpochatkin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new dce1dde501d IGNITE-28062 Entering REPL from connect command fails 
(#7705)
dce1dde501d is described below

commit dce1dde501d5091a20485d85e50a71b9886b4af9
Author: Vadim Pakhnushev <[email protected]>
AuthorDate: Mon Mar 16 19:48:13 2026 +0300

    IGNITE-28062 Entering REPL from connect command fails (#7705)
---
 .../connect/ItConnectNonReplCommandTest.java       |  3 ++-
 .../ItSqlReplCommandNotInitializedClusterTest.java |  3 ++-
 .../cli/commands/sql/ItSqlReplCommandTest.java     |  3 ++-
 .../java/org/apache/ignite/internal/cli/Main.java  | 23 ++--------------------
 .../apache/ignite/internal/cli/ReplManager.java    | 16 ++++++++++++---
 .../cli/commands/connect/ConnectCommand.java       |  2 +-
 .../cli/commands/sql/SqlExecReplCommand.java       |  2 +-
 .../core/repl/executor/ReplExecutorProvider.java   | 10 +++++++++-
 .../repl/executor/ReplExecutorProviderImpl.java    | 14 +++++--------
 9 files changed, 37 insertions(+), 39 deletions(-)

diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/connect/ItConnectNonReplCommandTest.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/connect/ItConnectNonReplCommandTest.java
index 7fb56629aa7..95a4907ad57 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/connect/ItConnectNonReplCommandTest.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/connect/ItConnectNonReplCommandTest.java
@@ -24,6 +24,7 @@ import org.apache.ignite.internal.cli.ReplManager;
 import org.apache.ignite.internal.cli.commands.TopLevelCliCommand;
 import org.apache.ignite.internal.cli.core.repl.EventListeningActivationPoint;
 import org.junit.jupiter.api.Test;
+import picocli.CommandLine;
 
 class ItConnectNonReplCommandTest extends ItConnectCommandTest {
     @Inject
@@ -39,7 +40,7 @@ class ItConnectNonReplCommandTest extends 
ItConnectCommandTest {
             }
 
             @Override
-            public void startReplMode() {
+            public void startReplMode(CommandLine.IFactory factory) {
                 // Emulate repl start by asking a question.
                 question.askQuestionOnReplStart();
             }
diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/sql/ItSqlReplCommandNotInitializedClusterTest.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/sql/ItSqlReplCommandNotInitializedClusterTest.java
index 60f27c8da3c..4c8cda2486b 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/sql/ItSqlReplCommandNotInitializedClusterTest.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/sql/ItSqlReplCommandNotInitializedClusterTest.java
@@ -30,6 +30,7 @@ import org.apache.ignite.internal.cli.core.repl.SessionInfo;
 import org.apache.ignite.internal.cli.core.repl.executor.ReplExecutorProvider;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
+import picocli.CommandLine.IFactory;
 
 /** Tests for {@link SqlReplCommand} with not initialized cluster. */
 public class ItSqlReplCommandNotInitializedClusterTest extends 
CliIntegrationTest {
@@ -38,7 +39,7 @@ public class ItSqlReplCommandNotInitializedClusterTest 
extends CliIntegrationTes
     @Bean
     @Replaces(ReplExecutorProvider.class)
     public ReplExecutorProvider replExecutorProvider() {
-        return () -> repl -> {};
+        return (IFactory factory) -> repl -> {};
     }
 
     @Bean
diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/sql/ItSqlReplCommandTest.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/sql/ItSqlReplCommandTest.java
index 33bdfad7d4a..c58d7b10b56 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/sql/ItSqlReplCommandTest.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/sql/ItSqlReplCommandTest.java
@@ -25,6 +25,7 @@ import org.apache.ignite.internal.cli.CliIntegrationTest;
 import org.apache.ignite.internal.cli.core.repl.executor.ReplExecutorProvider;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
+import picocli.CommandLine.IFactory;
 
 /** Tests for {@link SqlReplCommand}. */
 class ItSqlReplCommandTest extends CliIntegrationTest {
@@ -161,6 +162,6 @@ class ItSqlReplCommandTest extends CliIntegrationTest {
     @Bean
     @Replaces(ReplExecutorProvider.class)
     public ReplExecutorProvider replExecutorProvider() {
-        return () -> repl -> {};
+        return (IFactory factory) -> repl -> {};
     }
 }
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/Main.java 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/Main.java
index 2461a699b17..ad679cf9ea9 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/Main.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/Main.java
@@ -34,13 +34,9 @@ import 
org.apache.ignite.internal.cli.config.ConfigDefaultValueProvider;
 import org.apache.ignite.internal.cli.config.ConfigManagerProvider;
 import org.apache.ignite.internal.cli.config.StateFolderProvider;
 import 
org.apache.ignite.internal.cli.core.exception.handler.PicocliExecutionExceptionHandler;
-import 
org.apache.ignite.internal.cli.core.flow.question.JlineQuestionWriterReaderFactory;
-import org.apache.ignite.internal.cli.core.flow.question.QuestionAskerFactory;
-import 
org.apache.ignite.internal.cli.core.repl.executor.ReplExecutorProviderImpl;
 import org.apache.ignite.internal.cli.core.style.AnsiStringSupport;
 import org.apache.ignite.internal.cli.core.style.ColorScheme;
 import org.fusesource.jansi.AnsiConsole;
-import org.jline.terminal.Terminal;
 import picocli.CommandLine;
 import picocli.CommandLine.Help.Ansi;
 
@@ -67,8 +63,6 @@ public class Main {
             if (interactiveMode) {
                 // REPL mode: full initialization with Jansi ANSI console and 
JLine terminal.
                 AnsiConsole.systemInstall();
-                initReplExecutor(micronautFactory);
-                initQuestionAsker(micronautFactory);
                 enterRepl(micronautFactory);
             } else {
                 // Non-interactive mode: skip JLine terminal initialization 
for faster startup.
@@ -105,30 +99,17 @@ public class Main {
         AnsiStringSupport.setColorSchemeProvider(() -> {
             String schemeName = 
configProvider.get().getCurrentProperty("ignite.cli.color-scheme");
             ColorScheme scheme = ColorScheme.fromString(schemeName);
-            ColorScheme result = scheme != null ? scheme : 
ColorScheme.SOLARIZED_DARK;
-            return result;
+            return scheme != null ? scheme : ColorScheme.SOLARIZED_DARK;
         });
     }
 
-    /** Needed for immediate REPL mode and for running a command which will 
stay in REPL mode so we need to init it once. */
-    private static void initReplExecutor(MicronautFactory micronautFactory) 
throws Exception {
-        ReplExecutorProviderImpl replExecutorProvider = 
micronautFactory.create(ReplExecutorProviderImpl.class);
-        replExecutorProvider.injectFactory(micronautFactory);
-    }
-
-    /** Creates an instance of the terminal and sets the question asker 
factory. */
-    private static void initQuestionAsker(MicronautFactory micronautFactory) 
throws Exception {
-        Terminal terminal = micronautFactory.create(Terminal.class);
-        QuestionAskerFactory.setWriterReaderFactory(new 
JlineQuestionWriterReaderFactory(terminal));
-    }
-
     private static void enterRepl(MicronautFactory micronautFactory) throws 
Exception {
         VersionProvider versionProvider = 
micronautFactory.create(VersionProvider.class);
         System.out.println(banner(versionProvider));
 
         ReplManager replManager = micronautFactory.create(ReplManager.class);
         replManager.subscribe();
-        replManager.startReplMode();
+        replManager.startReplMode(micronautFactory);
     }
 
     private static int executeCommand(String[] args, MicronautFactory 
micronautFactory) throws Exception {
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/ReplManager.java 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/ReplManager.java
index df3c8b568db..f67247b81d2 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/ReplManager.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/ReplManager.java
@@ -24,11 +24,16 @@ import 
org.apache.ignite.internal.cli.commands.questions.ConnectToClusterQuestio
 import org.apache.ignite.internal.cli.core.call.CallExecutionPipeline;
 import org.apache.ignite.internal.cli.core.call.StringCallInput;
 import 
org.apache.ignite.internal.cli.core.exception.handler.DefaultExceptionHandlers;
+import 
org.apache.ignite.internal.cli.core.flow.question.JlineQuestionWriterReaderFactory;
+import org.apache.ignite.internal.cli.core.flow.question.QuestionAskerFactory;
 import org.apache.ignite.internal.cli.core.repl.EventListeningActivationPoint;
 import org.apache.ignite.internal.cli.core.repl.Repl;
 import org.apache.ignite.internal.cli.core.repl.SessionDefaultValueProvider;
 import org.apache.ignite.internal.cli.core.repl.executor.ReplExecutorProvider;
 import org.apache.ignite.internal.cli.core.repl.prompt.PromptProvider;
+import org.jline.terminal.Terminal;
+import picocli.CommandLine;
+import picocli.CommandLine.IFactory;
 
 /**
  * Class which runs main REPL mode, it's used both when starting directly into 
the REPL mode and from the `connect` command.
@@ -50,8 +55,11 @@ public class ReplManager {
     @Inject
     private EventListeningActivationPoint eventListeningActivationPoint;
 
+    @Inject
+    private Terminal terminal;
+
     /**
-     * Subscribes to CLI events. Should be called before {@link 
#startReplMode()}.
+     * Subscribes to CLI events. Should be called before {@link 
#startReplMode(IFactory)} ()}.
      */
     public void subscribe() {
         eventListeningActivationPoint.subscribe();
@@ -60,8 +68,10 @@ public class ReplManager {
     /**
      * Enters REPL mode.
      */
-    public void startReplMode() {
-        replExecutorProvider.get().execute(Repl.builder()
+    public void startReplMode(CommandLine.IFactory factory) {
+        QuestionAskerFactory.setWriterReaderFactory(new 
JlineQuestionWriterReaderFactory(terminal));
+
+        replExecutorProvider.get(factory).execute(Repl.builder()
                 .withPromptProvider(promptProvider)
                 .withCommandClass(TopLevelCliReplCommand.class)
                 .withDefaultValueProvider(defaultValueProvider)
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/connect/ConnectCommand.java
 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/connect/ConnectCommand.java
index 042144c5e92..b970d409e20 100644
--- 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/connect/ConnectCommand.java
+++ 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/connect/ConnectCommand.java
@@ -76,7 +76,7 @@ public class ConnectCommand extends BaseCommand implements 
Callable<Integer> {
                 .input(connectCallInput())
         );
         if (exitCode == 0) {
-            replManager.startReplMode();
+            replManager.startReplMode(spec.commandLine().getFactory());
         }
         return exitCode;
     }
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/sql/SqlExecReplCommand.java
 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/sql/SqlExecReplCommand.java
index aa247fb207b..e168e231628 100644
--- 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/sql/SqlExecReplCommand.java
+++ 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/sql/SqlExecReplCommand.java
@@ -154,7 +154,7 @@ public class SqlExecReplCommand extends BaseCommand 
implements Runnable {
                 SqlCompleter sqlCompleter = new SqlCompleter(schemaProvider);
                 IgniteSqlCommandCompleter sqlCommandCompleter = new 
IgniteSqlCommandCompleter();
 
-                replExecutorProvider.get().execute(Repl.builder()
+                
replExecutorProvider.get(spec.commandLine().getFactory()).execute(Repl.builder()
                         .withPromptProvider(() -> 
ansi(fg(Color.GREEN).mark("sql-cli> ")))
                         .withCompleter(new 
AggregateCompleter(sqlCommandCompleter, sqlCompleter))
                         .withCommandClass(SqlReplTopLevelCliCommand.class)
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutorProvider.java
 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutorProvider.java
index 3eef59870f0..20987eb5568 100644
--- 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutorProvider.java
+++ 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutorProvider.java
@@ -17,10 +17,18 @@
 
 package org.apache.ignite.internal.cli.core.repl.executor;
 
+import picocli.CommandLine.IFactory;
+
 /**
  * Provider of {@link ReplExecutor}.
  */
 @FunctionalInterface
 public interface ReplExecutorProvider {
-    ReplExecutor get();
+    /**
+     * Creates REPL executor.
+     *
+     * @param factory Commands factory.
+     * @return New instance of {@link ReplExecutor}.
+     */
+    ReplExecutor get(IFactory factory);
 }
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutorProviderImpl.java
 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutorProviderImpl.java
index e7009618b50..ab867121db3 100644
--- 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutorProviderImpl.java
+++ 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutorProviderImpl.java
@@ -17,11 +17,11 @@
 
 package org.apache.ignite.internal.cli.core.repl.executor;
 
-import io.micronaut.configuration.picocli.MicronautFactory;
 import jakarta.inject.Inject;
 import jakarta.inject.Singleton;
 import org.apache.ignite.internal.cli.config.ConfigManagerProvider;
 import org.jline.terminal.Terminal;
+import picocli.CommandLine.IFactory;
 import picocli.shell.jline3.PicocliCommands.PicocliCommandsFactory;
 
 /**
@@ -29,8 +29,6 @@ import 
picocli.shell.jline3.PicocliCommands.PicocliCommandsFactory;
  */
 @Singleton
 public class ReplExecutorProviderImpl implements ReplExecutorProvider {
-    private PicocliCommandsFactory factory;
-
     @Inject
     private Terminal terminal;
 
@@ -38,12 +36,10 @@ public class ReplExecutorProviderImpl implements 
ReplExecutorProvider {
     private ConfigManagerProvider configManagerProvider;
 
     @Override
-    public ReplExecutor get() {
-        return new ReplExecutorImpl(factory, terminal, configManagerProvider);
-    }
+    public ReplExecutor get(IFactory factory) {
+        PicocliCommandsFactory picocliCommandsFactory = new 
PicocliCommandsFactory(factory);
+        picocliCommandsFactory.setTerminal(terminal);
 
-    public void injectFactory(MicronautFactory micronautFactory) {
-        factory = new PicocliCommandsFactory(micronautFactory);
-        factory.setTerminal(terminal);
+        return new ReplExecutorImpl(picocliCommandsFactory, terminal, 
configManagerProvider);
     }
 }

Reply via email to