diff --git a/nucleus/admin/cli/pom.xml b/nucleus/admin/cli/pom.xml
index 6cc43b33032..66eb49217a7 100755
--- a/nucleus/admin/cli/pom.xml
+++ b/nucleus/admin/cli/pom.xml
@@ -166,7 +166,7 @@
${project.version}
- jline
+ org.jline
jline
diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/CLICommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/CLICommand.java
index 274dfe04552..1853c6df131 100644
--- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/CLICommand.java
+++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/CLICommand.java
@@ -37,7 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
-// Portions Copyright [2018] Payara Foundation and/or affiliates
+// Portions Copyright [2018-2019] Payara Foundation and/or affiliates
package com.sun.enterprise.admin.cli;
@@ -46,7 +46,9 @@
import java.lang.annotation.Annotation;
import java.util.logging.*;
-import jline.console.ConsoleReader;
+import org.jline.reader.LineReader;
+import org.jline.reader.LineReaderBuilder;
+import org.jline.terminal.TerminalBuilder;
import org.jvnet.hk2.annotations.Contract;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.config.InjectionManager;
@@ -912,10 +914,12 @@ protected void prevalidate() throws CommandException {
/*
* Check for missing options and operands.
*/
- ConsoleReader cons = null;
+ LineReader reader = null;
if (programOpts.isInteractive()) {
try {
- cons = new ConsoleReader(System.in, System.out, null);
+ reader = LineReaderBuilder.builder()
+ .terminal(TerminalBuilder.builder().streams(System.in, System.out).build())
+ .build();
} catch (IOException ioe) {
logger.log(Level.WARNING, "Error instantiating console", ioe);
}
@@ -935,15 +939,10 @@ protected void prevalidate() throws CommandException {
continue;
}
// if option isn't set, prompt for it (if interactive)
- if (getOption(opt.getName()) == null && cons != null && !missingOption) {
- cons.setPrompt(strings.get("optionPrompt", lc(opt.getName())));
- try {
- String val = cons.readLine();
- if (ok(val)) {
- options.set(opt.getName(), val);
- }
- } catch (IOException ioe) {
- logger.log(Level.WARNING, "Error reading input", ioe);
+ if (getOption(opt.getName()) == null && reader != null && !missingOption) {
+ String val = reader.readLine(strings.get("optionPrompt", lc(opt.getName())));
+ if (ok(val)) {
+ options.set(opt.getName(), val);
}
}
// if it's still not set, that's an error
@@ -967,16 +966,11 @@ protected void prevalidate() throws CommandException {
operandMax = operandParam.getParam().multiple() ? Integer.MAX_VALUE : 1;
}
- if (operands.size() < operandMin && cons != null) {
- cons.setPrompt(strings.get("operandPrompt", operandParam.getName()));
- try {
- String val = cons.readLine();
- if (ok(val)) {
- operands = new ArrayList();
- operands.add(val);
- }
- } catch (IOException ioe) {
- throw new CommandValidationException("Error reading input", ioe);
+ if (operands.size() < operandMin && reader != null) {
+ String val = reader.readLine(strings.get("operandPrompt", operandParam.getName()));
+ if (ok(val)) {
+ operands = new ArrayList<>();
+ operands.add(val);
}
}
if (operands.size() < operandMin) {
@@ -1209,15 +1203,26 @@ private String passwordName(ParamModel opt) {
protected char[] readPassword(String prompt) {
char[] pc = null;
- try (ConsoleReader consoleReader = new ConsoleReader(System.in, System.out, null)) {
+ LineReader lineReader = null;
+ try {
+ lineReader = LineReaderBuilder.builder()
+ .terminal(TerminalBuilder.builder()
+ .streams(System.in, System.out).build()).build();
// Don't echo anything when reading
- char echoCharacter = 0;
- consoleReader.setEchoCharacter(echoCharacter);
+ lineReader.getTerminal().echo(false);
- String line = consoleReader.readLine(prompt);
+ String line = lineReader.readLine(prompt);
pc = line.toCharArray();
} catch (IOException ioe) {
logger.log(Level.WARNING, "IOException reading password.", ioe);
+ } finally {
+ if (lineReader != null && lineReader.getTerminal() != null) {
+ try {
+ lineReader.getTerminal().close();
+ } catch (IOException ioe) {
+ logger.log(Level.WARNING, "IOException reading password.", ioe);
+ }
+ }
}
return pc;
diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/MultimodeCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/MultimodeCommand.java
index a94e75a9911..1d8f667902a 100644
--- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/MultimodeCommand.java
+++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/MultimodeCommand.java
@@ -1,365 +1,360 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License"). You
- * may not use this file except in compliance with the License. You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt. See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
- *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
- *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license." If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above. However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
- */
-// Portions Copyright [2018] Payara Foundation and/or affiliates
-
-package com.sun.enterprise.admin.cli;
-
-import static com.sun.enterprise.admin.cli.CLICommand.ERROR;
-import java.io.*;
-import java.util.*;
-
-import org.jvnet.hk2.annotations.Service;
-import org.glassfish.api.Param;
-import org.glassfish.api.admin.*;
-import org.glassfish.api.admin.CommandModel.ParamModel;
-import org.glassfish.hk2.api.ActiveDescriptor;
-import org.glassfish.hk2.api.DynamicConfiguration;
-import org.glassfish.hk2.api.DynamicConfigurationService;
-import org.glassfish.hk2.api.PerLookup;
-import org.glassfish.hk2.api.ServiceLocator;
-import org.glassfish.hk2.utilities.BuilderHelper;
-
-import com.sun.enterprise.admin.util.*;
-import com.sun.enterprise.universal.i18n.LocalStringsImpl;
-import java.util.logging.Level;
-
-import javax.inject.Inject;
-import jline.console.ConsoleReader;
-import jline.console.completer.Completer;
-import jline.console.completer.StringsCompleter;
-
-/**
- * A scaled-down implementation of multi-mode command.
- *
- * @author केदार(km@dev.java.net)
- * @author Bill Shannon
- */
-@Service(name = "multimode")
-@PerLookup
-public class MultimodeCommand extends CLICommand {
-
- @Inject
- private ServiceLocator habitat;
- @Inject
- private CLIContainer container;
- @Param(optional = true, shortName = "f")
- private File file;
- @Param(name = "printprompt", optional = true)
- private Boolean printPromptOpt;
- private boolean printPrompt;
- @Param(optional = true)
- private String encoding;
- private boolean echo; // saved echo flag
- private static final LocalStringsImpl strings = new LocalStringsImpl(MultimodeCommand.class);
-
- private static final String ASADMIN = "asadmin";
-
- /**
- * The validate method validates that the type and quantity of parameters
- * and operands matches the requirements for this command. The validate
- * method supplies missing options from the environment.
- * @throws CommandException
- * @throws CommandValidationException
- */
- @Override
- protected void validate() throws CommandException, CommandValidationException {
- if (printPromptOpt != null) {
- printPrompt = printPromptOpt;
- } else {
- printPrompt = programOpts.isInteractive();
- }
- /*
- * Save value of --echo because CLICommand will reset it
- * before calling our executeCommand method but we want it
- * to also apply to all commands in multimode.
- */
- echo = programOpts.isEcho();
- }
-
- /**
- * In the usage message modify the --printprompt option to have a default
- * based on the --interactive option.
- * @return
- */
- @Override
- protected Collection usageOptions() {
- Collection opts = commandModel.getParameters();
- Set uopts = new LinkedHashSet();
- ParamModel p = new CommandModelData.ParamModelData("printprompt", boolean.class, true, Boolean.toString(programOpts.isInteractive()));
- for (ParamModel pm : opts) {
- if (pm.getName().equals("printprompt")) {
- uopts.add(p);
- } else {
- uopts.add(pm);
- }
- }
- return uopts;
- }
-
- @Override
- protected int executeCommand() throws CommandException, CommandValidationException {
- ConsoleReader reader = null;
- programOpts.setEcho(echo); // restore echo flag, saved in validate
- try {
- checkToDisableJLineLogging();
- if (file == null) {
- System.out.println(strings.get("multimodeIntro"));
- reader = new ConsoleReader(ASADMIN, System.in, System.out, null, encoding);
- } else {
- printPrompt = false;
- if (!file.canRead()) {
- throw new CommandException("File: " + file + " can not be read");
- }
- OutputStream out = new OutputStream() {
-
- @Override
- public void write(int b) throws IOException {
- return;
- }
-
- @Override
- public void write(byte[] b) throws IOException {
- return;
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- return;
- }
- };
- reader = new ConsoleReader(ASADMIN, new FileInputStream(file), out, null, encoding);
- }
-
- reader.setBellEnabled(false);
- reader.addCompleter(getAllCommandsCompleter());
-
- return executeCommands(reader);
- }
- catch (IOException e) {
- throw new CommandException(e);
- }
- finally {
- try {
- if (file != null && reader != null)
- reader.close();
- }
- catch (Exception e) {
- // ignore it
- }
- }
- }
-
- private static void checkToDisableJLineLogging(){
- if (Boolean.getBoolean("fish.payara.admin.command.jline.log.disable")) {
- System.setProperty("jline.log.jul", "false");
- final OutputStream noOpOutputStream = new OutputStream() {
- @Override
- public void write(int b) throws IOException {
- //NO-OP
- }
- };
- jline.internal.Log.setOutput(new PrintStream(noOpOutputStream));
- }
- }
-
- private static void atomicReplace(ServiceLocator locator, ProgramOptions options) {
- DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
- DynamicConfiguration config = dcs.createDynamicConfiguration();
-
- config.addUnbindFilter(BuilderHelper.createContractFilter(ProgramOptions.class.getName()));
- ActiveDescriptor desc = BuilderHelper.createConstantDescriptor(options, null, ProgramOptions.class);
- config.addActiveDescriptor(desc);
-
- config.commit();
- }
-
- /**
- * Read commands from the specified BufferedReader and execute them. If
- * printPrompt is set, prompt first.
- *
- * @return the exit code of the last command executed
- */
- private int executeCommands(ConsoleReader reader) throws CommandException, CommandValidationException, IOException {
- String line = null;
- int rc = 0;
-
- /*
- * Any program options we start with are copied to the environment
- * to serve as defaults for commands we run, and then we give each
- * command an empty program options.
- */
- programOpts.toEnvironment(env);
- String prompt = programOpts.getCommandName() + "> ";
- for (;;) {
- if (printPrompt) {
- line = reader.readLine(prompt);
- } else {
- line = reader.readLine();
- }
- if (line == null) {
- if (printPrompt)
- System.out.println();
- break;
- }
-
- if (line.trim().startsWith("#")){ // ignore comment lines
- continue;
- }
-
- String[] args;
- try {
- args = getArgs(line);
- } catch (ArgumentTokenizer.ArgumentException ex) {
- logger.info(ex.getMessage());
- continue;
- }
-
- if (args.length == 0) {
- continue;
- }
-
- String command = args[0];
- if (command.length() == 0) {
- continue;
- }
-
- // handle built-in exit and quit commands
- // XXX - care about their arguments?
- if (command.equals("exit") || command.equals("quit")){
- break;
- }
-
- CLICommand cmd = null;
- ProgramOptions po = null;
- try {
- /*
- * Every command gets its own copy of program options
- * so that any program options specified in its
- * command line options don't effect other commands.
- * But all commands share the same environment.
- */
- po = new ProgramOptions(env);
- // copy over AsadminMain info
- po.setClassPath(programOpts.getClassPath());
- po.setClassName(programOpts.getClassName());
- po.setCommandName(programOpts.getCommandName());
- // remove the old one and replace it
- atomicReplace(habitat, po);
-
- cmd = CLICommand.getCommand(habitat, command);
- rc = cmd.execute(args);
- }
- catch (CommandValidationException cve) {
- logger.severe(cve.getMessage());
- if (cmd != null) {
- logger.severe(cmd.getUsage());
- }
- rc = ERROR;
- }
- catch (InvalidCommandException ice) {
- // find closest match with local or remote commands
- logger.severe(ice.getMessage());
- try {
- if(po != null) // many layers below, null WILL be de-referenced.
- CLIUtil.displayClosestMatch(command,
- CLIUtil.getAllCommands(container, po, env),
- strings.get("ClosestMatchedLocalAndRemoteCommands"), logger);
- }
- catch (InvalidCommandException e) {
- // not a big deal if we cannot help
- }
- rc = ERROR;
- }
- catch (CommandException ce) {
- if (ce.getCause() instanceof java.net.ConnectException) {
- // find closest match with local commands
- logger.severe(ce.getMessage());
- try {
- CLIUtil.displayClosestMatch(command,
- CLIUtil.getLocalCommands(container),
- strings.get("ClosestMatchedLocalCommands"), logger);
- }
- catch (InvalidCommandException e) {
- logger.info(strings.get("InvalidRemoteCommand", command));
- }
- } else {
- logger.severe(ce.getMessage());
- }
- rc = ERROR;
- } finally {
- // restore the original program options
- // XXX - is this necessary?
- atomicReplace(habitat, programOpts);
- }
-
- // XXX - this duplicates code in AsadminMain, refactor it
- switch (rc) {
- case SUCCESS:
- if (!programOpts.isTerse())
- logger.log(Level.FINE, strings.get("CommandSuccessful", command));
- break;
-
- case ERROR:
- case INVALID_COMMAND_ERROR:
- case CONNECTION_ERROR:
- default:
- logger.log(Level.FINE, strings.get("CommandUnSuccessful", command));
- break;
- }
- CLIUtil.writeCommandToDebugLog(programOpts.getCommandName() + "[multimode]", env, args, rc);
- }
- return rc;
- }
-
- private String[] getArgs(String line) throws ArgumentTokenizer.ArgumentException {
-
- List args = new ArrayList();
- ArgumentTokenizer t = new ArgumentTokenizer(line);
- while (t.hasMoreTokens()) {
- args.add(t.nextToken());
- }
- return args.toArray(new String[args.size()]);
- }
-
- private Completer getAllCommandsCompleter(){
- return new StringsCompleter(CLIUtil.getAllCommands(container, programOpts, env));
-
- }
-}
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+// Portions Copyright [2018-2019] Payara Foundation and/or affiliates
+
+package com.sun.enterprise.admin.cli;
+
+import java.io.*;
+import java.util.*;
+
+import org.jline.reader.Completer;
+import org.jline.reader.LineReader;
+import org.jline.reader.LineReaderBuilder;
+import org.jline.reader.impl.completer.StringsCompleter;
+import org.jline.terminal.TerminalBuilder;
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.*;
+import org.glassfish.api.admin.CommandModel.ParamModel;
+import org.glassfish.hk2.api.ActiveDescriptor;
+import org.glassfish.hk2.api.DynamicConfiguration;
+import org.glassfish.hk2.api.DynamicConfigurationService;
+import org.glassfish.hk2.api.PerLookup;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.hk2.utilities.BuilderHelper;
+
+import com.sun.enterprise.admin.util.*;
+import com.sun.enterprise.universal.i18n.LocalStringsImpl;
+import java.util.logging.Level;
+
+import javax.inject.Inject;
+
+/**
+ * A scaled-down implementation of multi-mode command.
+ *
+ * @author केदार(km@dev.java.net)
+ * @author Bill Shannon
+ */
+@Service(name = "multimode")
+@PerLookup
+public class MultimodeCommand extends CLICommand {
+
+ @Inject
+ private ServiceLocator habitat;
+ @Inject
+ private CLIContainer container;
+ @Param(optional = true, shortName = "f")
+ private File file;
+ @Param(name = "printprompt", optional = true)
+ private Boolean printPromptOpt;
+ private boolean printPrompt;
+ @Param(optional = true)
+ private String encoding;
+ private boolean echo; // saved echo flag
+ private static final LocalStringsImpl strings = new LocalStringsImpl(MultimodeCommand.class);
+
+ private static final String ASADMIN = "asadmin";
+
+ /**
+ * The validate method validates that the type and quantity of parameters
+ * and operands matches the requirements for this command. The validate
+ * method supplies missing options from the environment.
+ * @throws CommandException
+ * @throws CommandValidationException
+ */
+ @Override
+ protected void validate() throws CommandException, CommandValidationException {
+ if (printPromptOpt != null) {
+ printPrompt = printPromptOpt;
+ } else {
+ printPrompt = programOpts.isInteractive();
+ }
+ /*
+ * Save value of --echo because CLICommand will reset it
+ * before calling our executeCommand method but we want it
+ * to also apply to all commands in multimode.
+ */
+ echo = programOpts.isEcho();
+ }
+
+ /**
+ * In the usage message modify the --printprompt option to have a default
+ * based on the --interactive option.
+ * @return
+ */
+ @Override
+ protected Collection usageOptions() {
+ Collection opts = commandModel.getParameters();
+ Set uopts = new LinkedHashSet();
+ ParamModel p = new CommandModelData.ParamModelData("printprompt", boolean.class, true, Boolean.toString(programOpts.isInteractive()));
+ for (ParamModel pm : opts) {
+ if (pm.getName().equals("printprompt")) {
+ uopts.add(p);
+ } else {
+ uopts.add(pm);
+ }
+ }
+ return uopts;
+ }
+
+ @Override
+ protected int executeCommand() throws CommandException, CommandValidationException {
+ LineReader reader = null;
+ programOpts.setEcho(echo); // restore echo flag, saved in validate
+ try {
+ if (file == null) {
+ System.out.println(strings.get("multimodeIntro"));
+
+ reader = LineReaderBuilder.builder()
+ .terminal(TerminalBuilder.builder()
+ .streams(System.in, System.out).encoding(encoding).build())
+ .appName(ASADMIN)
+ .build();
+ } else {
+ printPrompt = false;
+ if (!file.canRead()) {
+ throw new CommandException("File: " + file + " can not be read");
+ }
+ OutputStream out = new OutputStream() {
+
+ @Override
+ public void write(int b) throws IOException {
+ return;
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ return;
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ return;
+ }
+ };
+
+ reader = LineReaderBuilder.builder()
+ .completer(getAllCommandsCompleter())
+ .terminal(TerminalBuilder.builder().encoding(encoding)
+ .streams(new FileInputStream(file), out).build())
+ .appName(ASADMIN)
+ .build();
+ }
+
+ return executeCommands(reader);
+ }
+ catch (IOException e) {
+ throw new CommandException(e);
+ }
+ finally {
+ try {
+ if (file != null && reader != null && reader.getTerminal() != null)
+ reader.getTerminal().close();
+ }
+ catch (Exception e) {
+ // ignore it
+ }
+ }
+ }
+
+ private static void atomicReplace(ServiceLocator locator, ProgramOptions options) {
+ DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
+ DynamicConfiguration config = dcs.createDynamicConfiguration();
+
+ config.addUnbindFilter(BuilderHelper.createContractFilter(ProgramOptions.class.getName()));
+ ActiveDescriptor desc = BuilderHelper.createConstantDescriptor(options, null, ProgramOptions.class);
+ config.addActiveDescriptor(desc);
+
+ config.commit();
+ }
+
+ /**
+ * Read commands from the specified BufferedReader and execute them. If
+ * printPrompt is set, prompt first.
+ *
+ * @return the exit code of the last command executed
+ */
+ private int executeCommands(LineReader reader) throws IOException {
+ String line;
+ int rc = 0;
+
+ /*
+ * Any program options we start with are copied to the environment
+ * to serve as defaults for commands we run, and then we give each
+ * command an empty program options.
+ */
+ programOpts.toEnvironment(env);
+ String prompt = programOpts.getCommandName() + "> ";
+ for (;;) {
+ if (printPrompt) {
+ line = reader.readLine(prompt);
+ } else {
+ line = reader.readLine();
+ }
+ if (line == null) {
+ if (printPrompt)
+ System.out.println();
+ break;
+ }
+
+ if (line.trim().startsWith("#")){ // ignore comment lines
+ continue;
+ }
+
+ String[] args;
+ try {
+ args = getArgs(line);
+ } catch (ArgumentTokenizer.ArgumentException ex) {
+ logger.info(ex.getMessage());
+ continue;
+ }
+
+ if (args.length == 0) {
+ continue;
+ }
+
+ String command = args[0];
+ if (command.length() == 0) {
+ continue;
+ }
+
+ // handle built-in exit and quit commands
+ // XXX - care about their arguments?
+ if (command.equals("exit") || command.equals("quit")){
+ break;
+ }
+
+ CLICommand cmd = null;
+ ProgramOptions po = null;
+ try {
+ /*
+ * Every command gets its own copy of program options
+ * so that any program options specified in its
+ * command line options don't effect other commands.
+ * But all commands share the same environment.
+ */
+ po = new ProgramOptions(env);
+ // copy over AsadminMain info
+ po.setClassPath(programOpts.getClassPath());
+ po.setClassName(programOpts.getClassName());
+ po.setCommandName(programOpts.getCommandName());
+ // remove the old one and replace it
+ atomicReplace(habitat, po);
+
+ cmd = CLICommand.getCommand(habitat, command);
+ rc = cmd.execute(args);
+ }
+ catch (CommandValidationException cve) {
+ logger.severe(cve.getMessage());
+ if (cmd != null) {
+ logger.severe(cmd.getUsage());
+ }
+ rc = ERROR;
+ }
+ catch (InvalidCommandException ice) {
+ // find closest match with local or remote commands
+ logger.severe(ice.getMessage());
+ try {
+ if(po != null) // many layers below, null WILL be de-referenced.
+ CLIUtil.displayClosestMatch(command,
+ CLIUtil.getAllCommands(container, po, env),
+ strings.get("ClosestMatchedLocalAndRemoteCommands"), logger);
+ }
+ catch (InvalidCommandException e) {
+ // not a big deal if we cannot help
+ }
+ rc = ERROR;
+ }
+ catch (CommandException ce) {
+ if (ce.getCause() instanceof java.net.ConnectException) {
+ // find closest match with local commands
+ logger.severe(ce.getMessage());
+ try {
+ CLIUtil.displayClosestMatch(command,
+ CLIUtil.getLocalCommands(container),
+ strings.get("ClosestMatchedLocalCommands"), logger);
+ }
+ catch (InvalidCommandException e) {
+ logger.info(strings.get("InvalidRemoteCommand", command));
+ }
+ } else {
+ logger.severe(ce.getMessage());
+ }
+ rc = ERROR;
+ } finally {
+ // restore the original program options
+ // XXX - is this necessary?
+ atomicReplace(habitat, programOpts);
+ }
+
+ // XXX - this duplicates code in AsadminMain, refactor it
+ switch (rc) {
+ case SUCCESS:
+ if (!programOpts.isTerse())
+ logger.log(Level.FINE, strings.get("CommandSuccessful", command));
+ break;
+
+ case ERROR:
+ case INVALID_COMMAND_ERROR:
+ case CONNECTION_ERROR:
+ default:
+ logger.log(Level.FINE, strings.get("CommandUnSuccessful", command));
+ break;
+ }
+ CLIUtil.writeCommandToDebugLog(programOpts.getCommandName() + "[multimode]", env, args, rc);
+ }
+ return rc;
+ }
+
+ private String[] getArgs(String line) throws ArgumentTokenizer.ArgumentException {
+
+ List args = new ArrayList();
+ ArgumentTokenizer t = new ArgumentTokenizer(line);
+ while (t.hasMoreTokens()) {
+ args.add(t.nextToken());
+ }
+ return args.toArray(new String[args.size()]);
+ }
+
+ private Completer getAllCommandsCompleter(){
+ return new StringsCompleter(CLIUtil.getAllCommands(container, programOpts, env));
+
+ }
+}
diff --git a/nucleus/osgi-platforms/osgi-cli-interactive/pom.xml b/nucleus/osgi-platforms/osgi-cli-interactive/pom.xml
index 1633c4746dd..c2da771c69e 100644
--- a/nucleus/osgi-platforms/osgi-cli-interactive/pom.xml
+++ b/nucleus/osgi-platforms/osgi-cli-interactive/pom.xml
@@ -41,6 +41,7 @@
Portions Copyright [2019] [Payara Foundation and/or its affiliates]
-->
+
4.0.0
@@ -77,7 +78,7 @@
${project.version}
- jline
+ org.jline
jline
diff --git a/nucleus/osgi-platforms/osgi-cli-interactive/src/main/java/org/glassfish/osgi/cli/interactive/LocalOSGiShellCommand.java b/nucleus/osgi-platforms/osgi-cli-interactive/src/main/java/org/glassfish/osgi/cli/interactive/LocalOSGiShellCommand.java
index bc19efeaa89..50026450066 100644
--- a/nucleus/osgi-platforms/osgi-cli-interactive/src/main/java/org/glassfish/osgi/cli/interactive/LocalOSGiShellCommand.java
+++ b/nucleus/osgi-platforms/osgi-cli-interactive/src/main/java/org/glassfish/osgi/cli/interactive/LocalOSGiShellCommand.java
@@ -37,6 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
+// Portions Copyright [2019] Payara Foundation and/or affiliates
package org.glassfish.osgi.cli.interactive;
@@ -60,10 +61,6 @@
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
-import jline.console.ConsoleReader;
-import jline.console.completer.Completer;
-import jline.console.completer.NullCompleter;
-import jline.console.completer.StringsCompleter;
import org.glassfish.api.I18n;
import org.glassfish.api.Param;
import org.glassfish.api.admin.CommandException;
@@ -76,6 +73,13 @@
import org.glassfish.hk2.api.PerLookup;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.BuilderHelper;
+import org.jline.reader.Completer;
+import org.jline.reader.LineReader;
+import org.jline.reader.LineReaderBuilder;
+import org.jline.reader.impl.completer.NullCompleter;
+import org.jline.reader.impl.completer.StringsCompleter;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.TerminalBuilder;
import org.jvnet.hk2.annotations.Service;
/**
@@ -225,9 +229,8 @@ protected Collection usageOptions() {
}
@Override
- protected int executeCommand()
- throws CommandException, CommandValidationException {
- ConsoleReader reader = null;
+ protected int executeCommand() throws CommandException {
+ LineReader reader;
if(cmd == null) {
throw new CommandException("Remote command 'osgi' is not available.");
@@ -247,9 +250,11 @@ protected int executeCommand()
if (file == null) {
System.out.println(strings.get("multimodeIntro"));
- reader = new ConsoleReader(REMOTE_COMMAND,
- new FileInputStream(FileDescriptor.in), System.out,
- null);
+ reader = LineReaderBuilder.builder()
+ .terminal(TerminalBuilder.builder()
+ .streams(new FileInputStream(FileDescriptor.in), System.out).build())
+ .appName(REMOTE_COMMAND)
+ .build();
} else {
printPrompt = false;
if (!file.canRead()) {
@@ -275,14 +280,14 @@ public void write(byte[] b, int off, int len) throws IOException {
}
};
- reader = new ConsoleReader(REMOTE_COMMAND,
- new FileInputStream(file), out,
- null);
+ Terminal terminal = TerminalBuilder.builder().streams(new FileInputStream(file), out).build();
+ reader = LineReaderBuilder.builder()
+ .completer(getCommandCompleter())
+ .terminal(terminal)
+ .appName(REMOTE_COMMAND)
+ .build();
}
- reader.setBellEnabled(false);
- reader.addCompleter(getCommandCompleter());
-
return executeCommands(reader);
} catch (IOException e) {
throw new CommandException(e);
@@ -376,7 +381,7 @@ private Completer getCommandCompleter() {
*
* @return the exit code of the last command executed
*/
- private int executeCommands(ConsoleReader reader)
+ private int executeCommands(LineReader reader)
throws CommandException, CommandValidationException, IOException {
String line = null;
int rc = 0;
diff --git a/nucleus/packager/nucleus/pom.xml b/nucleus/packager/nucleus/pom.xml
index 2113c9a9084..7b631bd1c7c 100644
--- a/nucleus/packager/nucleus/pom.xml
+++ b/nucleus/packager/nucleus/pom.xml
@@ -247,7 +247,7 @@
true
- jline
+ org.jline
jline
true
diff --git a/nucleus/pom.xml b/nucleus/pom.xml
index b18bfb51010..2b391f31b43 100644
--- a/nucleus/pom.xml
+++ b/nucleus/pom.xml
@@ -326,6 +326,7 @@
0.31.0
+ 3.10.0
6.0.1
@@ -1348,9 +1349,9 @@ Parent is ${project.parent}
- jline
+ org.jline
jline
- 2.14.6
+ ${jline.version}
org.fusesource.hawtjni