diff --git a/core-feature-pack/common/pom.xml b/core-feature-pack/common/pom.xml index 72ba90b900b..7713a3a48af 100644 --- a/core-feature-pack/common/pom.xml +++ b/core-feature-pack/common/pom.xml @@ -827,11 +827,6 @@ wildfly-version - - org.wildfly.core - wildfly-launcher - - org.wildfly.core wildfly-jar-runtime @@ -852,6 +847,11 @@ wildfly-discovery-client + + org.wildfly.launcher + wildfly-launcher + + org.wildfly.installation-manager installation-manager-api diff --git a/core-feature-pack/galleon-common/src/main/resources/packages/tools/pm/wildfly/tasks.xml b/core-feature-pack/galleon-common/src/main/resources/packages/tools/pm/wildfly/tasks.xml index 011483f6864..ccd70e6cfcd 100644 --- a/core-feature-pack/galleon-common/src/main/resources/packages/tools/pm/wildfly/tasks.xml +++ b/core-feature-pack/galleon-common/src/main/resources/packages/tools/pm/wildfly/tasks.xml @@ -6,7 +6,7 @@ --> - + diff --git a/launcher/pom.xml b/launcher/pom.xml deleted file mode 100644 index 864c3e93f96..00000000000 --- a/launcher/pom.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - 4.0.0 - - - org.wildfly.core - wildfly-core-parent - 27.0.0.Beta3-SNAPSHOT - - - wildfly-launcher - - WildFly: Launcher API - - - ${basedir}/target/fake-wildfly - ${basedir}/target/fake-wildfly.jar - - - - - - org.wildfly.core - wildfly-core-testbom - ${project.version} - pom - import - - - - - - - - org.jboss.logging - jboss-logging - provided - true - - - org.jboss.logging - jboss-logging-annotations - - provided - true - - - org.jboss.logging - jboss-logging-processor - - provided - true - - - - - junit - junit - test - - - org.jboss.modules - jboss-modules - test - - - - - - - - - maven-dependency-plugin - - - copy-deps - test-compile - - copy - - - - - org.jboss.modules - jboss-modules - jar - true - ${wildfly.launcher.home} - jboss-modules.jar - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${wildfly.launcher.home} - ${wildfly.launcher.bootable.jar} - - - - - - - - diff --git a/launcher/src/main/java/org/wildfly/core/launcher/AbstractCommandBuilder.java b/launcher/src/main/java/org/wildfly/core/launcher/AbstractCommandBuilder.java deleted file mode 100644 index 47e856b726b..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/AbstractCommandBuilder.java +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; - -import org.wildfly.core.launcher.logger.LauncherMessages; - -/** - * @author James R. Perkins - */ -@SuppressWarnings({"unused", "UnusedReturnValue"}) -abstract class AbstractCommandBuilder> extends JBossModulesCommandBuilder implements CommandBuilder { - - static final String HOME_DIR = Environment.HOME_DIR; - - private Path logDir; - private Path configDir; - - protected AbstractCommandBuilder(final Path wildflyHome, final String moduleName) { - this(wildflyHome, null, moduleName); - } - - protected AbstractCommandBuilder(final Path wildflyHome, final Jvm jvm, final String moduleName) { - super(wildflyHome, jvm, moduleName); - } - - @Override - public T setUseSecurityManager(final boolean useSecMgr) { - super.setUseSecurityManager(useSecMgr); - return getThis(); - } - - @Override - public T addModuleDir(final String moduleDir) { - super.addModuleDir(moduleDir); - return getThis(); - } - - @Override - public T addModuleDirs(final String... moduleDirs) { - super.addModuleDirs(moduleDirs); - return getThis(); - } - - @Override - public T addModuleDirs(final Iterable moduleDirs) { - super.addModuleDirs(moduleDirs); - return getThis(); - } - - @Override - public T setModuleDirs(final Iterable moduleDirs) { - super.setModuleDirs(moduleDirs); - return getThis(); - } - - @Override - public T setModuleDirs(final String... moduleDirs) { - super.setModuleDirs(moduleDirs); - return getThis(); - } - - /** - * Returns the log directory for the server. - * - * @return the log directory - */ - public Path getLogDirectory() { - if (logDir == null) { - return normalizePath(getBaseDirectory(), "log"); - } - return logDir; - } - - /** - * Sets the log directory to be used for log files. - *

- * If set to {@code null}, the default, the log directory will be resolved. - * - * @param path the path to the log directory or {@code null} to have the log directory resolved - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the directory is not a valid directory - */ - public T setLogDirectory(final String path) { - if (path == null) { - logDir = null; - return getThis(); - } - return setLogDirectory(Paths.get(path)); - } - - /** - * Sets the log directory to be used for log files. - *

- * If set to {@code null}, the default, the log directory will be resolved. - * - * @param path the path to the log directory or {@code null} to have the log directory resolved - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the directory is not a valid directory - */ - public T setLogDirectory(final Path path) { - if (path == null) { - logDir = null; - } else { - if (Files.exists(path) && !Files.isDirectory(path)) { - throw LauncherMessages.MESSAGES.invalidDirectory(path); - } - logDir = path.toAbsolutePath().normalize(); - } - return getThis(); - } - - /** - * Returns the configuration directory for the server. - * - * @return the configuration directory - */ - public Path getConfigurationDirectory() { - if (configDir == null) { - return normalizePath(getBaseDirectory(), "configuration"); - } - return configDir; - } - - /** - * Sets the configuration directory to be used for configuration files. - *

- * If set to {@code null}, the default, the configuration directory will be resolved. - * - * @param path the path to the configuration directory or {@code null} to have the configuration directory resolved - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the directory is not a valid directory - */ - public T setConfigurationDirectory(final String path) { - configDir = Environment.validateAndNormalizeDir(path, true); - return getThis(); - } - - /** - * Sets the configuration directory to be used for configuration files. - *

- * If set to {@code null}, the default, the configuration directory will be resolved. - * - * @param path the path to the configuration directory or {@code null} to have the configuration directory resolved - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the directory is not a valid directory - */ - public T setConfigurationDirectory(final Path path) { - configDir = Environment.validateAndNormalizeDir(path, true); - return getThis(); - } - - @Override - public T addServerArgument(final String arg) { - super.addServerArgument(arg); - return getThis(); - } - - @Override - public T addServerArguments(final String... args) { - super.addServerArguments(args); - return getThis(); - } - - @Override - public T addServerArguments(final Iterable args) { - super.addServerArguments(args); - return getThis(); - } - - /** - * Sets the server argument {@code --admin-only}. - * - * @return the builder - */ - public T setAdminOnly() { - return addServerArgument("--admin-only"); - } - - /** - * Sets the server argument {@code --start-mode=suspend}. - * - * @return the builder - */ - public T setStartSuspended() { - return addServerArgument("--start-mode=suspend"); - } - - /** - * Sets the system property {@code jboss.bind.address} to the address given. - *

- * This will override any previous value set via {@link #addServerArgument(String)}. - *

- * Note: This option only works if the standard system property has not been removed from the interface. If - * the system property was removed the address provided has no effect. - * - * @param address the address to set the bind address to - * - * @return the builder - */ - public T setBindAddressHint(final String address) { - setSingleServerArg("-b", address); - return getThis(); - } - - /** - * Sets the system property {@code jboss.bind.address.$INTERFACE} to the address given where {@code $INTERFACE} is - * the {@code interfaceName} parameter. For example in the default configuration passing {@code management} for the - * {@code interfaceName} parameter would result in the system property {@code jboss.bind.address.management} being - * set to the address provided. - *

- * This will override any previous value set via {@link #addServerArgument(String)}. - *

- * Note: This option only works if the standard system property has not been removed from the interface. If - * the system property was removed the address provided has no effect. - * - * @param interfaceName the name of the interface of the binding address - * @param address the address to bind the management interface to - * - * @return the builder - */ - public T setBindAddressHint(final String interfaceName, final String address) { - if (interfaceName == null) { - throw LauncherMessages.MESSAGES.nullParam("interfaceName"); - } - setSingleServerArg("-b" + interfaceName, address); - return getThis(); - } - - /** - * Sets the system property {@code jboss.default.multicast.address} to the address given. - *

- * This will override any previous value set via {@link #addServerArgument(String)}. - *

- * Note: This option only works if the standard system property has not been removed from the interface. If - * the system property was removed the address provided has no effect. - * - * @param address the address to set the multicast system property to - * - * @return the builder - */ - public T setMulticastAddressHint(final String address) { - setSingleServerArg("-u", address); - return getThis(); - } - - /** - * Adds a properties file to be passed to the server. Note that the file must exist. - * - * @param file the file to add - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the file does not exist or is not a regular file - */ - public T addPropertiesFile(final String file) { - if (file != null) { - addPropertiesFile(Paths.get(file)); - } - return getThis(); - } - - /** - * Adds a properties file to be passed to the server. Note that the file must exist. - * - * @param file the file to add - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the file does not exist or is not a regular file - */ - public T addPropertiesFile(final Path file) { - if (file != null) { - if (Files.notExists(file)) { - throw LauncherMessages.MESSAGES.pathDoesNotExist(file); - } - if (!Files.isRegularFile(file)) { - throw LauncherMessages.MESSAGES.pathNotAFile(file); - } - addServerArg("-P", file.toAbsolutePath().normalize().toString()); - } - return getThis(); - } - - /** - * Sets the properties file to use for the server or {@code null} to remove the file. Note that the file must exist. - *

- * This will override any previous values set. - *

- * - * @param file the properties file to use or {@code null} - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the file does not exist or is not a regular file - */ - public T setPropertiesFile(final String file) { - final Path path; - if (file == null) { - path = null; - } else { - path = Paths.get(file); - } - return setPropertiesFile(path); - } - - /** - * Sets the properties file to use for the server or {@code null} to remove the file. Note that the file must exist. - *

- * This will override any previous values set. - *

- * - * @param file the properties file to use or {@code null} - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the file does not exist or is not a regular file - */ - public T setPropertiesFile(final Path file) { - serverArgs.remove("-P"); - return addPropertiesFile(file); - } - - /** - * Returns the Java home directory where the java executable command can be found. - *

- * If the directory was not set the system property value, {@code java.home}, should be used. - * - * @return the path to the Java home directory - */ - public abstract Path getJavaHome(); - - /** - * Returns the command line argument that specifies the logging configuration. - * - * @param fileName the name of the configuration file - * - * @return the command line argument - */ - @SuppressWarnings("SameParameterValue") - protected String getLoggingPropertiesArgument(final String fileName) { - return "-Dlogging.configuration=file:" + normalizePath(getConfigurationDirectory(), fileName); - } - - /** - * Returns the command line argument that specifies the path the log file that should be used. - *

- * This is generally only used on the initial boot of the server in standalone. The server will rewrite the - * configuration file with hard-coded values. - * - * @param fileName the name of the file - * - * @return the command line argument - */ - protected String getBootLogArgument(final String fileName) { - return "-Dorg.jboss.boot.log.file=" + normalizePath(getLogDirectory(), fileName); - } - - - /** - * Resolves the path to the path relative to the WildFly home directory. - * - * @param path the name of the relative path - * - * @return the normalized path - */ - protected Path normalizePath(final String path) { - return environment.resolvePath(path).toAbsolutePath().normalize(); - } - - /** - * Resolves the path relative to the parent and normalizes it. - * - * @param parent the parent path - * @param path the path - * - * @return the normalized path - */ - protected Path normalizePath(final Path parent, final String path) { - return parent.resolve(path).toAbsolutePath().normalize(); - } - - /** - * Returns the base directory for the server. - *

- * Example: - * For standalone the base directory would be {@code $JBOSS_HOME/standalone}. - * - * @return the base directory - */ - public abstract Path getBaseDirectory(); - - /** - * Returns the concrete builder. - * - * @return the concrete builder - */ - protected abstract T getThis(); - - protected static void addSystemPropertyArg(final List cmd, final String key, final Object value) { - if (value != null) { - cmd.add("-D" + key + "=" + value); - } - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/Arguments.java b/launcher/src/main/java/org/wildfly/core/launcher/Arguments.java deleted file mode 100644 index 67c31ea63e3..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/Arguments.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * Stores arguments to be passed to the command line. - * - * @author James R. Perkins - */ -class Arguments { - - private final Map> map; - - Arguments() { - this.map = new LinkedHashMap<>(); - } - - /** - * Clears any arguments currently set. - */ - public void clear() { - map.clear(); - } - - /** - * {@link #parse(String) Parses} the argument and adds it to the collection of arguments ignoring {@code null} - * arguments. - * - * @param arg the argument to add - */ - public void add(final String arg) { - if (arg != null) { - final Argument argument = parse(arg); - add(argument); - } - } - - /** - * Adds a key/value pair to the collection of arguments. - *

- * If the key starts with {@code -D} it's assumed it's a system property argument and the prefix will be stripped - * from the key when checking for uniqueness. - * - * @param key the key for the argument - * @param value the value of the argument which may be {@code null} - */ - public void add(final String key, final String value) { - if (key != null) { - final Argument argument; - if (key.startsWith("-D")) { - if (value == null) { - argument = createSystemProperty(key); - } else { - argument = createSystemProperty(key, value); - } - } else { - if (value == null) { - argument = create(key); - } else { - argument = create(key, value); - } - } - add(argument); - } - } - - /** - * Sets a key/value pair to the collection of arguments. This guarantees only one value will be assigned to the - * argument key. A {@code null} value indicates the key should be removed. - *

- * If the key starts with {@code -D} it's assumed it's a system property argument and the prefix will be stripped - * from the key when checking for uniqueness. - * - * @param key the key for the argument - * @param value the value of the argument which may be {@code null} - */ - public void set(final String key, final String value) { - if (key != null) { - if (value == null) { - map.remove(key); - } else { - final Argument argument; - if (key.startsWith("-D")) { - argument = createSystemProperty(key, value); - } else { - argument = create(key, value); - } - set(argument); - } - } - } - - /** - * Sets an argument to the collection of arguments. This guarantees only one value will be assigned to the - * argument key. - * - * @param argument the argument to add - */ - public void set(final Argument argument) { - if (argument != null) { - map.put(argument.getKey(), Collections.singleton(argument)); - } - } - - /** - * Parses each argument and adds them to the collection of arguments ignoring any {@code null} values. - * - * @param args the arguments to add - * - * @see #add(String) - */ - public void addAll(final String... args) { - if (args != null) { - for (String arg : args) { - add(arg); - } - } - } - - /** - * Gets the first value for the key. - * - * @param key the key to check for the value - * - * @return the value or {@code null} if the key is not found or the value was {@code null} - */ - public String get(final String key) { - final Collection args = map.get(key); - if (args != null) { - return args.iterator().hasNext() ? args.iterator().next().getValue() : null; - } - return null; - } - - /** - * Gets the value for the key. - * - * @param key the key to check for the value - * - * @return the value or an empty collection if no values were set - */ - public Collection getArguments(final String key) { - final Collection args = map.get(key); - if (args != null) { - return new ArrayList<>(args); - } - return Collections.emptyList(); - } - - /** - * Removes the argument from the collection of arguments. - * - * @param key they key of the argument to remove - * - * @return the arguments or {@code null} if the argument was not found - */ - public Collection remove(final String key) { - return map.remove(key); - } - - /** - * Returns the arguments as a list in their command line form. - * - * @return the arguments for the command line - */ - public List asList() { - final List result = new ArrayList<>(); - for (Collection args : map.values()) { - for (Argument arg : args) { - result.add(arg.asCommandLineArgument()); - } - } - return result; - } - - /** - * Adds the argument to the collection of arguments ignoring {@code null} values. - * - * @param argument the argument to add - */ - void add(final Argument argument) { - if (argument != null) { - if (argument.multipleValuesAllowed()) { - final Collection arguments = map.computeIfAbsent(argument.getKey(), k -> new ArrayList<>()); - arguments.add(argument); - } else { - set(argument); - } - } - } - - /** - * Attempts to parse the argument into a key value pair. The separator is assumed to be {@code =}. If the value - * starts with a {@code -D} it's assumed to be a system property. - *

- * If the argument is not a traditional key/value pair separated by an {@code =} the arguments key will be the full - * argument passed in and the arguments value will be {@code null}. - * - * @param arg the argument to parse - * - * @return the parsed argument - */ - public static Argument parse(final String arg) { - if (arg.startsWith("-D")) { - final String key; - final String value; - // Check for an = - final int index = arg.indexOf('='); - if (index == -1) { - key = arg.substring(2); - value = null; - } else { - key = arg.substring(2, index); - if (arg.length() < (index + 1)) { - value = null; - } else { - value = arg.substring(index + 1); - } - } - return new SystemPropertyArgument(key, value); - } - final String key; - final String value; - // Check for an = - final int index = arg.indexOf('='); - if (index == -1) { - key = arg; - value = null; - } else { - key = arg.substring(0, index); - if (arg.length() < (index + 1)) { - value = null; - } else { - value = arg.substring(index + 1); - } - } - return new DefaultArgument(key, value); - } - - private static Argument create(final String arg) { - return new DefaultArgument(arg, null); - } - - private static Argument create(final String key, final String value) { - return new DefaultArgument(key, value); - } - - private static Argument createSystemProperty(final String arg) { - return new SystemPropertyArgument(arg, null); - } - - private static Argument createSystemProperty(final String key, final String value) { - return new SystemPropertyArgument(key, value); - } - - /** - * Represents a command line argument in a possible key/value pair. - */ - public abstract static class Argument { - private final String key; - private final String value; - - protected Argument(final String key, final String value) { - this.key = key; - this.value = value; - } - - /** - * They key to the command line argument which may be the full argument. - * - * @return the key - */ - public String getKey() { - return key; - } - - /** - * The optional value for the command line argument. - * - * @return the value or {@code null} - */ - public String getValue() { - return value; - } - - /** - * Indicates whether or not multiple values are allowed for the argument. In the case of system properties only - * one value should be set for the property. - * - * @return {@code true} if multiple values should be allowed for an argument, otherwise {@code false} - */ - public boolean multipleValuesAllowed() { - return true; - } - - /** - * The argument formatted for the command line. - * - * @return the command line argument - */ - public abstract String asCommandLineArgument(); - - @Override - public String toString() { - return asCommandLineArgument(); - } - } - - - private static final class SystemPropertyArgument extends Argument { - private final String cliArg; - - public SystemPropertyArgument(final String key, final String value) { - super(key, value); - if (value != null) { - cliArg = "-D" + key + "=" + value; - } else { - cliArg = "-D" + key; - } - } - - @Override - public boolean multipleValuesAllowed() { - return false; - } - - @Override - public String asCommandLineArgument() { - return cliArg; - } - } - - private static final class DefaultArgument extends Argument { - private final String cliArg; - - public DefaultArgument(final String key, final String value) { - super(key, value); - if (value != null) { - cliArg = key + "=" + value; - } else { - cliArg = key; - } - } - - @Override - public String asCommandLineArgument() { - return cliArg; - } - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/BootableJarCommandBuilder.java b/launcher/src/main/java/org/wildfly/core/launcher/BootableJarCommandBuilder.java deleted file mode 100644 index c9c4704cf86..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/BootableJarCommandBuilder.java +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; - -import static org.wildfly.core.launcher.JBossModulesCommandBuilder.DEFAULT_VM_ARGUMENTS; - -import org.wildfly.core.launcher.Arguments.Argument; -import static org.wildfly.core.launcher.StandaloneCommandBuilder.DEBUG_FORMAT; -import org.wildfly.core.launcher.logger.LauncherMessages; - -/** - * Builds a list of commands used to launch a bootable jar instance of WildFly. - *

- * This builder is not thread safe and the same instance should not be used in multiple threads. - * - * @author JF Denise - */ -@SuppressWarnings({"unused", "UnusedReturnValue"}) -public class BootableJarCommandBuilder implements CommandBuilder { - - private final Arguments javaOpts; - private String debugArg; - private String modulesLocklessArg; - private String modulesMetricsArg; - private final Map securityProperties; - private final Path bootableJar; - private Jvm jvm; - private final Arguments serverArgs; - - /** - * Creates a new command builder for a bootable instance. - *

- * Note the {@code bootableJar} and {@code javaHome} are not validated using - * the constructor. The static {@link - * #of(java.nio.file.Path)} is preferred. - * - * @param bootableJar the path to the bootable jar file. - */ - private BootableJarCommandBuilder(final Path bootableJar) { - this.bootableJar = bootableJar; - javaOpts = new Arguments(); - javaOpts.addAll(DEFAULT_VM_ARGUMENTS); - securityProperties = new LinkedHashMap<>(); - serverArgs = new Arguments(); - jvm = Jvm.current(); - } - - /** - * Set the directory to install the server. - * - * @param installDir Installation directory. - * @return This builder. - */ - public BootableJarCommandBuilder setInstallDir(Path installDir) { - setSingleServerArg("--install-dir", installDir.toString()); - return this; - } - - /** - * A collection of server command line arguments. - * - * @return the server arguments - */ - public List getServerArguments() { - return serverArgs.asList(); - } - - /** - * Adds the arguments to the collection of arguments that will be passed to - * the server ignoring any {@code null} arguments. - * - * @param args the arguments to add - * - * @return the builder - */ - public BootableJarCommandBuilder addServerArguments(final String... args) { - if (args != null) { - for (String arg : args) { - addServerArgument(arg); - } - } - return this; - } - - /** - * Adds the arguments to the collection of arguments that will be passed to - * the server ignoring any {@code null} arguments. - * - * @param args the arguments to add - * - * @return the builder - */ - public BootableJarCommandBuilder addServerArguments(final Iterable args) { - if (args != null) { - for (String arg : args) { - addServerArgument(arg); - } - } - return this; - } - - /** - * Adds an argument to be passed to the server ignore the argument if - * {@code null}. - * - * @param arg the argument to pass - * - * @return the builder - */ - public BootableJarCommandBuilder addServerArgument(final String arg) { - if (arg != null) { - serverArgs.add(Arguments.parse(arg)); - } - return this; - } - - /** - * Sets the system property {@code jboss.bind.address} to the address given. - *

- * This will override any previous value set via - * {@link #addServerArgument(String)}. - *

- * Note: This option only works if the standard system property has - * not been removed from the interface. If the system property was removed - * the address provided has no effect. - * - * @param address the address to set the bind address to - * - * @return the builder - */ - public BootableJarCommandBuilder setBindAddressHint(final String address) { - setSingleServerArg("-b", address); - return this; - } - - /** - * Sets the system property {@code jboss.bind.address.$INTERFACE} to the - * address given where {@code $INTERFACE} is the {@code interfaceName} - * parameter. For example in the default configuration passing - * {@code management} for the {@code interfaceName} parameter would result - * in the system property {@code jboss.bind.address.management} being set to - * the address provided. - *

- * This will override any previous value set via - * {@link #addServerArgument(String)}. - *

- * Note: This option only works if the standard system property has - * not been removed from the interface. If the system property was removed - * the address provided has no effect. - * - * @param interfaceName the name of the interface of the binding address - * @param address the address to bind the management interface to - * - * @return the builder - */ - public BootableJarCommandBuilder setBindAddressHint(final String interfaceName, final String address) { - if (interfaceName == null) { - throw LauncherMessages.MESSAGES.nullParam("interfaceName"); - } - setSingleServerArg("-b" + interfaceName, address); - return this; - } - - /** - * Sets the system property {@code jboss.default.multicast.address} to the - * address given. - *

- * This will override any previous value set via - * {@link #addServerArgument(String)}. - *

- * Note: This option only works if the standard system property has - * not been removed from the interface. If the system property was removed - * the address provided has no effect. - * - * @param address the address to set the multicast system property to - * - * @return the builder - */ - public BootableJarCommandBuilder setMulticastAddressHint(final String address) { - setSingleServerArg("-u", address); - return this; - } - - private void setSingleServerArg(final String key, final String value) { - serverArgs.set(key, value); - } - - /** - * Creates a command builder for a bootable instance of WildFly. - * - * @param bootableJar the path to the bootable jar - * - * @return a new builder - */ - public static BootableJarCommandBuilder of(final Path bootableJar) { - return new BootableJarCommandBuilder(Environment.validateJar(bootableJar)); - } - - /** - * Creates a command builder for a bootable instance of WildFly. - * - * @param bootableJar the path to the WildFly home directory - * - * @return a new builder - */ - public static BootableJarCommandBuilder of(final String bootableJar) { - return new BootableJarCommandBuilder(Environment.validateJar(bootableJar)); - } - - /** - * Adds a JVM argument to the command ignoring {@code null} arguments. - * - * @param jvmArg the JVM argument to add - * - * @return the builder - */ - public BootableJarCommandBuilder addJavaOption(final String jvmArg) { - if (jvmArg != null && !jvmArg.trim().isEmpty()) { - final Argument argument = Arguments.parse(jvmArg); - javaOpts.add(argument); - } - return this; - } - - /** - * Adds the YAML configuration file argument with the given YAML configuration files. - * - * @param yamlFiles the files to add - * - * @return the builder - */ - public BootableJarCommandBuilder setYamlFiles(final Path... yamlFiles) { - if (yamlFiles == null || yamlFiles.length == 0) { - return this; - } - return setYamlFiles(List.of(yamlFiles)); - } - - /** - * Adds the YAML configuration file argument with the given YAML configuration files. - * - * @param yamlFiles the files to add - * - * @return the builder - */ - public BootableJarCommandBuilder setYamlFiles(final Collection yamlFiles) { - if (yamlFiles == null || yamlFiles.isEmpty()) { - return this; - } - StringJoiner joiner = new StringJoiner(File.pathSeparator); - for (Path yamlFile : yamlFiles) { - joiner.add(yamlFile.toAbsolutePath().toString()); - } - setSingleServerArg("--yaml", joiner.toString()); - return this; - } - - /** - * Adds the array of JVM arguments to the command. - * - * @param javaOpts the array of JVM arguments to add, {@code null} arguments are ignored - * - * @return the builder - */ - public BootableJarCommandBuilder addJavaOptions(final String... javaOpts) { - if (javaOpts != null) { - for (String javaOpt : javaOpts) { - addJavaOption(javaOpt); - } - } - return this; - } - - /** - * Adds the collection of JVM arguments to the command. - * - * @param javaOpts the collection of JVM arguments to add, {@code null} arguments are ignored - * - * @return the builder - */ - public BootableJarCommandBuilder addJavaOptions(final Iterable javaOpts) { - if (javaOpts != null) { - for (String javaOpt : javaOpts) { - addJavaOption(javaOpt); - } - } - return this; - } - - /** - * Sets the JVM arguments to use. This overrides any default JVM arguments that would normally be added and ignores - * {@code null} values in the collection. - *

- * If the collection is {@code null} the JVM arguments will be cleared and no new arguments will be added. - * - * @param javaOpts the JVM arguments to use - * - * @return the builder - */ - public BootableJarCommandBuilder setJavaOptions(final Iterable javaOpts) { - this.javaOpts.clear(); - return addJavaOptions(javaOpts); - } - - - /** - * Sets the JVM arguments to use. This overrides any default JVM arguments that would normally be added and ignores - * {@code null} values in the array. - *

- * If the array is {@code null} the JVM arguments will be cleared and no new arguments will be added. - * - * @param javaOpts the JVM arguments to use - * - * @return the builder - */ - public BootableJarCommandBuilder setJavaOptions(final String... javaOpts) { - this.javaOpts.clear(); - return addJavaOptions(javaOpts); - } - - /** - * Returns the JVM arguments. - * - * @return the JVM arguments - */ - public List getJavaOptions() { - return javaOpts.asList(); - } - - /** - * Sets the debug argument for the JVM with a default port of {@code 8787}. - * - * @return the builder - */ - public BootableJarCommandBuilder setDebug() { - return setDebug(false, 8787); - } - - /** - * Sets the debug argument for the JVM. - * - * @param port the port to listen on - * - * @return the builder - */ - public BootableJarCommandBuilder setDebug(final int port) { - return setDebug(false, port); - } - - /** - * Sets the debug JPDA remote socket debugging argument. - * - * @param suspend {@code true} to suspend otherwise {@code false} - * @param port the port to listen on - * - * @return the builder - */ - public BootableJarCommandBuilder setDebug(final boolean suspend, final int port) { - debugArg = String.format(DEBUG_FORMAT, (suspend ? "y" : "n"), port); - return this; - } - - /** - * Sets the Java home where the Java executable can be found. - * - * @param javaHome the Java home or {@code null} to use te system property {@code java.home} - * - * @return the builder - */ - public BootableJarCommandBuilder setJavaHome(final String javaHome) { - jvm = Jvm.of(javaHome); - return this; - } - - /** - * Sets the Java home where the Java executable can be found. - * - * @param javaHome the Java home or {@code null} to use te system property {@code java.home} - * - * @return the builder - */ - public BootableJarCommandBuilder setJavaHome(final Path javaHome) { - jvm = Jvm.of(javaHome); - return this; - } - - /** - * Set to {@code true} to use JBoss Modules lockless mode. - * - * @param b {@code true} to use lockless mode - * - * @return the builder - */ - public BootableJarCommandBuilder setModulesLockless(final boolean b) { - if (b) { - modulesLocklessArg = "-Djboss.modules.lockless=true"; - } else { - modulesLocklessArg = null; - } - return this; - } - - /** - * Set to {@code true} to gather metrics for JBoss Modules. - * - * @param b {@code true} to gather metrics for JBoss Modules. - * - * @return this builder - */ - public BootableJarCommandBuilder setModulesMetrics(final boolean b) { - if (b) { - modulesMetricsArg = "-Djboss.modules.metrics=true"; - } else { - modulesMetricsArg = null; - } - return this; - } - - /** - * Adds a security property to be passed to the server with a {@code null} value. - * - * @param key the property key - * - * @return the builder - */ - public BootableJarCommandBuilder addSecurityProperty(final String key) { - securityProperties.put(key, null); - return this; - } - - /** - * Adds a security property to be passed to the server. - * - * @param key the property key - * @param value the property value - * - * @return the builder - */ - public BootableJarCommandBuilder addSecurityProperty(final String key, final String value) { - securityProperties.put(key, value); - return this; - } - - /** - * Adds all the security properties to be passed to the server. - * - * @param properties a map of the properties to add, {@code null} values are allowed in the map - * - * @return the builder - */ - public BootableJarCommandBuilder addSecurityProperties(final Map properties) { - securityProperties.putAll(properties); - return this; - } - - @Override - public List buildArguments() { - final List cmd = new ArrayList<>(getJavaOptions()); - if (jvm.enhancedSecurityManagerAvailable()) { - cmd.add(JBossModulesCommandBuilder.SECURITY_MANAGER_PROP_WITH_ALLOW_VALUE); - } - if (modulesLocklessArg != null) { - cmd.add(modulesLocklessArg); - } - if (modulesMetricsArg != null) { - cmd.add(modulesMetricsArg); - } - if (debugArg != null) { - cmd.add(debugArg); - } - - cmd.add("-jar"); - - cmd.add(bootableJar.toString()); - - // Add the security properties - StringBuilder sb = new StringBuilder(64); - for (Map.Entry entry : securityProperties.entrySet()) { - sb.append("-S").append(entry.getKey()); - if (entry.getValue() != null) { - sb.append('=').append(entry.getValue()); - } - cmd.add(sb.toString()); - sb.setLength(0); - } - - cmd.addAll(getServerArguments()); - return cmd; - } - - @Override - public List build() { - final List cmd = new ArrayList<>(); - cmd.add(jvm.getCommand()); - cmd.addAll(buildArguments()); - return cmd; - } - - /** - * Returns the Java home directory where the java executable command can be - * found. - *

- * If the directory was not set the system property value, - * {@code java.home}, should be used. - * - * @return the path to the Java home directory - */ - public Path getJavaHome() { - return jvm.getPath(); - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/CliCommandBuilder.java b/launcher/src/main/java/org/wildfly/core/launcher/CliCommandBuilder.java deleted file mode 100644 index 20f0ce3257f..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/CliCommandBuilder.java +++ /dev/null @@ -1,743 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.wildfly.core.launcher.Arguments.Argument; -import org.wildfly.core.launcher.logger.LauncherMessages; - -/** - * Builds a list of commands to create a new process for a CLI instance. - *

- * This builder is not thread safe and the same instance should not be used in multiple threads. - *

- * - * @author James R. Perkins - */ -@SuppressWarnings({"unused", "UnusedReturnValue"}) -public class CliCommandBuilder implements CommandBuilder { - - private static final Path cliClientJar = Paths.get("bin").resolve("client").resolve("jboss-cli-client.jar"); - - enum CliArgument { - CONNECT("--connect", "-c"), - CONTROLLER("--controller", "controller"), - GUI("--gui"), - FILE("--file"), - COMMAND("--command"), - COMMANDS("--commands"), - USER("--user", "-u"), - PASSWORD("--password", "-p"), - TIMEOUT("--timeout"),; - private static final Map ENTRIES; - - static { - final Map map = new HashMap<>(); - for (CliArgument arg : values()) { - map.put(arg.key, arg); - if (arg.altKey != null) { - map.put(arg.altKey, arg); - } - } - ENTRIES = Collections.unmodifiableMap(map); - } - - public static CliArgument find(final String key) { - return ENTRIES.get(key); - } - - public static CliArgument find(final Argument argument) { - return ENTRIES.get(argument.getKey()); - } - - private final String key; - private final String altKey; - - CliArgument(final String key) { - this(key, null); - } - - CliArgument(final String key, final String altKey) { - this.key = key; - this.altKey = altKey; - } - } - - private final Environment environment; - private final Arguments javaOpts; - private final Arguments cliArgs; - private final boolean modularLauncher; - - private CliCommandBuilder(final Environment environment, boolean modularLauncher) { - this.environment = environment; - this.modularLauncher = modularLauncher; - javaOpts = new Arguments(); - cliArgs = new Arguments(); - if (modularLauncher) { - // Add the default logging.properties file - javaOpts.add("-Dlogging.configuration=file:" + environment.resolvePath("bin", "jboss-cli-logging.properties")); - } - } - - /** - * Creates a command builder for a CLI instance. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static CliCommandBuilder asModularLauncher(final Path wildflyHome) { - return new CliCommandBuilder(new Environment(wildflyHome), true); - } - - /** - * Creates a command builder for a CLI instance. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static CliCommandBuilder asModularLauncher(final String wildflyHome) { - return new CliCommandBuilder(new Environment(wildflyHome), true); - } - - /** - * Creates a command builder for a modular CLI instance. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static CliCommandBuilder of(final Path wildflyHome) { - return asModularLauncher(wildflyHome); - } - - /** - * Creates a command builder for a modular CLI instance. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static CliCommandBuilder of(final String wildflyHome) { - return asModularLauncher(wildflyHome); - } - - /** - * Creates a command builder for a non-modular CLI instance launched from wildflyHome/bin/client/jboss-client.jar. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static CliCommandBuilder asJarLauncher(final Path wildflyHome) { - Environment environment = new Environment(wildflyHome); - Environment.validateJar(environment.getWildflyHome().resolve(cliClientJar)); - return new CliCommandBuilder(environment, false); - } - - /** - * Creates a command builder for a non-modular CLI instance launched from wildflyHome/bin/client/jboss-client.jar. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static CliCommandBuilder asJarLauncher(final String wildflyHome) { - Environment environment = new Environment(wildflyHome); - Environment.validateJar(environment.getWildflyHome().resolve(cliClientJar)); - return new CliCommandBuilder(environment, false); - } - - /** - * Sets the hostname and port to connect to. - *

- * This sets both the {@code --connect} and {@code --controller} arguments. - *

- * - * @param controller the controller argument to use - * - * @return the builder - */ - public CliCommandBuilder setConnection(final String controller) { - addCliArgument(CliArgument.CONNECT); - setController(controller); - return this; - } - - /** - * Sets the hostname and port to connect to. - *

- * This sets both the {@code --connect} and {@code --controller} arguments. - *

- * - * @param hostname the host name - * @param port the port - * - * @return the builder - */ - public CliCommandBuilder setConnection(final String hostname, final int port) { - addCliArgument(CliArgument.CONNECT); - setController(hostname, port); - return this; - } - - /** - * Sets the protocol, hostname and port to connect to. - *

- * This sets both the {@code --connect} and {@code --controller} arguments. - *

- * - * @param protocol the protocol to use - * @param hostname the host name - * @param port the port - * - * @return the builder - */ - public CliCommandBuilder setConnection(final String protocol, final String hostname, final int port) { - addCliArgument(CliArgument.CONNECT); - setController(protocol, hostname, port); - return this; - } - - /** - * Sets the hostname and port to connect to. - * - * @param controller the controller argument to use - * - * @return the builder - */ - public CliCommandBuilder setController(final String controller) { - addCliArgument(CliArgument.CONTROLLER, controller); - return this; - } - - /** - * Sets the hostname and port to connect to. - * - * @param hostname the host name - * @param port the port - * - * @return the builder - */ - public CliCommandBuilder setController(final String hostname, final int port) { - setController(formatAddress(null, hostname, port)); - return this; - } - - /** - * Sets the protocol, hostname and port to connect to. - * - * @param protocol the protocol to use - * @param hostname the host name - * @param port the port - * - * @return the builder - */ - public CliCommandBuilder setController(final String protocol, final String hostname, final int port) { - setController(formatAddress(protocol, hostname, port)); - return this; - } - - /** - * Sets the user to use when establishing a connection. - * - * @param user the user to use - * - * @return the builder - */ - public CliCommandBuilder setUser(final String user) { - addCliArgument(CliArgument.USER, user); - return this; - } - - /** - * Sets the password to use when establishing a connection. - * - * @param password the password to use - * - * @return the builder - */ - public CliCommandBuilder setPassword(final String password) { - addCliArgument(CliArgument.PASSWORD, password); - return this; - } - - /** - * Sets the path to the script file to execute. - * - * @param path the path to the script file to execute - * - * @return the builder - */ - public CliCommandBuilder setScriptFile(final String path) { - if (path == null) { - addCliArgument(CliArgument.FILE, null); - return this; - } - return setScriptFile(Paths.get(path)); - } - - /** - * Sets the path to the script file to execute. - * - * @param path the path to the script file to execute - * - * @return the builder - */ - public CliCommandBuilder setScriptFile(final Path path) { - if (path == null) { - addCliArgument(CliArgument.FILE, null); - } else { - // Make sure the path exists - if (Files.notExists(path)) { - throw LauncherMessages.MESSAGES.pathDoesNotExist(path); - } - addCliArgument(CliArgument.FILE, path.toString()); - } - return this; - } - - /** - * Sets the command to execute. - * - * @param command the command to execute - * - * @return the builder - */ - public CliCommandBuilder setCommand(final String command) { - addCliArgument(CliArgument.COMMAND, command); - return this; - } - - /** - * Sets the commands to execute. - * - * @param commands the commands to execute - * - * @return the builder - */ - public CliCommandBuilder setCommands(final String... commands) { - if (commands == null || commands.length == 0) { - addCliArgument(CliArgument.COMMANDS, null); - return this; - } - return setCommands(Arrays.asList(commands)); - } - - /** - * Sets the commands to execute. - * - * @param commands the commands to execute - * - * @return the builder - */ - public CliCommandBuilder setCommands(final Iterable commands) { - if (commands == null) { - addCliArgument(CliArgument.COMMANDS, null); - return this; - } - final StringBuilder cmds = new StringBuilder(); - for (final Iterator iterator = commands.iterator(); iterator.hasNext(); ) { - cmds.append(iterator.next()); - if (iterator.hasNext()) cmds.append(','); - } - addCliArgument(CliArgument.COMMANDS, cmds.toString()); - return this; - } - - /** - * Sets the timeout used when connecting to the server. - * - * @param timeout the time out to use - * - * @return the builder - */ - public CliCommandBuilder setTimeout(final int timeout) { - if (timeout > 0) { - addCliArgument(CliArgument.TIMEOUT, Integer.toString(timeout)); - } else { - addCliArgument(CliArgument.TIMEOUT, null); - } - return this; - } - - /** - * Sets the command argument to use the GUI CLI client. - * - * @return the builder - */ - public CliCommandBuilder setUseGui() { - if (Environment.isMac()) { - addJavaOption("-Djboss.modules.system.pkgs=com.apple.laf,com.apple.laf.resources"); - } else { - addJavaOption("-Djboss.modules.system.pkgs=com.sun.java.swing"); - } - addCliArgument(CliArgument.GUI); - return this; - } - - /** - * Adds a JVM argument to the command ignoring {@code null} arguments. - * - * @param jvmArg the JVM argument to add - * - * @return the builder - */ - public CliCommandBuilder addJavaOption(final String jvmArg) { - if (jvmArg != null && !jvmArg.trim().isEmpty()) { - javaOpts.add(jvmArg); - } - return this; - } - - /** - * Adds the array of JVM arguments to the command. - * - * @param javaOpts the array of JVM arguments to add, {@code null} arguments are ignored - * - * @return the builder - */ - public CliCommandBuilder addJavaOptions(final String... javaOpts) { - if (javaOpts != null) { - for (String javaOpt : javaOpts) { - addJavaOption(javaOpt); - } - } - return this; - } - - /** - * Adds the collection of JVM arguments to the command. - * - * @param javaOpts the collection of JVM arguments to add, {@code null} arguments are ignored - * - * @return the builder - */ - public CliCommandBuilder addJavaOptions(final Iterable javaOpts) { - if (javaOpts != null) { - for (String javaOpt : javaOpts) { - addJavaOption(javaOpt); - } - } - return this; - } - - /** - * Sets the JVM arguments to use. This overrides any default JVM arguments that would normally be added and ignores - * {@code null} values in the collection. - *

- * If the collection is {@code null} the JVM arguments will be cleared and no new arguments will be added. - * - * @param javaOpts the JVM arguments to use - * - * @return the builder - */ - public CliCommandBuilder setJavaOptions(final Iterable javaOpts) { - this.javaOpts.clear(); - return addJavaOptions(javaOpts); - } - - - /** - * Sets the JVM arguments to use. This overrides any default JVM arguments that would normally be added and ignores - * {@code null} values in the array. - *

- * If the array is {@code null} the JVM arguments will be cleared and no new arguments will be added. - * - * @param javaOpts the JVM arguments to use - * - * @return the builder - */ - public CliCommandBuilder setJavaOptions(final String... javaOpts) { - this.javaOpts.clear(); - return addJavaOptions(javaOpts); - } - - /** - * Returns the JVM arguments. - * - * @return the JVM arguments - */ - public List getJavaOptions() { - return javaOpts.asList(); - } - - /** - * Adds an argument to be passed to the CLI command ignore the argument if {@code null}. - * - * @param arg the argument to pass - * - * @return the builder - */ - public CliCommandBuilder addCliArgument(final String arg) { - if (arg != null) { - final Argument argument = Arguments.parse(arg); - final CliArgument cliArgument = CliArgument.find(argument.getKey()); - if (cliArgument != null) { - // Remove the alternate key if required - if (cliArgument.altKey != null) { - cliArgs.remove(cliArgument.altKey); - } - } - cliArgs.set(argument); - } - return this; - } - - /** - * Adds the arguments to the collection of arguments that will be passed to the CLI command ignoring any {@code - * null} arguments. - * - * @param args the arguments to add - * - * @return the builder - */ - public CliCommandBuilder addCliArguments(final String... args) { - if (args != null) { - for (String arg : args) { - addCliArgument(arg); - } - } - return this; - } - - /** - * Adds the arguments to the collection of arguments that will be passed to the CLI command ignoring any {@code - * null} arguments. - * - * @param args the arguments to add - * - * @return the builder - */ - public CliCommandBuilder addCliArguments(final Iterable args) { - if (args != null) { - for (String arg : args) { - addCliArgument(arg); - } - } - return this; - } - - /** - * Adds a directory to the collection of module paths. - * - * @param moduleDir the module directory to add - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the path is {@code null} - */ - public CliCommandBuilder addModuleDir(final String moduleDir) { - environment.addModuleDir(moduleDir); - return this; - } - - /** - * Adds all the module directories to the collection of module paths. - * - * @param moduleDirs an array of module paths to add - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public CliCommandBuilder addModuleDirs(final String... moduleDirs) { - environment.addModuleDirs(moduleDirs); - return this; - } - - /** - * Adds all the module directories to the collection of module paths. - * - * @param moduleDirs a collection of module paths to add - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public CliCommandBuilder addModuleDirs(final Iterable moduleDirs) { - environment.addModuleDirs(moduleDirs); - return this; - } - - /** - * Replaces any previously set module directories with the collection of module directories. - *

- * The default module directory will NOT be used if this method is invoked. - * - * @param moduleDirs the collection of module directories to use - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public CliCommandBuilder setModuleDirs(final Iterable moduleDirs) { - environment.setModuleDirs(moduleDirs); - return this; - } - - /** - * Replaces any previously set module directories with the array of module directories. - *

- * The default module directory will NOT be used if this method is invoked. - * - * @param moduleDirs the array of module directories to use - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public CliCommandBuilder setModuleDirs(final String... moduleDirs) { - environment.setModuleDirs(moduleDirs); - return this; - } - - /** - * Returns the modules paths used on the command line. - * - * @return the paths separated by the {@link java.io.File#pathSeparator path separator} - */ - public String getModulePaths() { - return environment.getModulePaths(); - } - - /** - * Sets the Java home where the Java executable can be found. - * - * @param javaHome the Java home or {@code null} to use te system property {@code java.home} - * - * @return the builder - */ - public CliCommandBuilder setJavaHome(final String javaHome) { - environment.setJvm(Jvm.of(javaHome)); - return this; - } - - /** - * Sets the Java home where the Java executable can be found. - * - * @param javaHome the Java home or {@code null} to use te system property {@code java.home} - * - * @return the builder - */ - public CliCommandBuilder setJavaHome(final Path javaHome) { - environment.setJvm(Jvm.of(javaHome)); - return this; - } - - /** - * Returns the Java home directory where the java executable command can be found. - *

- * If the directory was not set the system property value, {@code java.home}, should be used. - * - * @return the path to the Java home directory - */ - public Path getJavaHome() { - return environment.getJvm().getPath(); - } - - @Override - public List buildArguments() { - final List cmd = new ArrayList<>(getJavaOptions()); - if (modularLauncher) { - if (environment.getJvm().isModular()) { - cmd.addAll(JBossModulesCommandBuilder.DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : JBossModulesCommandBuilder.OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } - } - } - } - if (environment.getJvm().enhancedSecurityManagerAvailable()) { - cmd.add(JBossModulesCommandBuilder.SECURITY_MANAGER_PROP_WITH_ALLOW_VALUE); - } - cmd.add("-jar"); - - if (modularLauncher) { - cmd.add(environment.getModuleJar().toString()); - cmd.add("-mp"); - cmd.add(getModulePaths()); - cmd.add("org.jboss.as.cli"); - cmd.add("-D" + Environment.HOME_DIR + "=" + environment.getWildflyHome()); - } else { - cmd.add(environment.getWildflyHome().resolve(cliClientJar).toString()); - } - - cmd.addAll(cliArgs.asList()); - return cmd; - - } - - @Override - public List build() { - final List cmd = new ArrayList<>(); - cmd.add(environment.getJvm().getCommand()); - cmd.addAll(buildArguments()); - return cmd; - } - - private CliCommandBuilder addCliArgument(final CliArgument cliArgument) { - if (cliArgument.altKey != null) { - cliArgs.remove(cliArgument.altKey); - } - cliArgs.set(Arguments.parse(cliArgument.key)); - return this; - } - - private CliCommandBuilder addCliArgument(final CliArgument cliArgument, final String value) { - if (cliArgument.altKey != null) { - cliArgs.remove(cliArgument.altKey); - } - cliArgs.set(cliArgument.key, value); - return this; - } - - - private static String formatAddress(final String protocol, final String hostname, final int port) { - final char first = hostname.charAt(0); - if (first == '[' && hostname.charAt(hostname.length() - 1) != ']') { - throw LauncherMessages.MESSAGES.invalidHostname(hostname); - } - boolean wrapIpv6 = false; - if (first != '[' && (first == ':' || Character.digit(first, 16) != -1)) { - int counter = 0; - for (char c : hostname.toCharArray()) { - if (c == ':') { - counter++; - } else if (Character.digit(c, 16) == -1) { - // Not IPV6 - break; - } - if (counter > 1) { - wrapIpv6 = true; - break; - } - } - } - if (protocol == null) { - if (wrapIpv6) { - return String.format("[%s]:%d", hostname, port); - } - return String.format("%s:%d", hostname, port); - } - if (wrapIpv6) { - return String.format("%s://[%s]:%d", protocol, hostname, port); - } - return String.format("%s://%s:%d", protocol, hostname, port); - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/CommandBuilder.java b/launcher/src/main/java/org/wildfly/core/launcher/CommandBuilder.java deleted file mode 100644 index a51417d4bba..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/CommandBuilder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.util.List; - -/** - * Builds a list of commands that can be used to launch WildFly. - * - * @author James R. Perkins - */ -public interface CommandBuilder { - - /** - * A list of command arguments required to launch WildFly instance. - *

- * These are the arguments the follow a {@code java} executable command. - * - * @return the list of arguments required to launch WildFly - */ - List buildArguments(); - - /** - * A list of commands, including a {@code java} executable, required to launch WildFly - * instance. - * - * @return the list of arguments required to launch WildFly - */ - List build(); -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/DomainCommandBuilder.java b/launcher/src/main/java/org/wildfly/core/launcher/DomainCommandBuilder.java deleted file mode 100644 index b95f4bdbcf4..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/DomainCommandBuilder.java +++ /dev/null @@ -1,813 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import org.wildfly.core.launcher.Arguments.Argument; - -/** - * Builds a list of commands used to launch a domain instance of WildFly. - *

- * This builder is not thread safe and the same instance should not be used in multiple threads. - *

- * The {@link #getJavaHome() default Java home} directory is used for the process controller and optionally for the - * host - * controller and the servers launched. - * - * @author James R. Perkins - */ -@SuppressWarnings({"unused", "UnusedReturnValue"}) -public class DomainCommandBuilder extends AbstractCommandBuilder implements CommandBuilder { - - private static final String MODULE_NAME = "org.jboss.as.process-controller"; - private static final String DOMAIN_BASE_DIR = "jboss.domain.base.dir"; - private static final String DOMAIN_CONFIG_DIR = "jboss.domain.config.dir"; - private static final String DOMAIN_LOG_DIR = "jboss.domain.log.dir"; - - private Jvm hostControllerJvm; - private Jvm serverJvm; - private Path baseDir; - private final Arguments hostControllerJavaOpts; - private final Arguments processControllerJavaOpts; - - /** - * Creates a new command builder for a domain instance of WildFly. - *

- * Note the {@code wildflyHome} and {@code javaHome} are not validated using the constructor. The static {@link - * #of(java.nio.file.Path)} is preferred. - * - * @param wildflyHome the WildFly home directory - * @param jvm the default JVM - */ - private DomainCommandBuilder(final Path wildflyHome, final Jvm jvm) { - super(wildflyHome, jvm, MODULE_NAME); - hostControllerJavaOpts = new Arguments(); - hostControllerJavaOpts.addAll(DEFAULT_VM_ARGUMENTS); - processControllerJavaOpts = new Arguments(); - processControllerJavaOpts.addAll(DEFAULT_VM_ARGUMENTS); - hostControllerJvm = serverJvm = environment.getJvm(); - } - - /** - * Creates a command builder for a domain instance of WildFly. - *

- * Uses the system property {@code java.home} to find the java executable required for the default Java home. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static DomainCommandBuilder of(final Path wildflyHome) { - return new DomainCommandBuilder(Environment.validateWildFlyDir(wildflyHome), Jvm.current()); - } - - /** - * Creates a command builder for a domain instance of WildFly. - *

- * Uses the system property {@code java.home} to find the java executable required for the default Java home. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static DomainCommandBuilder of(final String wildflyHome) { - return new DomainCommandBuilder(Environment.validateWildFlyDir(wildflyHome), Jvm.current()); - } - - /** - * Creates a command builder for a domain instance of WildFly. - * - * @param wildflyHome the path to the WildFly home directory - * @param javaHome the path to the default Java home directory - * - * @return a new builder - */ - public static DomainCommandBuilder of(final String wildflyHome, final String javaHome) { - return new DomainCommandBuilder(Environment.validateWildFlyDir(wildflyHome), Jvm.of(javaHome)); - } - - /** - * Creates a command builder for a domain instance of WildFly. - * - * @param wildflyHome the path to the WildFly home directory - * @param javaHome the path default to the Java home directory - * - * @return a new builder - */ - public static DomainCommandBuilder of(final Path wildflyHome, final Path javaHome) { - return new DomainCommandBuilder(Environment.validateWildFlyDir(wildflyHome), Jvm.of(javaHome)); - } - - /** - * Sets the option ({@code --backup} to keep a copy of the persistent domain configuration even if this host is not - * a domain controller. - * - * @return the builder - */ - public DomainCommandBuilder setBackup() { - addServerArgument("--backup"); - return this; - } - - /** - * Sets the option ({@code --cached-dc}) to boot using a locally cached copy of the domain configuration. - * - * @return the builder - * - * @see #setBackup() - */ - public DomainCommandBuilder setCachedDomainController() { - addServerArgument("--cached-dc"); - return this; - } - - /** - * Sets the address on which the host controller should listen for communication from the process controller - * ({@code interprocess-hc-address}). Ignores {@code null} values. - * - * @param address the address - * - * @return the builder - */ - public DomainCommandBuilder setInterProcessHostControllerAddress(final String address) { - if (address != null) { - setSingleServerArg("--interprocess-hc-address", address); - } - return this; - } - - /** - * Sets the port on which the host controller should listen for communication from the process controller ({@code - * interprocess-hc-address}). Ignores {@code null} values or values less than 0. - * - * @param port the port - * - * @return the builder - * - * @throws java.lang.NumberFormatException if the port is not a valid integer - */ - public DomainCommandBuilder setInterProcessHostControllerPort(final String port) { - if (port != null) { - setInterProcessHostControllerPort(Integer.parseInt(port)); - } - return this; - } - - - /** - * Sets the port on which the host controller should listen for communication from the process controller ({@code - * interprocess-hc-address}). Ignores values less than 0. - * - * @param port the port - * - * @return the builder - */ - public DomainCommandBuilder setInterProcessHostControllerPort(final int port) { - if (port > -1) { - setSingleServerArg("--interprocess-hc-port", Integer.toString(port)); - } - return this; - } - - /** - * Sets the system property {@code jboss.domain.primary.address}. In a default slave host configuration this is used - * to configure the address of the master host controller. Ignores {@code null} values. - *

- * Note: This option only works if the standard system property has not been removed from the remote host. - * If the system property was removed the address provided has no effect. - * - * @param address the address - * - * @return the builder - */ - public DomainCommandBuilder setMasterAddressHint(final String address) { - if (address != null) { - setSingleServerArg("--primary-address", address); - } - return this; - } - - /** - * Sets the system property {@code jboss.domain.primary.port}. In a default slave host configuration this is used - * to configure the port of the master host controller. Ignores {@code null} values or values less than 0. - *

- * Note: This option only works if the standard system property has not been removed from the remote host. - * If the system property was removed the port provided has no effect. - * - * @param port the port - * - * @return the builder - * - * @throws java.lang.NumberFormatException if the port is not a valid integer - */ - public DomainCommandBuilder setMasterPortHint(final String port) { - if (port != null) { - setMasterPortHint(Integer.parseInt(port)); - } - return this; - } - - /** - * Sets the system property {@code jboss.domain.primary.port}. In a default slave host configuration this is used - * to configure the port of the master host controller. Ignores values less than 0. - *

- * Note: This option only works if the standard system property has not been removed from the remote host. - * If the system property was removed the port provided has no effect. - * - * @param port the port - * - * @return the builder - */ - public DomainCommandBuilder setMasterPortHint(final int port) { - if (port > -1) { - setSingleServerArg("--primary-port", Integer.toString(port)); - } - return this; - } - - /** - * Sets the address on which the process controller listens for communication from processes it controls. Ignores - * {@code null} values. - * - * @param address the address - * - * @return the builder - */ - public DomainCommandBuilder setProcessControllerAddress(final String address) { - if (address != null) { - setSingleServerArg("--pc-address", address); - } - return this; - } - - /** - * Sets the port on which the process controller listens for communication from processes it controls. Ignores - * {@code null} values or values less than 0. - * - * @param port the port - * - * @return the builder - * - * @throws java.lang.NumberFormatException if the port is not a valid integer - */ - public DomainCommandBuilder setProcessControllerPort(final String port) { - if (port != null) { - setProcessControllerPort(Integer.parseInt(port)); - } - return this; - } - - /** - * Sets the port on which the process controller listens for communication from processes it controls. Ignores - * values less than 0. - * - * @param port the port - * - * @return the builder - */ - public DomainCommandBuilder setProcessControllerPort(final int port) { - if (port > -1) { - setSingleServerArg("--pc-port", Integer.toString(port)); - } - return this; - } - - /** - * Sets the base directory to use. - *

- * The default is {@code $JBOSS_HOME/standalone}. - * - * @param baseDir the base directory or {@code null} to resolve the base directory - * - * @return the builder - */ - public DomainCommandBuilder setBaseDirectory(final String baseDir) { - this.baseDir = Environment.validateAndNormalizeDir(baseDir, true); - return this; - } - - /** - * Sets the base directory to use. - *

- * The default is {@code $JBOSS_HOME/standalone}. - * - * @param baseDir the base directory or {@code null} to resolve the base directory - * - * @return the builder - */ - public DomainCommandBuilder setBaseDirectory(final Path baseDir) { - this.baseDir = Environment.validateAndNormalizeDir(baseDir, true); - return this; - } - - /** - * Sets the Java home for the host controller. - *

- * If the {@code javaHome} is not {@code null} then the java executable will be resolved and used to launch the - * host processor. If the {@code javaHome} is {@code null} the same java executable will be used to launch the host - * controller that launched the process controller. - * - * @param javaHome the java home to set, can be {@code null} to use the default - * - * @return the builder - */ - public DomainCommandBuilder setHostControllerJavaHome(final String javaHome) { - hostControllerJvm = Jvm.of(javaHome); - return this; - } - - /** - * Sets the Java home for the host controller. - *

- * If the {@code javaHome} is not {@code null} then the java executable will be resolved and used to launch the - * host processor. If the {@code javaHome} is {@code null} the same java executable will be used to launch the host - * controller that launched the process controller. - * - * @param javaHome the java home to set, can be {@code null} to use the default - * - * @return the builder - */ - public DomainCommandBuilder setHostControllerJavaHome(final Path javaHome) { - hostControllerJvm = Jvm.of(javaHome); - return this; - } - - /** - * Returns the Java home path the host controller will use. - * - * @return the path to the Java home for the host controller - */ - public Path getHostControllerJavaHome() { - return hostControllerJvm.getPath(); - } - - /** - * Sets the configuration file for the host controller (host.xml). The file must be in the {@link - * #setConfigurationDirectory(String) configuration} directory. A value of {@code null} is ignored. - * - * @param configFile the configuration file name - * - * @return the builder - */ - public DomainCommandBuilder setHostConfiguration(final String configFile) { - if (configFile != null) { - setSingleServerArg("--host-config", configFile); - } - return this; - } - - /** - * Returns the configuration file {@link #setHostConfiguration(String) set} or {@code null} if one was not set. - * - * @return the configuration file set or {@code null} if not set - */ - public String getHostConfiguration() { - return getServerArg("--host-config"); - } - - /** - * Sets the read only configuration file for the host controller (host.xml). The file must be in the {@link - * #setConfigurationDirectory(String) configuration} directory. A value of {@code null} is ignored - *

- * This will override any previous value set. - * - * @param configFile the configuration file name or {@code null} - * - * @return the builder - */ - public DomainCommandBuilder setReadOnlyHostConfiguration(final String configFile) { - if (configFile != null) { - setSingleServerArg("--read-only-host-config", configFile); - } - return this; - } - - - /** - * Returns the configuration file {@link #setReadOnlyHostConfiguration(String)} set} or {@code null} if one was - * not set. - * - * @return the configuration file set or {@code null} if not set - */ - public String getReadOnlyHostConfiguration() { - return getServerArg("--read-only-host-config"); - } - - /** - * Sets the configuration file for the domain (domain.xml). The file must be in the {@link - * #setConfigurationDirectory(String) configuration} directory. A value of {@code null} is ignored. - *

- * This will override any previous value set. - * - * @param configFile the configuration file name - * - * @return the builder - */ - public DomainCommandBuilder setDomainConfiguration(final String configFile) { - setSingleServerArg("-c", configFile); - return this; - } - - /** - * Returns the configuration file {@link #setDomainConfiguration(String) set} or {@code null} if one was not set. - * - * @return the configuration file set or {@code null} if not set - */ - public String getDomainConfiguration() { - return getServerArg("-c"); - } - - /** - * Sets the read only configuration file for the domain (domain.xml). The file must be in the {@link - * #setConfigurationDirectory(String) configuration} directory. A value of {@code null} is ignored - *

- * This will override any previous value set. - * - * @param configFile the configuration file name or {@code null} - * - * @return the builder - */ - public DomainCommandBuilder setReadOnlyDomainConfiguration(final String configFile) { - if (configFile != null) { - setSingleServerArg("--read-only-domain-config", configFile); - } - return this; - } - - - /** - * Returns the configuration file {@link #setReadOnlyDomainConfiguration(String)} set} or {@code null} if one was - * not set. - * - * @return the configuration file set or {@code null} if not set - */ - public String getReadOnlyDomainConfiguration() { - return getServerArg("--read-only-domain-config"); - } - - /** - * Adds a JVM argument to the host controller ignoring {@code null} values. - * - * @param arg the argument to add - * - * @return the builder - */ - public DomainCommandBuilder addHostControllerJavaOption(final String arg) { - if (arg != null && !arg.trim().isEmpty()) { - final Argument argument = Arguments.parse(arg); - switch (argument.getKey()) { - case DOMAIN_BASE_DIR: - if (argument.getValue() != null) { - setBaseDirectory(argument.getValue()); - } - break; - case DOMAIN_CONFIG_DIR: - if (argument.getValue() != null) { - setConfigurationDirectory(argument.getValue()); - } - break; - case DOMAIN_LOG_DIR: - if (argument.getValue() != null) { - setLogDirectory(argument.getValue()); - } - break; - default: - hostControllerJavaOpts.add(argument); - break; - } - } - return this; - } - - /** - * Adds a JVM arguments to the host controller ignoring {@code null} values. - * - * @param args the arguments to add - * - * @return the builder - */ - public DomainCommandBuilder addHostControllerJavaOptions(final String... args) { - if (args != null) { - for (String arg : args) { - addHostControllerJavaOption(arg); - } - } - return this; - } - - /** - * Adds a JVM arguments to the host controller ignoring {@code null} values. - * - * @param args the arguments to add - * - * @return the builder - */ - public DomainCommandBuilder addHostControllerJavaOptions(final Iterable args) { - if (args != null) { - for (String arg : args) { - addHostControllerJavaOption(arg); - } - } - return this; - } - - /** - * Sets the JVM arguments for the host controller ignoring {@code null} values in the array. - *

- * If the array is {@code null} the host controller JVM arguments are cleared and no new ones are added - * - * @param args the arguments to add - * - * @return the builder - */ - public DomainCommandBuilder setHostControllerJavaOptions(final String... args) { - hostControllerJavaOpts.clear(); - return addHostControllerJavaOptions(args); - } - - /** - * Sets the JVM arguments for the host controller ignoring {@code null} values in the collection. - *

- * If the collection is {@code null} the host controller JVM arguments are cleared and no new ones are added - * - * @param args the arguments to add - * - * @return the builder - */ - public DomainCommandBuilder setHostControllerJavaOptions(final Iterable args) { - hostControllerJavaOpts.clear(); - return addHostControllerJavaOptions(args); - } - - /** - * Returns the JVM arguments for the host controller. - * - * @return the JVM arguments - */ - public List getHostControllerJavaOptions() { - return hostControllerJavaOpts.asList(); - } - - /** - * Adds a JVM argument to the process controller ignoring {@code null} values. - * - * @param arg the argument to add - * - * @return the builder - */ - public DomainCommandBuilder addProcessControllerJavaOption(final String arg) { - if (arg != null && !arg.trim().isEmpty()) { - final Argument argument = Arguments.parse(arg); - if (argument.getKey().equals(SECURITY_MANAGER_PROP)) { - // [WFCORE-5778] java.security.manager system property with value "allow" detected. - // It doesn't mean SM is going to be installed but it indicates SM can be installed dynamically. - setUseSecurityManager(isJavaSecurityManagerConfigured(argument)); - } else { - processControllerJavaOpts.add(argument); - } - } - return this; - } - - /** - * Adds a JVM arguments to the process controller ignoring {@code null} values. - * - * @param args the arguments to add - * - * @return the builder - */ - public DomainCommandBuilder addProcessControllerJavaOptions(final String... args) { - if (args != null) { - for (String arg : args) { - addProcessControllerJavaOption(arg); - } - } - return this; - } - - /** - * Adds a JVM arguments to the process controller ignoring {@code null} values. - * - * @param args the arguments to add - * - * @return the builder - */ - public DomainCommandBuilder addProcessControllerJavaOptions(final Iterable args) { - if (args != null) { - for (String arg : args) { - addProcessControllerJavaOption(arg); - } - } - return this; - } - - /** - * Sets the JVM arguments for the process controller ignoring {@code null} values in the array. - *

- * If the array is {@code null} the process controller JVM arguments are cleared and no new ones are added - * - * @param args the arguments to add - * - * @return the builder - */ - public DomainCommandBuilder setProcessControllerJavaOptions(final String... args) { - processControllerJavaOpts.clear(); - return addProcessControllerJavaOptions(args); - } - - /** - * Sets the JVM arguments for the process controller ignoring {@code null} values in the collection. - *

- * If the collection is {@code null} the process controller JVM arguments are cleared and no new ones are added - * - * @param args the arguments to add - * - * @return the builder - */ - public DomainCommandBuilder setProcessControllerJavaOptions(final Iterable args) { - processControllerJavaOpts.clear(); - return addProcessControllerJavaOptions(args); - } - - /** - * Returns the JVM arguments used for the process controller. - * - * @return the JVM arguments - */ - public List getProcessControllerJavaOptions() { - return processControllerJavaOpts.asList(); - } - - - /** - * Sets the Java home for the servers that are launched in the domain. - *

- * If the {@code javaHome} is not {@code null} then the java executable will be resolved and used to launch the - * servers in the domain. If the {@code javaHome} is {@code null} the same java executable will be used to launch - * the servers in the domain that launched the process controller. - * - * @param javaHome the java home to set, can be {@code null} to use the default - * - * @return the builder - */ - public DomainCommandBuilder setServerJavaHome(final String javaHome) { - serverJvm = Jvm.of(javaHome); - return this; - } - - - /** - * Sets the Java home for the servers that are launched in the domain. - *

- * If the {@code javaHome} is not {@code null} then the java executable will be resolved and used to launch the - * servers in the domain. If the {@code javaHome} is {@code null} the same java executable will be used to launch - * the servers in the domain that launched the process controller. - * - * @param javaHome the java home to set, can be {@code null} to use the default - * - * @return the builder - */ - public DomainCommandBuilder setServerJavaHome(final Path javaHome) { - serverJvm = Jvm.of(javaHome); - return this; - } - - /** - * Sets the stability level of the standalone server process. - * @param stability a stability level - * @return a reference to this builder - */ - public DomainCommandBuilder setStability(String stability) { - if (stability != null) { - this.setSingleServerArg("--stability", stability); - } - return this; - } - - /** - * Returns the Java home path the servers will use. - * - * @return the path to the Java home for the servers - */ - public Path getServerJavaHome() { - return serverJvm.getPath(); - } - - @Override - public List buildArguments() { - final List cmd = new ArrayList<>(); - - // Process Controller - cmd.add("-D[Process Controller]"); - addSystemPropertyArg(cmd, HOME_DIR, getWildFlyHome()); - - // PROCESS_CONTROLLER_JAVA_OPTS - cmd.addAll(processControllerJavaOpts.asList()); - if (environment.getJvm().isModular()) { - cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } - } - } - if (environment.getJvm().enhancedSecurityManagerAvailable()) { - cmd.add(SECURITY_MANAGER_PROP_WITH_ALLOW_VALUE); - } - - cmd.add(getBootLogArgument("process-controller.log")); - cmd.add(getLoggingPropertiesArgument("logging.properties")); - cmd.add("-jar"); - cmd.add(getModulesJarName()); - if (useSecurityManager()) { - cmd.add(SECURITY_MANAGER_ARG); - } - cmd.add("-mp"); - cmd.add(getModulePaths()); - cmd.add(MODULE_NAME); - cmd.add("-jboss-home"); - cmd.add(getWildFlyHome().toString()); - cmd.add("-jvm"); - cmd.add(hostControllerJvm.getCommand()); - cmd.add("-mp"); - cmd.add(getModulePaths()); - - // Host Controller - cmd.add("--"); - cmd.add(getBootLogArgument("host-controller.log")); - cmd.add(getLoggingPropertiesArgument("logging.properties")); - - // HOST_CONTROLLER_JAVA_OPTS - cmd.addAll(hostControllerJavaOpts.asList()); - if (hostControllerJvm.isModular()) { - cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } - } - } - if (hostControllerJvm.enhancedSecurityManagerAvailable()) { - cmd.add(SECURITY_MANAGER_PROP_WITH_ALLOW_VALUE); - } - - cmd.add("--"); - cmd.add("-default-jvm"); - cmd.add(serverJvm.getCommand()); - addSystemPropertyArg(cmd, DOMAIN_BASE_DIR, getBaseDirectory()); - addSystemPropertyArg(cmd, DOMAIN_LOG_DIR, getLogDirectory()); - addSystemPropertyArg(cmd, DOMAIN_CONFIG_DIR, getConfigurationDirectory()); - - cmd.addAll(getServerArguments()); - return cmd; - } - - @Override - public Path getJavaHome() { - return environment.getJvm().getPath(); - } - - @Override - public Path getBaseDirectory() { - if (baseDir == null) { - return normalizePath("domain"); - } - return baseDir; - } - - @Override - protected DomainCommandBuilder getThis() { - return this; - } - - @Override - boolean addServerArgument(final Argument argument) { - switch (argument.getKey()) { - case DOMAIN_BASE_DIR: - if (argument.getValue() != null) { - setBaseDirectory(argument.getValue()); - return false; - } - break; - case DOMAIN_CONFIG_DIR: - if (argument.getValue() != null) { - setConfigurationDirectory(argument.getValue()); - return false; - } - break; - case DOMAIN_LOG_DIR: - if (argument.getValue() != null) { - setLogDirectory(argument.getValue()); - return false; - } - break; - } - return true; - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/Environment.java b/launcher/src/main/java/org/wildfly/core/launcher/Environment.java deleted file mode 100644 index 26b19ae55ed..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/Environment.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -import org.wildfly.core.launcher.logger.LauncherMessages; - -/** - * @author James R. Perkins - */ -class Environment { - private static final boolean MAC; - private static final boolean WINDOWS; - - static final String HOME_DIR = "jboss.home.dir"; - static final String MODULES_JAR_NAME = "jboss-modules.jar"; - - static { - final String os = System.getProperty("os.name").toLowerCase(Locale.ROOT); - MAC = os.startsWith("mac"); - WINDOWS = os.contains("win"); - } - - private final Path wildflyHome; - private Jvm jvm; - private final List modulesDirs; - private boolean addDefaultModuleDir; - - Environment(final String wildflyHome) { - this(validateWildFlyDir(wildflyHome)); - } - - Environment(final Path wildflyHome) { - this.wildflyHome = validateWildFlyDir(wildflyHome); - modulesDirs = new ArrayList<>(); - addDefaultModuleDir = true; - jvm = Jvm.current(); - } - - /** - * Returns the WildFly Home directory. - * - * @return the WildFly home directory - */ - public Path getWildflyHome() { - return wildflyHome; - } - - /** - * Returns the full path to the {@code jboss-modules.jar}. - * - * @return the path to {@code jboss-modules.jar} - */ - public Path getModuleJar() { - return resolvePath(MODULES_JAR_NAME); - } - - /** - * Adds a directory to the collection of module paths. - * - * @param moduleDir the module directory to add - * - * @throws java.lang.IllegalArgumentException if the path is {@code null} - */ - public void addModuleDir(final String moduleDir) { - if (moduleDir == null) { - throw LauncherMessages.MESSAGES.nullParam("moduleDir"); - } - // Validate the path - final Path path = Paths.get(moduleDir).normalize(); - modulesDirs.add(path.toString()); - } - - /** - * Adds all the module directories to the collection of module paths. - * - * @param moduleDirs an array of module paths to add - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public void addModuleDirs(final String... moduleDirs) { - // Validate and add each path - for (String path : moduleDirs) { - addModuleDir(path); - } - } - - /** - * Adds all the module directories to the collection of module paths. - * - * @param moduleDirs a collection of module paths to add - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public void addModuleDirs(final Iterable moduleDirs) { - // Validate and add each path - for (String path : moduleDirs) { - addModuleDir(path); - } - } - - /** - * Replaces any previously set module directories with the collection of module directories. - *

- * The default module directory will NOT be used if this method is invoked. - * - * @param moduleDirs the collection of module directories to use - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public void setModuleDirs(final Iterable moduleDirs) { - this.modulesDirs.clear(); - // Process each module directory - for (String path : moduleDirs) { - addModuleDir(path); - } - addDefaultModuleDir = false; - } - - /** - * Replaces any previously set module directories with the array of module directories. - *

- * The default module directory will NOT be used if this method is invoked. - * - * @param moduleDirs the array of module directories to use - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public void setModuleDirs(final String... moduleDirs) { - this.modulesDirs.clear(); - // Process each module directory - for (String path : moduleDirs) { - addModuleDir(path); - } - addDefaultModuleDir = false; - } - - /** - * Returns the modules paths used on the command line. - * - * @return the paths separated by the {@link File#pathSeparator path separator} - */ - public String getModulePaths() { - final StringBuilder result = new StringBuilder(); - if (addDefaultModuleDir) { - result.append(wildflyHome.resolve("modules").toString()); - } - if (!modulesDirs.isEmpty()) { - if (addDefaultModuleDir) result.append(File.pathSeparator); - for (Iterator iterator = modulesDirs.iterator(); iterator.hasNext(); ) { - result.append(iterator.next()); - if (iterator.hasNext()) { - result.append(File.pathSeparator); - } - } - } - return result.toString(); - } - - Jvm getJvm() { - return jvm; - } - - Environment setJvm(final Jvm jvm) { - this.jvm = jvm == null ? Jvm.current() : jvm; - return this; - } - - /** - * Resolves a path relative to the WildFly home directory. - *

- * Note this does not validate whether or not the path is valid or exists. - *

- * - * @param paths the paths to resolve - * - * @return the path - */ - public Path resolvePath(final String... paths) { - Path result = wildflyHome; - for (String path : paths) { - result = result.resolve(path); - } - return result; - } - - public static boolean isMac() { - return MAC; - } - - public static boolean isWindows() { - return WINDOWS; - } - - static Path validateWildFlyDir(final String wildflyHome) { - if (wildflyHome == null) { - throw LauncherMessages.MESSAGES.pathDoesNotExist(null); - } - return validateWildFlyDir(Paths.get(wildflyHome)); - } - - static Path validateWildFlyDir(final Path wildflyHome) { - if (wildflyHome == null || Files.notExists(wildflyHome)) { - throw LauncherMessages.MESSAGES.pathDoesNotExist(wildflyHome); - } - if (!Files.isDirectory(wildflyHome)) { - throw LauncherMessages.MESSAGES.invalidDirectory(wildflyHome); - } - final Path result = wildflyHome.toAbsolutePath().normalize(); - if (Files.notExists(result.resolve(MODULES_JAR_NAME))) { - throw LauncherMessages.MESSAGES.invalidDirectory(MODULES_JAR_NAME, wildflyHome); - } - return result; - } - - static Path validateJar(final Path jarPath) { - if (jarPath == null || Files.notExists(jarPath)) { - throw LauncherMessages.MESSAGES.pathDoesNotExist(jarPath); - } - if (Files.isDirectory(jarPath)) { - throw LauncherMessages.MESSAGES.pathNotAFile(jarPath); - } - return jarPath.toAbsolutePath().normalize(); - } - - static Path validateJar(final String jarPath) { - if (jarPath == null) { - throw LauncherMessages.MESSAGES.pathDoesNotExist(null); - } - return validateJar(Paths.get(jarPath)); - } - - @SuppressWarnings("SameParameterValue") - static Path validateAndNormalizeDir(final String path, final boolean allowNull) { - if (path == null) { - if (allowNull) return null; - throw LauncherMessages.MESSAGES.pathDoesNotExist(null); - } - return validateAndNormalizeDir(Paths.get(path), allowNull); - } - - static Path validateAndNormalizeDir(final Path path, final boolean allowNull) { - if (allowNull && path == null) return null; - if (path == null || Files.notExists(path)) { - throw LauncherMessages.MESSAGES.pathDoesNotExist(path); - } - if (!Files.isDirectory(path)) { - throw LauncherMessages.MESSAGES.invalidDirectory(path); - } - return path.toAbsolutePath().normalize(); - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/JBossModulesCommandBuilder.java b/launcher/src/main/java/org/wildfly/core/launcher/JBossModulesCommandBuilder.java deleted file mode 100644 index 32e519f442d..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/JBossModulesCommandBuilder.java +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.core.launcher; - -import static org.wildfly.core.launcher.logger.LauncherMessages.MESSAGES; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.wildfly.core.launcher.Arguments.Argument; - -/** - * Builds a list of commands used to launch JBoss Modules module. - *

- * This builder is not thread safe and the same instance should not be used in multiple threads. - * - * @author James R. Perkins - */ -@SuppressWarnings({"unused", "UnusedReturnValue"}) -public class JBossModulesCommandBuilder implements CommandBuilder { - - static final String[] DEFAULT_VM_ARGUMENTS = { - "-Xms64m", - "-Xmx512m", - "-Djava.net.preferIPv4Stack=true", - "-Djava.awt.headless=true", - "-Djboss.modules.system.pkgs=org.jboss.byteman" - }; - /** - * Packages being exported or opened are available on all JVMs - */ - static final Collection DEFAULT_MODULAR_VM_ARGUMENTS; - /** - * Packages being exported or opened may not be available on all JVMs - */ - static final Collection OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS; - private static final String ALLOW_VALUE = "allow"; - private static final String DISALLOW_VALUE = "disallow"; - static final String SECURITY_MANAGER_ARG = "-secmgr"; - static final String SECURITY_MANAGER_PROP = "java.security.manager"; - static final String SECURITY_MANAGER_PROP_WITH_ALLOW_VALUE = "-D" + SECURITY_MANAGER_PROP + "=" + ALLOW_VALUE; - - static { - // Default JVM parameters for all modular JDKs - // Additions to these should include good explanations why in the relevant JIRA - // Keep them alphabetical to avoid the code history getting confused by reordering commits - final List modularJavaOpts; - final boolean skipJPMSOptions = Boolean.getBoolean("launcher.skip.jpms.properties"); - if (!skipJPMSOptions) { - modularJavaOpts = List.of( - "--add-exports=java.desktop/sun.awt=ALL-UNNAMED", - "--add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED", - "--add-exports=java.naming/com.sun.jndi.url.ldap=ALL-UNNAMED", - "--add-exports=java.naming/com.sun.jndi.url.ldaps=ALL-UNNAMED", - "--add-exports=jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED", - "--add-opens=java.base/java.lang=ALL-UNNAMED", - "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED", - "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED", - "--add-opens=java.base/java.io=ALL-UNNAMED", - "--add-opens=java.base/java.net=ALL-UNNAMED", - "--add-opens=java.base/java.security=ALL-UNNAMED", - "--add-opens=java.base/java.util=ALL-UNNAMED", - "--add-opens=java.base/java.util.concurrent=ALL-UNNAMED", - "--add-opens=java.management/javax.management=ALL-UNNAMED", - "--add-opens=java.naming/javax.naming=ALL-UNNAMED", - // As of jboss-modules 1.9.1.Final the java.se module is no longer required to be added. However as this API is - // designed to work with older versions of the server we still need to add this argument of modular JVM's. - "--add-modules=java.se" - ); - } else { - modularJavaOpts = List.of(); - } - DEFAULT_MODULAR_VM_ARGUMENTS = modularJavaOpts; - - final List optionalModularJavaOpts; - if (!skipJPMSOptions) { - optionalModularJavaOpts = List.of(("--add-opens=java.base/com.sun.net.ssl.internal.ssl=ALL-UNNAMED")); - } else { - optionalModularJavaOpts = List.of(); - } - OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS = optionalModularJavaOpts; - } - - final Environment environment; - final Arguments serverArgs; - final Arguments javaOpts; - private final String moduleName; - private String modulesLocklessArg; - private String modulesMetricsArg; - private boolean useSecMgr; - private boolean addModuleAgent; - private final Collection moduleOpts; - - /** - * Creates a command builder for a launching JBoss Modules module. - *

- * Note the {@code wildflyHome} and {@code javaHome} are not validated using the constructor. The static {@link - * #of(Path, String)} is preferred. - * - * @param wildflyHome the path to WildFly, cannot be {@code null} - * @param moduleName the name of the entry module, cannot be {@code null} - */ - protected JBossModulesCommandBuilder(final Path wildflyHome, final String moduleName) { - this(wildflyHome, null, moduleName); - } - - /** - * Creates a command builder for a launching JBoss Modules module. - *

- * Note the {@code wildflyHome} and {@code javaHome} are not validated using the constructor. The static {@link - * #of(Path, String)} is preferred. - * - * @param wildflyHome the path to WildFly, cannot be {@code null} - * @param jvm the JVM used for the command builder, {@code null} will use the current JVM - * @param moduleName the name of the entry module, cannot be {@code null} - */ - JBossModulesCommandBuilder(final Path wildflyHome, final Jvm jvm, final String moduleName) { - if (wildflyHome == null) { - throw MESSAGES.nullParam("wildflyHome"); - } - if (moduleName == null) { - throw MESSAGES.nullParam("moduleName"); - } - this.environment = new Environment(wildflyHome).setJvm(jvm); - this.serverArgs = new Arguments(); - this.moduleName = moduleName; - javaOpts = new Arguments(); - moduleOpts = new ArrayList<>(); - addModuleAgent = false; - } - - /** - * Creates a command builder for a launching JBoss Modules module. - * - * @param wildflyHome the path to the WildFly home directory, cannot be {@code null} - * @param moduleName the name of the entry module, cannot be {@code null} - * - * @return a new builder - */ - public static JBossModulesCommandBuilder of(final Path wildflyHome, final String moduleName) { - if (moduleName == null) { - throw MESSAGES.nullParam("moduleName"); - } - return new JBossModulesCommandBuilder(Environment.validateWildFlyDir(wildflyHome), moduleName); - } - - /** - * Creates a command builder for a launching JBoss Modules module. - * - * @param wildflyHome the path to the WildFly home directory, cannot be {@code null} - * @param moduleName the name of the entry module, cannot be {@code null} - * - * @return a new builder - */ - public static JBossModulesCommandBuilder of(final String wildflyHome, final String moduleName) { - if (moduleName == null) { - throw MESSAGES.nullParam("moduleName"); - } - return new JBossModulesCommandBuilder(Environment.validateWildFlyDir(wildflyHome), moduleName); - } - - - /** - * Sets whether or not the security manager option, {@code -secmgr}, should be used. - * - * @param useSecMgr {@code true} to use the a security manager, otherwise {@code false} - * - * @return the builder - */ - public JBossModulesCommandBuilder setUseSecurityManager(final boolean useSecMgr) { - this.useSecMgr = useSecMgr; - return this; - } - - /** - * Indicates whether or no a security manager should be used for the server launched. - * - * @return {@code true} if a security manager should be used, otherwise {@code false} - */ - public boolean useSecurityManager() { - return useSecMgr; - } - - /** - * Adds a directory to the collection of module paths. - * - * @param moduleDir the module directory to add - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if the path is {@code null} - */ - public JBossModulesCommandBuilder addModuleDir(final String moduleDir) { - environment.addModuleDir(moduleDir); - return this; - } - - /** - * Adds all the module directories to the collection of module paths. - * - * @param moduleDirs an array of module paths to add - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public JBossModulesCommandBuilder addModuleDirs(final String... moduleDirs) { - environment.addModuleDirs(moduleDirs); - return this; - } - - /** - * Adds all the module directories to the collection of module paths. - * - * @param moduleDirs a collection of module paths to add - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public JBossModulesCommandBuilder addModuleDirs(final Iterable moduleDirs) { - environment.addModuleDirs(moduleDirs); - return this; - } - - /** - * Replaces any previously set module directories with the collection of module directories. - *

- * The default module directory will NOT be used if this method is invoked. - * - * @param moduleDirs the collection of module directories to use - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public JBossModulesCommandBuilder setModuleDirs(final Iterable moduleDirs) { - environment.setModuleDirs(moduleDirs); - return this; - } - - /** - * Replaces any previously set module directories with the array of module directories. - *

- * The default module directory will NOT be used if this method is invoked. - * - * @param moduleDirs the array of module directories to use - * - * @return the builder - * - * @throws java.lang.IllegalArgumentException if any of the module paths are invalid or {@code null} - */ - public JBossModulesCommandBuilder setModuleDirs(final String... moduleDirs) { - environment.setModuleDirs(moduleDirs); - return this; - } - - /** - * Returns the modules paths used on the command line. - * - * @return the paths separated by the {@link java.io.File#pathSeparator path separator} - */ - public String getModulePaths() { - return environment.getModulePaths(); - } - - /** - * Adds an argument to be passed to the server ignore the argument if {@code null}. - * - * @param arg the argument to pass - * - * @return the builder - */ - public JBossModulesCommandBuilder addServerArgument(final String arg) { - if (arg != null) { - final Argument argument = Arguments.parse(arg); - if (addServerArgument(argument)) { - if (SECURITY_MANAGER_ARG.equals(arg)) { - setUseSecurityManager(true); - } else { - serverArgs.add(argument); - } - } - } - return this; - } - - /** - * Adds the arguments to the collection of arguments that will be passed to the server ignoring any {@code null} - * arguments. - * - * @param args the arguments to add - * - * @return the builder - */ - public JBossModulesCommandBuilder addServerArguments(final String... args) { - if (args != null) { - for (String arg : args) { - addServerArgument(arg); - } - } - return this; - } - - /** - * Adds the arguments to the collection of arguments that will be passed to the server ignoring any {@code null} - * arguments. - * - * @param args the arguments to add - * - * @return the builder - */ - public JBossModulesCommandBuilder addServerArguments(final Iterable args) { - if (args != null) { - for (String arg : args) { - addServerArgument(arg); - } - } - return this; - } - - /** - * Returns the home directory used. - * - * @return the home directory - */ - public Path getWildFlyHome() { - return environment.getWildflyHome(); - } - - /** - * Returns the Java home directory where the java executable command can be found. - *

- * If the directory was not set the system property value, {@code java.home}, should be used. - * - * @return the path to the Java home directory - */ - public Path getJavaHome() { - return environment.getWildflyHome(); - } - - /** - * Returns the normalized path to the {@code jboss-modules.jar} for launching the server. - * - * @return the path to {@code jboss-modules.jar} - */ - public String getModulesJarName() { - return environment.getModuleJar().toString(); - } - - /** - * A collection of server command line arguments. - * - * @return the server arguments - */ - public List getServerArguments() { - return serverArgs.asList(); - } - - /** - * Adds a JVM argument to the command ignoring {@code null} arguments. - * - * @param jvmArg the JVM argument to add - * - * @return the builder - */ - public JBossModulesCommandBuilder addJavaOption(final String jvmArg) { - if (jvmArg != null && !jvmArg.isBlank()) { - final Argument argument = Arguments.parse(jvmArg); - if (argument.getKey().equals(SECURITY_MANAGER_PROP)) { - // [WFCORE-5778] java.security.manager system property with value "allow" detected. - // It doesn't mean SM is going to be installed but it indicates SM can be installed dynamically. - setUseSecurityManager(isJavaSecurityManagerConfigured(argument)); - } else { - javaOpts.add(argument); - } - } - return this; - } - - /** - * Adds the array of JVM arguments to the command. - * - * @param javaOpts the array of JVM arguments to add, {@code null} arguments are ignored - * - * @return the builder - */ - public JBossModulesCommandBuilder addJavaOptions(final String... javaOpts) { - if (javaOpts != null) { - for (String javaOpt : javaOpts) { - addJavaOption(javaOpt); - } - } - return this; - } - - /** - * Adds the collection of JVM arguments to the command. - * - * @param javaOpts the collection of JVM arguments to add, {@code null} arguments are ignored - * - * @return the builder - */ - public JBossModulesCommandBuilder addJavaOptions(final Iterable javaOpts) { - if (javaOpts != null) { - for (String javaOpt : javaOpts) { - addJavaOption(javaOpt); - } - } - return this; - } - - /** - * Sets the JVM arguments to use. This overrides any default JVM arguments that would normally be added and ignores - * {@code null} values in the collection. - *

- * If the collection is {@code null} the JVM arguments will be cleared and no new arguments will be added. - * - * @param javaOpts the JVM arguments to use - * - * @return the builder - */ - public JBossModulesCommandBuilder setJavaOptions(final Iterable javaOpts) { - this.javaOpts.clear(); - return addJavaOptions(javaOpts); - } - - /** - * Sets the JVM arguments to use. This overrides any default JVM arguments that would normally be added and ignores - * {@code null} values in the array. - *

- * If the array is {@code null} the JVM arguments will be cleared and no new arguments will be added. - * - * @param javaOpts the JVM arguments to use - * - * @return the builder - */ - public JBossModulesCommandBuilder setJavaOptions(final String... javaOpts) { - this.javaOpts.clear(); - return addJavaOptions(javaOpts); - } - - /** - * Returns the JVM arguments. - * - * @return the JVM arguments - */ - public List getJavaOptions() { - return javaOpts.asList(); - } - - /** - * Adds an option which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDir(String)} to add a module - * directory. - *

- * - * @param arg the argument to add - * - * @return the builder - */ - public JBossModulesCommandBuilder addModuleOption(final String arg) { - if (arg != null) { - if (arg.startsWith("-javaagent:")) { - addModuleAgent = true; - } else if ("-mp".equals(arg) || "--modulepath".equals(arg)) { - throw MESSAGES.invalidArgument(arg, "addModuleOption"); - } else if ("-secmgr".equals(arg)) { - throw MESSAGES.invalidArgument(arg, "setUseSecurityManager"); - } - moduleOpts.add(arg); - } - return this; - } - - /** - * Adds the options which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDirs(String...)} to add a - * module directory. - *

- * - * @param args the argument to add - * - * @return the builder - */ - public JBossModulesCommandBuilder addModuleOptions(final String... args) { - if (args != null) { - for (String arg : args) { - addModuleOption(arg); - } - } - return this; - } - - /** - * Adds the options which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDirs(Iterable)} to add a - * module directory. - *

- * - * @param args the argument to add - * - * @return the builder - */ - public JBossModulesCommandBuilder addModuleOptions(final Iterable args) { - if (args != null) { - for (String arg : args) { - addModuleOption(arg); - } - } - return this; - } - - /** - * Clears the current module options and adds the options which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDirs(String...)} to add a - * module directory. - *

- * - * @param args the argument to use - * - * @return the builder - */ - public JBossModulesCommandBuilder setModuleOptions(final String... args) { - moduleOpts.clear(); - addModuleOptions(args); - return this; - } - - /** - * Clears the current module options and adds the options which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDirs(Iterable)} to add a - * module directory. - *

- * - * @param args the argument to use - * - * @return the builder - */ - public JBossModulesCommandBuilder setModuleOptions(final Iterable args) { - moduleOpts.clear(); - addModuleOptions(args); - return this; - } - - /** - * Sets the Java home where the Java executable can be found. - * - * @param javaHome the Java home or {@code null} to use te system property {@code java.home} - * - * @return the builder - */ - public JBossModulesCommandBuilder setJavaHome(final String javaHome) { - environment.setJvm(Jvm.of(javaHome)); - return this; - } - - /** - * Sets the Java home where the Java executable can be found. - * - * @param javaHome the Java home or {@code null} to use te system property {@code java.home} - * - * @return the builder - */ - public JBossModulesCommandBuilder setJavaHome(final Path javaHome) { - environment.setJvm(Jvm.of(javaHome)); - return this; - } - - /** - * Set to {@code true} to use JBoss Modules lockless mode. - * - * @param b {@code true} to use lockless mode - * - * @return the builder - */ - public JBossModulesCommandBuilder setModulesLockless(final boolean b) { - if (b) { - modulesLocklessArg = "-Djboss.modules.lockless=true"; - } else { - modulesLocklessArg = null; - } - return this; - } - - /** - * Set to {@code true} to gather metrics for JBoss Modules. - * - * @param b {@code true} to gather metrics for JBoss Modules. - * - * @return this builder - */ - public JBossModulesCommandBuilder setModulesMetrics(final boolean b) { - if (b) { - modulesMetricsArg = "-Djboss.modules.metrics=true"; - } else { - modulesMetricsArg = null; - } - return this; - } - - @Override - public List buildArguments() { - final List cmd = new ArrayList<>(); - // Check to see if an agent was added as a module option, if so we want to add JBoss Modules as an agent. - if (addModuleAgent) { - cmd.add("-javaagent:" + getModulesJarName()); - } - cmd.addAll(getJavaOptions()); - if (environment.getJvm().isModular()) { - cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } - } - } - if (environment.getJvm().enhancedSecurityManagerAvailable()) { - cmd.add(SECURITY_MANAGER_PROP_WITH_ALLOW_VALUE); - } - // Add these to JVM level system properties - if (modulesLocklessArg != null) { - cmd.add(modulesLocklessArg); - } - if (modulesMetricsArg != null) { - cmd.add(modulesMetricsArg); - } - cmd.add("-jar"); - cmd.add(getModulesJarName()); - if (useSecurityManager()) { - cmd.add(SECURITY_MANAGER_ARG); - } - // Add the agent argument for jboss-modules - cmd.addAll(moduleOpts); - cmd.add("-mp"); - cmd.add(getModulePaths()); - cmd.add(moduleName); - - cmd.addAll(getServerArguments()); - return cmd; - } - - @Override - public List build() { - final List cmd = new ArrayList<>(); - cmd.add(environment.getJvm().getCommand()); - cmd.addAll(buildArguments()); - return cmd; - } - - protected void setSingleServerArg(final String key, final String value) { - serverArgs.set(key, value); - } - - protected void addServerArg(final String key, final String value) { - serverArgs.add(key, value); - } - - /** - * Returns the first argument from the server arguments. - * - * @param key the key to the argument - * - * @return the first argument or {@code null} - */ - protected String getServerArg(final String key) { - return serverArgs.get(key); - } - - /** - * Allows the subclass to do additional checking on whether the server argument should be added or not. In some - * cases it may be desirable for the argument passed to be added or processed elsewhere. - * - * @param argument the argument to test - * - * @return {@code true} if the argument should be added to the server arguments, {@code false} if the argument is - * handled by the subclass - */ - boolean addServerArgument(final Argument argument) { - return true; - } - - static boolean isJavaSecurityManagerConfigured(final Argument argument) { - return !ALLOW_VALUE.equals(argument.getValue()) && !DISALLOW_VALUE.equals(argument.getValue()); - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/Jvm.java b/launcher/src/main/java/org/wildfly/core/launcher/Jvm.java deleted file mode 100644 index 0414449015c..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/Jvm.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.wildfly.core.launcher.logger.LauncherMessages; - -/** - * Represents a JVM description. - * - * @author James R. Perkins - */ -class Jvm { - private static final String JAVA_EXE; - private static final Path JAVA_HOME; - private static final boolean MODULAR_JVM = true; - private static final boolean ENHANCED_SECURITY_MANAGER = Runtime.version().feature() >= 12; - - static { - String exe = "java"; - if (Environment.isWindows()) { - exe = "java.exe"; - } - JAVA_EXE = exe; - final String javaHome = System.getProperty("java.home"); - JAVA_HOME = Paths.get(javaHome); - } - - private static final Jvm DEFAULT = new Jvm(JAVA_HOME, MODULAR_JVM, ENHANCED_SECURITY_MANAGER); - - private final Path path; - private final boolean isModular; - private final boolean enhancedSecurityManager; - - private Jvm(final Path path, final boolean isModular, final boolean enhancedSecurityManager) { - this.path = path; - this.isModular = isModular; - this.enhancedSecurityManager = enhancedSecurityManager; - } - - /** - * The current JVM. - * - * @return the current JVM - */ - static Jvm current() { - return DEFAULT; - } - - /** - * Creates a new JVM. If the {@code javaHome} is {@code null} the {@linkplain #current() current} JVM is returned. - * - * @param javaHome the path to the Java home - * - * @return a JVM descriptor based on the Java home path - */ - static Jvm of(final String javaHome) { - if (javaHome == null) { - return DEFAULT; - } - return of(Paths.get(javaHome)); - } - - /** - * Creates a new JVM. If the {@code javaHome} is {@code null} the {@linkplain #current() current} JVM is returned. - * - * @param javaHome the path to the Java home - * - * @return a JVM descriptor based on the Java home path - */ - static Jvm of(final Path javaHome) { - if (javaHome == null || javaHome.equals(JAVA_HOME)) { - return DEFAULT; - } - final Path path = validateJavaHome(javaHome); - return new Jvm(path, isModularJavaHome(path), hasEnhancedSecurityManager(javaHome)); - } - - /** - * The the command which can launch this JVM. - * - * @return the command - */ - public String getCommand() { - return resolveJavaCommand(path); - } - - /** - * The path to this JVM. - * - * @return the path - */ - public Path getPath() { - return path; - } - - /** - * Indicates whether or not this is a modular JVM. - * - * @return {@code true} if this is a modular JVM, otherwise {@code false} - */ - public boolean isModular() { - return isModular; - } - - /** - * Indicates whether or not this is a modular JVM supporting special SecurityManager values like "allow", "disallow" & "default" - * - * @return {@code true} if this is a modular JVM with enhanced SecurityManager, otherwise {@code false} - */ - public boolean enhancedSecurityManagerAvailable() { - return enhancedSecurityManager; - } - - private static boolean isModularJavaHome(final Path javaHome) { - final Path jmodsDir = javaHome.resolve("jmods"); - // If the jmods directory exists we can safely assume this is a modular JDK, note even in a modular JDK this - // may not exist. - if (Files.isDirectory(jmodsDir)) { - return true; - } - // Next check for a $JAVA_HOME/release file, for a JRE this will not exist - final Path releaseFile = javaHome.resolve("release"); - if (Files.isReadable(releaseFile) && Files.isRegularFile(releaseFile)) { - // Read the file and look for a JAVA_VERSION property - try (final BufferedReader reader = Files.newBufferedReader(releaseFile, StandardCharsets.UTF_8)) { - String line; - while ((line = reader.readLine()) != null) { - if (line.startsWith("JAVA_VERSION=")) { - // Get the version value - final int index = line.indexOf('='); - return isModularJavaVersion(line.substring(index + 1).replace("\"", "")); - } - } - } catch (IOException ignore) { - } - } - // Final check is to launch a new process with some modular JVM arguments and check the exit code - return isModular(javaHome); - } - - private static boolean isModularJavaVersion(final String version) { - if (version != null) { - try { - final String[] versionParts = version.split("\\."); - if (versionParts.length == 1) { - return Integer.parseInt(versionParts[0]) >= 9; - } else if (versionParts.length > 1) { - // Check the first part and if one, use the second part - if ("1".equals(versionParts[0])) { - return Integer.parseInt(versionParts[2]) >= 9; - } - return Integer.parseInt(versionParts[0]) >= 9; - } - } catch (Exception ignore) { - } - } - return false; - } - - /** - * Checks to see if the {@code javaHome} supports special security manager tokens like "allow", "disallow" & "default" - * - * @param javaHome the Java Home if {@code null} an attempt to discover the Java Home will be done - * - * @return {@code true} if this is a modular environment - */ - private static boolean hasEnhancedSecurityManager(final Path javaHome) { - final List cmd = new ArrayList<>(); - cmd.add(resolveJavaCommand(javaHome)); - cmd.add("-Djava.security.manager=allow"); - cmd.add("-version"); - return checkProcessStatus(cmd); - } - - static boolean isPackageAvailable(final Path javaHome, final String optionalModularArgument) { - final List cmd = new ArrayList<>(); - cmd.add(resolveJavaCommand(javaHome)); - cmd.add(optionalModularArgument); - cmd.add("-version"); - return checkProcessStatus(cmd); - } - - /** - * Checks to see if the {@code javaHome} is a modular JVM. - * - * @param javaHome the Java Home if {@code null} an attempt to discover the Java Home will be done - * - * @return {@code true} if this is a modular environment - */ - private static boolean isModular(final Path javaHome) { - final List cmd = new ArrayList<>(); - cmd.add(resolveJavaCommand(javaHome)); - cmd.add("--add-modules=java.se"); - cmd.add("-version"); - return checkProcessStatus(cmd); - } - /** - * Checks the process status. - * - * @param cmd command to execute - * - * @return {@code true} if command was successful, {@code false} if process failed. - */ - private static boolean checkProcessStatus(final List cmd) { - boolean result; - final ProcessBuilder builder = new ProcessBuilder(cmd); - Process process = null; - Path stdout = null; - try { - // Create a temporary file for stdout - stdout = Files.createTempFile("stdout", ".txt"); - process = builder.redirectErrorStream(true) - .redirectOutput(stdout.toFile()).start(); - - if (process.waitFor(30, TimeUnit.SECONDS)) { - result = process.exitValue() == 0; - } else { - result = false; - } - } catch (IOException | InterruptedException e) { - result = false; - } finally { - if (process != null && process.isAlive()) { - process.destroyForcibly(); - } - if (stdout != null) { - try { - if (containsWarning(stdout)) { - result = false; - } - Files.deleteIfExists(stdout); - } catch (IOException ignore) { - } - } - } - return result; - } - - private static boolean containsWarning(final Path logFile) throws IOException { - String line; - try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(logFile.toFile())))) { - while ((line = br.readLine()) != null) { - if (line.startsWith("WARNING:")) { - return true; - } - } - } - return false; - } - - /** - * Returns the Java executable command. - * - * @param javaHome the java home directory or {@code null} to use the default - * - * @return the java command to use - */ - private static String resolveJavaCommand(final Path javaHome) { - final String exe; - if (javaHome == null) { - exe = "java"; - } else { - exe = javaHome.resolve("bin").resolve("java").toString(); - } - if (exe.contains(" ")) { - return "\"" + exe + "\""; - } - return exe; - } - - private static Path validateJavaHome(final Path javaHome) { - if (javaHome == null || Files.notExists(javaHome)) { - throw LauncherMessages.MESSAGES.pathDoesNotExist(javaHome); - } - if (!Files.isDirectory(javaHome)) { - throw LauncherMessages.MESSAGES.invalidDirectory(javaHome); - } - final Path result = javaHome.toAbsolutePath().normalize(); - final Path exe = result.resolve("bin").resolve(JAVA_EXE); - if (Files.notExists(exe)) { - final int count = exe.getNameCount(); - throw LauncherMessages.MESSAGES.invalidDirectory(exe.subpath(count - 2, count).toString(), javaHome); - } - return result; - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/Launcher.java b/launcher/src/main/java/org/wildfly/core/launcher/Launcher.java deleted file mode 100644 index 0ffa70051af..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/Launcher.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.io.File; -import java.io.IOException; -import java.lang.ProcessBuilder.Redirect; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; - -/** - * Builds a {@link java.lang.Process process} to launch a standalone or domain server based on the {@link - * org.wildfly.core.launcher.CommandBuilder command builder}. - *

- * The process is only created by the launcher and not managed. It's the responsibility of the consumer to manage the - * process. - * - * @author James R. Perkins - */ -@SuppressWarnings("unused") -public class Launcher { - - private final CommandBuilder builder; - private boolean redirectErrorStream; - private Redirect outputDestination; - private Redirect errorDestination; - private File workingDirectory; - private final Map env; - - /** - * Creates a new launcher. - * - * @param builder the builder to build the list of commands - */ - public Launcher(final CommandBuilder builder) { - this.builder = builder; - redirectErrorStream = false; - outputDestination = null; - errorDestination = null; - env = new HashMap<>(); - } - - /** - * Creates a new launcher to create a {@link java.lang.Process process} based on the command builder. - * - * @param builder the builder used to launch the process - * - * @return the newly created launcher - */ - public static Launcher of(final CommandBuilder builder) { - return new Launcher(builder); - } - - /** - * Sets the output and error streams to inherit the output and error streams from it's parent process. - * - * @return the launcher - */ - public Launcher inherit() { - outputDestination = Redirect.INHERIT; - errorDestination = Redirect.INHERIT; - return this; - } - - /** - * Set to {@code true} if the error stream should be redirected to the output stream. - * - * @param redirectErrorStream {@code true} to merge the error stream into the output stream, otherwise {@code - * false} - * to keep the streams separate - * - * @return the launcher - */ - public Launcher setRedirectErrorStream(final boolean redirectErrorStream) { - this.redirectErrorStream = redirectErrorStream; - return this; - } - - /** - * Redirects the output of the process to a file. - * - * @param file the file to redirect the output to - * - * @return the launcher - * - * @see java.lang.ProcessBuilder.Redirect#to(java.io.File) - */ - public Launcher redirectOutput(final File file) { - outputDestination = Redirect.to(file); - return this; - } - - /** - * Redirects the output of the process to a file. - * - * @param path the path to redirect the output to - * - * @return the launcher - * - * @see java.lang.ProcessBuilder.Redirect#to(java.io.File) - */ - public Launcher redirectOutput(final Path path) { - return redirectOutput(path.toFile()); - } - - /** - * Redirects the output of the process to the destination provided. - * - * @param destination the output destination - * - * @return the launcher - * - * @see java.lang.ProcessBuilder#redirectOutput(java.lang.ProcessBuilder.Redirect) - */ - public Launcher redirectOutput(final Redirect destination) { - outputDestination = destination; - return this; - } - - /** - * Redirects the error stream of the process to a file. - * - * @param file the file to redirect the error stream to - * - * @return the launcher - * - * @see java.lang.ProcessBuilder.Redirect#to(java.io.File) - */ - public Launcher redirectError(final File file) { - errorDestination = Redirect.to(file); - return this; - } - - - /** - * Redirects the error stream of the process to the destination provided. - * - * @param destination the error stream destination - * - * @return the launcher - * - * @see java.lang.ProcessBuilder#redirectError(java.lang.ProcessBuilder.Redirect) - */ - public Launcher redirectError(final Redirect destination) { - errorDestination = destination; - return this; - } - - /** - * Sets the working directory for the process created. - * - * @param path the path to the working directory - * - * @return the launcher - * - * @see java.lang.ProcessBuilder#directory(java.io.File) - */ - public Launcher setDirectory(final Path path) { - workingDirectory = path.toFile(); - return this; - } - - /** - * Sets the working directory for the process created. - * - * @param dir the working directory - * - * @return the launcher - * - * @see java.lang.ProcessBuilder#directory(java.io.File) - */ - public Launcher setDirectory(final File dir) { - workingDirectory = dir; - return this; - } - - /** - * Sets the working directory for the process created. - * - * @param dir the working directory - * - * @return the launcher - * - * @see java.lang.ProcessBuilder#directory(java.io.File) - */ - public Launcher setDirectory(final String dir) { - return setDirectory(Environment.validateAndNormalizeDir(dir, true)); - } - - /** - * Adds an environment variable to the process being created. If the key or value is {@code null}, the environment - * variable will not be added. - * - * @param key they key for the variable - * @param value the value for the variable - * - * @return the launcher - * @see ProcessBuilder#environment() - */ - public Launcher addEnvironmentVariable(final String key, final String value) { - if (key != null && value != null) { - env.put(key, value); - } - return this; - } - - /** - * Adds the environment variables to the process being created. Note that {@code null} keys or values will not be - * added. - * - * @param env the environment variables to add - * - * @return the launcher - * @see ProcessBuilder#environment() - */ - public Launcher addEnvironmentVariables(final Map env) { - env.forEach((key, value) -> { - if (key != null && value != null) { - addEnvironmentVariable(key, value); - } - }); - return this; - } - - /** - * Launches a new process based on the commands from the {@link org.wildfly.core.launcher.CommandBuilder builder}. - * - * @return the newly created process - * - * @throws IOException if an error occurs launching the process - */ - public Process launch() throws IOException { - final ProcessBuilder processBuilder = new ProcessBuilder(builder.build()); - if (outputDestination != null) { - processBuilder.redirectOutput(outputDestination); - } - if (errorDestination != null) { - processBuilder.redirectError(errorDestination); - } - if (workingDirectory != null) { - processBuilder.directory(workingDirectory); - } - if (!env.isEmpty()) { - processBuilder.environment().putAll(env); - } - processBuilder.redirectErrorStream(redirectErrorStream); - return processBuilder.start(); - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/ProcessHelper.java b/launcher/src/main/java/org/wildfly/core/launcher/ProcessHelper.java deleted file mode 100644 index 6520fc81d98..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/ProcessHelper.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -/** - * A helper class to help with managing a process. - * - * @author James R. Perkins - */ -public class ProcessHelper { - - /** - * Checks to see if the process has died. - * - * @param process the process to check - * - * @return {@code true} if the process has died, otherwise {@code false} - * @see Process#isAlive() - */ - @SuppressWarnings("unused") - @Deprecated(forRemoval = true) - public static boolean processHasDied(final Process process) { - return !process.isAlive(); - } - - /** - * Destroys the process if the process is not {@code null}. - * - * @param process the process to destroy, terminate - * - * @return 0 if the process was successfully destroyed - */ - public static int destroyProcess(final Process process) throws InterruptedException { - if (process == null) - return 0; - process.destroy(); - return process.waitFor(); - } - - /** - * Adds a shutdown hook for the process. - * - * @param process the process to add a shutdown hook for - * - * @return the thread set as the shutdown hook - * - * @throws java.lang.SecurityException If a security manager is present and it denies {@link - * java.lang.RuntimePermission RuntimePermission("shutdownHooks")} - */ - public static Thread addShutdownHook(final Process process) { - final Thread thread = new Thread(() -> { - if (process != null) { - process.destroyForcibly(); - try { - process.waitFor(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - thread.setDaemon(true); - Runtime.getRuntime().addShutdownHook(thread); - return thread; - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/StandaloneCommandBuilder.java b/launcher/src/main/java/org/wildfly/core/launcher/StandaloneCommandBuilder.java deleted file mode 100644 index a0a18953999..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/StandaloneCommandBuilder.java +++ /dev/null @@ -1,670 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.core.launcher; - -import static org.wildfly.core.launcher.logger.LauncherMessages.MESSAGES; - -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; - -import org.wildfly.core.launcher.Arguments.Argument; - -/** - * Builds a list of commands used to launch a standalone instance of WildFly. - *

- * This builder is not thread safe and the same instance should not be used in multiple threads. - * - * @author James R. Perkins - */ -@SuppressWarnings({"unused", "UnusedReturnValue"}) -public class StandaloneCommandBuilder extends AbstractCommandBuilder implements CommandBuilder { - - // JPDA remote socket debugging - static final String DEBUG_FORMAT = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=%s,address=%d"; - - private static final String MODULE_NAME = "org.jboss.as.standalone"; - private static final String SERVER_BASE_DIR = "jboss.server.base.dir"; - private static final String SERVER_CONFIG_DIR = "jboss.server.config.dir"; - private static final String SERVER_LOG_DIR = "jboss.server.log.dir"; - - private Path baseDir; - private final Arguments javaOpts; - private String debugArg; - private String modulesLocklessArg; - private String modulesMetricsArg; - private final Map securityProperties; - private boolean addModuleAgent; - private final Collection moduleOpts; - - /** - * Creates a new command builder for a standalone instance. - *

- * Note the {@code wildflyHome} and {@code javaHome} are not validated using the constructor. The static {@link - * #of(java.nio.file.Path)} is preferred. - * - * @param wildflyHome the path to WildFly - */ - private StandaloneCommandBuilder(final Path wildflyHome) { - super(wildflyHome, MODULE_NAME); - javaOpts = new Arguments(); - javaOpts.addAll(DEFAULT_VM_ARGUMENTS); - securityProperties = new LinkedHashMap<>(); - moduleOpts = new ArrayList<>(); - addModuleAgent = false; - } - - /** - * Creates a command builder for a standalone instance of WildFly. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static StandaloneCommandBuilder of(final Path wildflyHome) { - return new StandaloneCommandBuilder(Environment.validateWildFlyDir(wildflyHome)); - } - - /** - * Creates a command builder for a standalone instance of WildFly. - * - * @param wildflyHome the path to the WildFly home directory - * - * @return a new builder - */ - public static StandaloneCommandBuilder of(final String wildflyHome) { - return new StandaloneCommandBuilder(Environment.validateWildFlyDir(wildflyHome)); - } - - /** - * Adds a JVM argument to the command ignoring {@code null} arguments. - * - * @param jvmArg the JVM argument to add - * - * @return the builder - */ - public StandaloneCommandBuilder addJavaOption(final String jvmArg) { - if (jvmArg != null && !jvmArg.trim().isEmpty()) { - final Argument argument = Arguments.parse(jvmArg); - switch (argument.getKey()) { - case SERVER_BASE_DIR: - if (argument.getValue() != null) { - setBaseDirectory(argument.getValue()); - } - break; - case SERVER_CONFIG_DIR: - if (argument.getValue() != null) { - setConfigurationDirectory(argument.getValue()); - } - break; - case SERVER_LOG_DIR: - if (argument.getValue() != null) { - setLogDirectory(argument.getValue()); - } - break; - case SECURITY_MANAGER_PROP: - // [WFCORE-5778] java.security.manager system property with value "allow" detected. - // It doesn't mean SM is going to be installed but it indicates SM can be installed dynamically. - setUseSecurityManager(isJavaSecurityManagerConfigured(argument)); - break; - default: - javaOpts.add(argument); - break; - } - } - return this; - } - - /** - * Adds the array of JVM arguments to the command. - * - * @param javaOpts the array of JVM arguments to add, {@code null} arguments are ignored - * - * @return the builder - */ - public StandaloneCommandBuilder addJavaOptions(final String... javaOpts) { - if (javaOpts != null) { - for (String javaOpt : javaOpts) { - addJavaOption(javaOpt); - } - } - return this; - } - - /** - * Adds the collection of JVM arguments to the command. - * - * @param javaOpts the collection of JVM arguments to add, {@code null} arguments are ignored - * - * @return the builder - */ - public StandaloneCommandBuilder addJavaOptions(final Iterable javaOpts) { - if (javaOpts != null) { - for (String javaOpt : javaOpts) { - addJavaOption(javaOpt); - } - } - return this; - } - - /** - * Sets the JVM arguments to use. This overrides any default JVM arguments that would normally be added and ignores - * {@code null} values in the collection. - *

- * If the collection is {@code null} the JVM arguments will be cleared and no new arguments will be added. - * - * @param javaOpts the JVM arguments to use - * - * @return the builder - */ - public StandaloneCommandBuilder setJavaOptions(final Iterable javaOpts) { - this.javaOpts.clear(); - return addJavaOptions(javaOpts); - } - - /** - * Sets the JVM arguments to use. This overrides any default JVM arguments that would normally be added and ignores - * {@code null} values in the array. - *

- * If the array is {@code null} the JVM arguments will be cleared and no new arguments will be added. - * - * @param javaOpts the JVM arguments to use - * - * @return the builder - */ - public StandaloneCommandBuilder setJavaOptions(final String... javaOpts) { - this.javaOpts.clear(); - return addJavaOptions(javaOpts); - } - - /** - * Returns the JVM arguments. - * - * @return the JVM arguments - */ - public List getJavaOptions() { - return javaOpts.asList(); - } - - /** - * Adds an option which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDir(String)} to add a module - * directory. - *

- * - * @param arg the argument to add - * - * @return the builder - */ - public StandaloneCommandBuilder addModuleOption(final String arg) { - if (arg != null) { - if (arg.startsWith("-javaagent:")) { - addModuleAgent = true; - } else if ("-mp".equals(arg) || "--modulepath".equals(arg)) { - throw MESSAGES.invalidArgument(arg, "addModuleOption"); - } else if ("-secmgr".equals(arg)) { - throw MESSAGES.invalidArgument(arg, "setUseSecurityManager"); - } - moduleOpts.add(arg); - } - return this; - } - - /** - * Adds the options which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDirs(String...)} to add a - * module directory. - *

- * - * @param args the argument to add - * - * @return the builder - */ - public StandaloneCommandBuilder addModuleOptions(final String... args) { - if (args != null) { - for (String arg : args) { - addModuleOption(arg); - } - } - return this; - } - - /** - * Adds the options which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDirs(Iterable)} to add a - * module directory. - *

- * - * @param args the argument to add - * - * @return the builder - */ - public StandaloneCommandBuilder addModuleOptions(final Iterable args) { - if (args != null) { - for (String arg : args) { - addModuleOption(arg); - } - } - return this; - } - - /** - * Clears the current module options and adds the options which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDirs(String...)} to add a - * module directory. - *

- * - * @param args the argument to use - * - * @return the builder - */ - public StandaloneCommandBuilder setModuleOptions(final String... args) { - moduleOpts.clear(); - addModuleOptions(args); - return this; - } - - /** - * Clears the current module options and adds the options which will be passed to JBoss Modules. - *

- * Note that {@code -mp} or {@code --modulepath} is not supported. Use {@link #addModuleDirs(Iterable)} to add a - * module directory. - *

- * - * @param args the argument to use - * - * @return the builder - */ - public StandaloneCommandBuilder setModuleOptions(final Iterable args) { - moduleOpts.clear(); - addModuleOptions(args); - return this; - } - - /** - * Sets the debug argument for the JVM with a default port of {@code 8787}. - * - * @return the builder - */ - public StandaloneCommandBuilder setDebug() { - return setDebug(false, 8787); - } - - /** - * Sets the debug argument for the JVM. - * - * @param port the port to listen on - * - * @return the builder - */ - public StandaloneCommandBuilder setDebug(final int port) { - return setDebug(false, port); - } - - /** - * Sets the debug JPDA remote socket debugging argument. - * - * @param suspend {@code true} to suspend otherwise {@code false} - * @param port the port to listen on - * - * @return the builder - */ - public StandaloneCommandBuilder setDebug(final boolean suspend, final int port) { - debugArg = String.format(DEBUG_FORMAT, (suspend ? "y" : "n"), port); - return this; - } - - /** - * Sets the base directory to use. - *

- * The default is {@code $JBOSS_HOME/standalone}. - * - * @param baseDir the base directory or {@code null} to resolve the base directory - * - * @return the builder - */ - public StandaloneCommandBuilder setBaseDirectory(final String baseDir) { - this.baseDir = Environment.validateAndNormalizeDir(baseDir, true); - return this; - } - - /** - * Sets the base directory to use. - *

- * The default is {@code $JBOSS_HOME/standalone}. - * - * @param baseDir the base directory or {@code null} to resolve the base directory - * - * @return the builder - */ - public StandaloneCommandBuilder setBaseDirectory(final Path baseDir) { - this.baseDir = Environment.validateAndNormalizeDir(baseDir, true); - return this; - } - - /** - * Sets the Java home where the Java executable can be found. - * - * @param javaHome the Java home or {@code null} to use te system property {@code java.home} - * - * @return the builder - */ - public StandaloneCommandBuilder setJavaHome(final String javaHome) { - environment.setJvm(Jvm.of(javaHome)); - return this; - } - - /** - * Sets the Java home where the Java executable can be found. - * - * @param javaHome the Java home or {@code null} to use te system property {@code java.home} - * - * @return the builder - */ - public StandaloneCommandBuilder setJavaHome(final Path javaHome) { - environment.setJvm(Jvm.of(javaHome)); - return this; - } - - /** - * Set to {@code true} to use JBoss Modules lockless mode. - * - * @param b {@code true} to use lockless mode - * - * @return the builder - */ - public StandaloneCommandBuilder setModulesLockless(final boolean b) { - if (b) { - modulesLocklessArg = "-Djboss.modules.lockless=true"; - } else { - modulesLocklessArg = null; - } - return this; - } - - /** - * Set to {@code true} to gather metrics for JBoss Modules. - * - * @param b {@code true} to gather metrics for JBoss Modules. - * - * @return this builder - */ - public StandaloneCommandBuilder setModulesMetrics(final boolean b) { - if (b) { - modulesMetricsArg = "-Djboss.modules.metrics=true"; - } else { - modulesMetricsArg = null; - } - return this; - } - - /** - * Sets the configuration file for the server. The file must be in the {@link #setConfigurationDirectory(String) - * configuration} directory. A value of {@code null} will remove the configuration file. - *

- * This will override any previous value set via {@link #addServerArgument(String)}. - * - * @param configFile the configuration file name or {@code null} to remove the configuration file - * - * @return the builder - */ - public StandaloneCommandBuilder setServerConfiguration(final String configFile) { - setSingleServerArg("-c", configFile); - return this; - } - - /** - * Returns the configuration file {@link #setServerConfiguration(String) set} or {@code null} if one was not set. - * - * @return the configuration file set or {@code null} if not set - */ - public String getServerConfiguration() { - return getServerArg("-c"); - } - - /** - * Sets the configuration file for the server. The file must be in the {@link #setConfigurationDirectory(String) - * configuration} directory. A value of {@code null} will remove the configuration file. - *

- * This will override any previous value set via {@link #addServerArgument(String)}. - * - * @param configFile the configuration file name or {@code null} to remove the configuration file - * - * @return the builder - */ - public StandaloneCommandBuilder setServerReadOnlyConfiguration(final String configFile) { - setSingleServerArg("--read-only-server-config", configFile); - return this; - } - - /** - * Returns the configuration file {@link #setServerConfiguration(String) set} or {@code null} if one was not set. - * - * @return the configuration file set or {@code null} if not set - */ - public String getReadOnlyServerConfiguration() { - return getServerArg("--read-only-server-config"); - } - - /** - * Adds a security property to be passed to the server with a {@code null} value. - * - * @param key the property key - * - * @return the builder - */ - public StandaloneCommandBuilder addSecurityProperty(final String key) { - securityProperties.put(key, null); - return this; - } - - /** - * Adds a security property to be passed to the server. - * - * @param key the property key - * @param value the property value - * - * @return the builder - */ - public StandaloneCommandBuilder addSecurityProperty(final String key, final String value) { - securityProperties.put(key, value); - return this; - } - - /** - * Adds all the security properties to be passed to the server. - * - * @param properties a map of the properties to add, {@code null} values are allowed in the map - * - * @return the builder - */ - public StandaloneCommandBuilder addSecurityProperties(final Map properties) { - securityProperties.putAll(properties); - return this; - } - - /** - * Configures the git repository for the standalone server. - * - * @param gitRepository the git repository to clone to get the server configuration from - * @param gitBranch the branch to use to get the server configuration - * @param gitAuthentication the Elytron configuration file for managing git credentials - * - * @return the builder - */ - public StandaloneCommandBuilder setGitRepository(final String gitRepository, final String gitBranch, final String gitAuthentication) { - if (gitRepository == null) { - throw MESSAGES.nullParam("git-repo"); - } - addServerArg("--git-repo", gitRepository); - if (gitBranch != null) { - addServerArg("--git-branch", gitBranch); - } - if (gitAuthentication != null) { - addServerArg("--git-auth", gitAuthentication); - } - - return this; - } - - /** - * Adds the YAML configuration file argument with the given YAML configuration files. - * - * @param yamlFiles the files to add - * - * @return the builder - */ - public StandaloneCommandBuilder setYamlFiles(final Collection yamlFiles) { - if (yamlFiles == null || yamlFiles.isEmpty()) { - return this; - } - StringJoiner joiner = new StringJoiner(File.pathSeparator); - for (Path yamlFile : yamlFiles) { - joiner.add(yamlFile.toAbsolutePath().toString()); - } - setSingleServerArg("--yaml", joiner.toString()); - return this; - } - - /** - * Adds the YAML configuration file argument with the given YAML configuration files. - * - * @param yamlFiles the files to add - * - * @return the builder - */ - public StandaloneCommandBuilder setYamlFiles(final Path... yamlFiles) { - if (yamlFiles == null || yamlFiles.length == 0) { - return this; - } - return setYamlFiles(List.of(yamlFiles)); - } - - /** - * Sets the stability level of the domain controller process. - * @param stability a stability level - * @return a reference to this builder - */ - public StandaloneCommandBuilder setStability(String stability) { - if (stability != null) { - this.setSingleServerArg("--stability", stability); - } - return this; - } - - @Override - public List buildArguments() { - final List cmd = new ArrayList<>(); - cmd.add("-D[Standalone]"); - // Check to see if an agent was added as a module option, if so we want to add JBoss Modules as an agent. - if (addModuleAgent) { - cmd.add("-javaagent:" + getModulesJarName()); - } - cmd.addAll(getJavaOptions()); - if (environment.getJvm().isModular()) { - cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } - } - } - if (environment.getJvm().enhancedSecurityManagerAvailable()) { - cmd.add(SECURITY_MANAGER_PROP_WITH_ALLOW_VALUE); - } - // Add these to JVM level system properties - addSystemPropertyArg(cmd, HOME_DIR, getWildFlyHome()); - addSystemPropertyArg(cmd, SERVER_BASE_DIR, getBaseDirectory()); - addSystemPropertyArg(cmd, SERVER_LOG_DIR, getLogDirectory()); - addSystemPropertyArg(cmd, SERVER_CONFIG_DIR, getConfigurationDirectory()); - if (modulesLocklessArg != null) { - cmd.add(modulesLocklessArg); - } - if (modulesMetricsArg != null) { - cmd.add(modulesMetricsArg); - } - if (debugArg != null) { - cmd.add(debugArg); - } - cmd.add(getBootLogArgument("server.log")); - cmd.add(getLoggingPropertiesArgument("logging.properties")); - cmd.add("-jar"); - cmd.add(getModulesJarName()); - if (useSecurityManager()) { - cmd.add(SECURITY_MANAGER_ARG); - } - // Add the agent argument for jboss-modules - cmd.addAll(moduleOpts); - cmd.add("-mp"); - cmd.add(getModulePaths()); - cmd.add(MODULE_NAME); - - // Add the security properties - StringBuilder sb = new StringBuilder(64); - for (Map.Entry entry : securityProperties.entrySet()) { - sb.append("-S").append(entry.getKey()); - if (entry.getValue() != null) { - sb.append('=').append(entry.getValue()); - } - cmd.add(sb.toString()); - sb.setLength(0); - } - - cmd.addAll(getServerArguments()); - return cmd; - } - - @Override - public Path getJavaHome() { - return environment.getJvm().getPath(); - } - - @Override - public Path getBaseDirectory() { - if (baseDir == null) { - return normalizePath("standalone"); - } - return baseDir; - } - - @Override - protected StandaloneCommandBuilder getThis() { - return this; - } - - @Override - boolean addServerArgument(final Argument argument) { - switch (argument.getKey()) { - case SERVER_BASE_DIR: - if (argument.getValue() != null) { - setBaseDirectory(argument.getValue()); - return false; - } - break; - case SERVER_CONFIG_DIR: - if (argument.getValue() != null) { - setConfigurationDirectory(argument.getValue()); - return false; - } - break; - case SERVER_LOG_DIR: - if (argument.getValue() != null) { - setLogDirectory(argument.getValue()); - return false; - } - break; - } - return true; - } -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/logger/LauncherMessages.java b/launcher/src/main/java/org/wildfly/core/launcher/logger/LauncherMessages.java deleted file mode 100644 index 1f6db0e4e6e..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/logger/LauncherMessages.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher.logger; - -import java.nio.file.Path; - -import org.jboss.logging.annotations.Message; -import org.jboss.logging.annotations.MessageBundle; - -/** - * @author James R. Perkins - */ -@MessageBundle(projectCode = "WFLYLNCHR", length = 4) -public interface LauncherMessages { - - LauncherMessages MESSAGES = Messages.getBundle(LauncherMessages.class); - - /** - * Creates a message indicating the path does not exist. - * - * @param path the path that does not exist - * - * @return an exception for the error - */ - @Message(id = 1, value = "The path '%s' does not exist") - IllegalArgumentException pathDoesNotExist(Path path); - - @Message(id = 2, value = "The directory '%s' is not a valid directory") - IllegalArgumentException invalidDirectory(Path dir); - - @Message(id = 3, value = "Invalid directory, could not find '%s' in '%s'") - IllegalArgumentException invalidDirectory(String filename, Path dir); - - @Message(id = 4, value = "Path '%s' is not a regular file.") - IllegalArgumentException pathNotAFile(Path path); - - @Message(id = 5, value = "The parameter %s cannot be null.") - IllegalArgumentException nullParam(String name); - - @Message(id = 6, value = "Invalid hostname: %s") - IllegalArgumentException invalidHostname(CharSequence hostname); - - @Message(id = 7, value = "The argument %s is not allowed for %s.") - IllegalArgumentException invalidArgument(String argument, String methodName); -} diff --git a/launcher/src/main/java/org/wildfly/core/launcher/logger/Messages.java b/launcher/src/main/java/org/wildfly/core/launcher/logger/Messages.java deleted file mode 100644 index 987853a56e7..00000000000 --- a/launcher/src/main/java/org/wildfly/core/launcher/logger/Messages.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher.logger; - -import static java.security.AccessController.doPrivileged; - -import java.lang.reflect.Field; -import java.security.PrivilegedAction; -import java.util.Locale; - -/** - * Copied the logging Messages to use 0 dependencies for this module. - * - * @author David M. Lloyd - * @author James R. Perkins - */ -class Messages { - - private Messages() { - } - - /** - * Get a message bundle of the given type. - * - * @param type the bundle type class - * - * @return the bundle - */ - public static T getBundle(final Class type) { - return doPrivileged(new PrivilegedAction() { - public T run() { - final Locale locale = Locale.getDefault(); - final String lang = locale.getLanguage(); - final String country = locale.getCountry(); - final String variant = locale.getVariant(); - - Class bundleClass = null; - if (variant != null && !variant.isEmpty()) try { - bundleClass = Class.forName(join(type.getName(), "$bundle", lang, country, variant), true, type.getClassLoader()).asSubclass(type); - } catch (ClassNotFoundException e) { - // ignore - } - if (bundleClass == null && country != null && !country.isEmpty()) try { - bundleClass = Class.forName(join(type.getName(), "$bundle", lang, country, null), true, type.getClassLoader()).asSubclass(type); - } catch (ClassNotFoundException e) { - // ignore - } - if (bundleClass == null && lang != null && !lang.isEmpty()) try { - bundleClass = Class.forName(join(type.getName(), "$bundle", lang, null, null), true, type.getClassLoader()).asSubclass(type); - } catch (ClassNotFoundException e) { - // ignore - } - if (bundleClass == null) try { - bundleClass = Class.forName(join(type.getName(), "$bundle", null, null, null), true, type.getClassLoader()).asSubclass(type); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Invalid bundle " + type + " (implementation not found)"); - } - final Field field; - try { - field = bundleClass.getField("INSTANCE"); - } catch (NoSuchFieldException e) { - throw new IllegalArgumentException("Bundle implementation " + bundleClass + " has no instance field"); - } - try { - return type.cast(field.get(null)); - } catch (IllegalAccessException e) { - throw new IllegalArgumentException("Bundle implementation " + bundleClass + " could not be instantiated", e); - } - } - }); - } - - private static String join(final String interfaceName, final String type, final String lang, final String country, final String variant) { - final StringBuilder build = new StringBuilder(); - build.append(interfaceName).append('_').append(type); - if (lang != null && !lang.isEmpty()) { - build.append('_'); - build.append(lang); - } - if (country != null && !country.isEmpty()) { - build.append('_'); - build.append(country); - } - if (variant != null && !variant.isEmpty()) { - build.append('_'); - build.append(variant); - } - return build.toString(); - } -} diff --git a/launcher/src/test/java/org/wildfly/core/launcher/CommandBuilderTest.java b/launcher/src/test/java/org/wildfly/core/launcher/CommandBuilderTest.java deleted file mode 100644 index 509cb42a6c9..00000000000 --- a/launcher/src/test/java/org/wildfly/core/launcher/CommandBuilderTest.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.wildfly.core.launcher.Arguments.Argument; - -/** - * @author James R. Perkins - */ -public class CommandBuilderTest { - - private static final Path WILDFLY_HOME; - private static final Path WILDFLY_BOOTABLE_JAR; - - static { - WILDFLY_HOME = Paths.get(System.getProperty("wildfly.launcher.home")).toAbsolutePath().normalize(); - WILDFLY_BOOTABLE_JAR = Paths.get(System.getProperty("wildfly.launcher.bootable.jar")).toAbsolutePath().normalize(); - - // Create some default directories and empty bootable fake jar file - try { - Files.createFile(WILDFLY_BOOTABLE_JAR); - Files.createDirectories(WILDFLY_HOME.resolve("modules")); - Files.createDirectories(WILDFLY_HOME.resolve("configuration")); - Files.createDirectories(WILDFLY_HOME.resolve("data")); - } catch (IOException ignore) { - } - } - - @Test - public void testJBossModulesBuilder() { - // Set up a standalone command builder - final JBossModulesCommandBuilder commandBuilder = JBossModulesCommandBuilder.of(WILDFLY_HOME, "org.jboss.as.launcher.test") - .addJavaOption("-Djava.security.manager") - .addJavaOption("-Djava.net.preferIPv4Stack=true") - .addJavaOption("-Djava.net.preferIPv4Stack=false") - .addModuleOption("-javaagent:test-agent1.jar") - .addServerArgument("--server=test"); - - // Get all the commands - List commands = commandBuilder.buildArguments(); - - Assert.assertTrue("Missing -secmgr option", commands.contains("-secmgr")); - - Assert.assertTrue("Missing jboss-modules.jar", commands.stream().anyMatch(entry -> entry.matches("-javaagent:.*jboss-modules.jar$"))); - Assert.assertTrue("Missing test-agent1.jar", commands.contains("-javaagent:test-agent1.jar")); - Assert.assertTrue("Missing --server=test", commands.contains("--server=test")); - - // If we're using Java 9+ ensure the modular JDK options were added - testModularJvmArguments(commands, 1); - - // A system property should only be added ones - long count = 0L; - for (String s : commandBuilder.getJavaOptions()) { - if (s.contains("java.net.preferIPv4Stack")) { - count++; - } - } - Assert.assertEquals("There should be only one java.net.preferIPv4Stack system property", 1, count); - - // The value saved should be the last value added - Assert.assertTrue("java.net.preferIPv4Stack should be set to false", commandBuilder.getJavaOptions().contains("-Djava.net.preferIPv4Stack=false")); - } - - @Test - public void testStandaloneBuilder() { - // Set up a standalone command builder - final StandaloneCommandBuilder commandBuilder = StandaloneCommandBuilder.of(WILDFLY_HOME) - .setAdminOnly() - .setBindAddressHint("0.0.0.0") - .setDebug(true, 5005) - .setServerConfiguration("standalone-full.xml") - .addJavaOption("-Djava.security.manager") - .addJavaOption("-Djava.net.preferIPv4Stack=true") - .addJavaOption("-Djava.net.preferIPv4Stack=false") - .addModuleOption("-javaagent:test-agent1.jar") - .setBindAddressHint("management", "0.0.0.0"); - - // Get all the commands - List commands = commandBuilder.buildArguments(); - - Assert.assertTrue("--admin-only is missing", commands.contains("--admin-only")); - - Assert.assertTrue("Missing -b=0.0.0.0", commands.contains("-b=0.0.0.0")); - - Assert.assertTrue("Missing -b=0.0.0.0", commands.contains("-bmanagement=0.0.0.0")); - - Assert.assertTrue("Missing debug argument", commands.contains(String.format(StandaloneCommandBuilder.DEBUG_FORMAT, "y", 5005))); - - Assert.assertTrue("Missing server configuration file override", commands.contains("-c=standalone-full.xml")); - - Assert.assertTrue("Missing -secmgr option", commands.contains("-secmgr")); - - Assert.assertTrue("Missing jboss-modules.jar", commands.stream().anyMatch(entry -> entry.matches("-javaagent:.*jboss-modules.jar$"))); - Assert.assertTrue("Missing test-agent1.jar", commands.contains("-javaagent:test-agent1.jar")); - - // If we're using Java 9+ ensure the modular JDK options were added - testModularJvmArguments(commands, 1); - - // A system property should only be added ones - long count = 0L; - for (String s : commandBuilder.getJavaOptions()) { - if (s.contains("java.net.preferIPv4Stack")) { - count++; - } - } - Assert.assertEquals("There should be only one java.net.preferIPv4Stack system property", 1, count); - - // The value saved should be the last value added - Assert.assertTrue("java.net.preferIPv4Stack should be set to false", commandBuilder.getJavaOptions().contains("-Djava.net.preferIPv4Stack=false")); - - // Rename the binding address - commandBuilder.setBindAddressHint(null); - commands = commandBuilder.buildArguments(); - Assert.assertFalse("Binding address should have been removed", commands.contains("-b=0.0.0.0")); - } - - @Test - public void testBootableJarBuilder() { - // Set up a bootable command builder - final BootableJarCommandBuilder commandBuilder = BootableJarCommandBuilder.of(WILDFLY_BOOTABLE_JAR) - .setInstallDir(Paths.get("foo")) - .setInstallDir(Paths.get("bar")) - .setBindAddressHint("0.0.0.0") - .setDebug(true, 5005) - .addJavaOption("-Djava.security.manager") - .addJavaOption("-Djava.net.preferIPv4Stack=true") - .addJavaOption("-Djava.net.preferIPv4Stack=false") - .setBindAddressHint("management", "0.0.0.0") - .setYamlFiles(Path.of("bad.yml")) - .setYamlFiles(Path.of("dummy.yml")); - - // Get all the commands - List commands = commandBuilder.buildArguments(); - - Assert.assertTrue("--install-dir is missing", commands.contains("--install-dir=bar")); - - Assert.assertTrue("Missing -b=0.0.0.0", commands.contains("-b=0.0.0.0")); - - Assert.assertTrue("Missing -b=0.0.0.0", commands.contains("-bmanagement=0.0.0.0")); - - Assert.assertTrue("Missing debug argument", commands.contains(String.format(StandaloneCommandBuilder.DEBUG_FORMAT, "y", 5005))); - - Assert.assertTrue("--yaml is missing", commands.contains("--yaml=" + Path.of("dummy.yml").toFile().getAbsolutePath())); - - // If we're using Java 12+. the enhanced security manager option must be set. - testEnhancedSecurityManager(commands, 1); - // Bootable JAR handles JPMS arguments thanks to its Manifest file. - testJPMSArguments(commands, 0); - // A system property should only be added ones - long count = 0L; - for (String s : commandBuilder.getJavaOptions()) { - if (s.contains("java.net.preferIPv4Stack")) { - count++; - } - } - Assert.assertEquals("There should be only one java.net.preferIPv4Stack system property", 1, count); - - // Install dir should be added once. - count = 0L; - for (String s : commandBuilder.getServerArguments()) { - if (s.contains("--install-dir")) { - count++; - } - } - Assert.assertEquals("There should be only one --install-dir", 1, count); - - // Install dir should be added once. - count = 0L; - for (String s : commandBuilder.getServerArguments()) { - if (s.contains("--yaml")) { - count++; - } - } - Assert.assertEquals("There should be only one --yaml", 1, count); - - // Rename the binding address - commandBuilder.setBindAddressHint(null); - commands = commandBuilder.buildArguments(); - Assert.assertFalse("Binding address should have been removed", commands.contains("-b=0.0.0.0")); - } - - @Test - public void testDomainBuilder() { - // Set up a standalone command builder - final DomainCommandBuilder commandBuilder = DomainCommandBuilder.of(WILDFLY_HOME) - .setAdminOnly() - .setBindAddressHint("0.0.0.0") - .setMasterAddressHint("0.0.0.0") - .setDomainConfiguration("domain.xml") - .setHostConfiguration("host.xml") - .addProcessControllerJavaOption("-Djava.security.manager") - .setBindAddressHint("management", "0.0.0.0"); - - // Get all the commands - List commands = commandBuilder.buildArguments(); - - Assert.assertTrue("--admin-only is missing", commands.contains("--admin-only")); - - Assert.assertTrue("Missing -b=0.0.0.0", commands.contains("-b=0.0.0.0")); - - Assert.assertTrue("Missing -b=0.0.0.0", commands.contains("--primary-address=0.0.0.0")); - - Assert.assertTrue("Missing -b=0.0.0.0", commands.contains("-bmanagement=0.0.0.0")); - - Assert.assertTrue("Missing server configuration file override", commands.contains("-c=domain.xml")); - - Assert.assertTrue("Missing -secmgr option", commands.contains("-secmgr")); - - // If we're using Java 9+ ensure the modular JDK options were added - testModularJvmArguments(commands, 2); - - // Rename the binding address - commandBuilder.setBindAddressHint(null); - commands = commandBuilder.buildArguments(); - Assert.assertFalse("Binding address should have been removed", commands.contains("-b=0.0.0.0")); - } - - @Test - public void testCliBuilder() { - // Set up a standalone command builder - final CliCommandBuilder commandBuilder = CliCommandBuilder.asModularLauncher(WILDFLY_HOME) - .addJavaOption("-Djava.net.preferIPv4Stack=true") - .addJavaOption("-Djava.net.preferIPv4Stack=false"); - - // Get all the commands - final List commands = commandBuilder.buildArguments(); - - // If we're using Java 9+ ensure the modular JDK options were added - testModularJvmArguments(commands, 1); - - // A system property should only be added ones - long count = 0L; - for (String s : commandBuilder.getJavaOptions()) { - if (s.contains("java.net.preferIPv4Stack")) { - count++; - } - } - Assert.assertEquals("There should be only one java.net.preferIPv4Stack system property", 1, count); - - // The value saved should be the last value added - Assert.assertTrue("java.net.preferIPv4Stack should be set to false", commandBuilder.getJavaOptions().contains("-Djava.net.preferIPv4Stack=false")); - } - - @Test - public void testArguments() { - final Arguments arguments = new Arguments(); - arguments.add("-Dkey=value"); - arguments.add("-X"); - arguments.add("-X"); - arguments.set("single-key", "single-value"); - arguments.set("single-key", "single-value"); - arguments.addAll("-Dprop1=value1", "-Dprop2=value2", "-Dprop3=value3"); - - // Validate the arguments - Iterator iter = arguments.getArguments("key").iterator(); - Assert.assertTrue("Missing 'key' entry", iter.hasNext()); - Assert.assertEquals("value", arguments.get("key")); - Assert.assertEquals("-Dkey=value", iter.next().asCommandLineArgument()); - - // -X should have been added twice - Assert.assertEquals(2, arguments.getArguments("-X").size()); - - // Using set should only add the value once - Assert.assertEquals("Should not be more than one 'single-key' argument", 1, arguments.getArguments("single-key").size()); - - // Convert the arguments to a list and ensure each entry has been added in the format expected - final List stringArgs = arguments.asList(); - Assert.assertEquals(7, stringArgs.size()); - Assert.assertTrue("Missing -Dkey=value", stringArgs.contains("-Dkey=value")); - Assert.assertTrue("Missing -X", stringArgs.contains("-X")); - Assert.assertTrue("Missing single-key=single-value", stringArgs.contains("single-key=single-value")); - Assert.assertTrue("Missing -Dprop1=value1", stringArgs.contains("-Dprop1=value1")); - Assert.assertTrue("Missing -Dprop2=value2", stringArgs.contains("-Dprop2=value2")); - Assert.assertTrue("Missing -Dprop3=value3", stringArgs.contains("-Dprop3=value3")); - } - - private void testEnhancedSecurityManager(final Collection command, final int expectedCount) { - // If we're using Java 12+ ensure enhanced security manager option was added - if (Jvm.current().enhancedSecurityManagerAvailable()) { - assertArgumentExists(command, "-Djava.security.manager=allow", expectedCount); - } else { - Assert.assertFalse("Did not expect \"-Djava.security.manager=allow\" to be in the command list", - command.contains("-Djava.security.manager=allow")); - } - } - - private void testJPMSArguments(final Collection command, final int expectedCount) { - // Check exports and opens - assertArgumentExists(command, "--add-exports=java.desktop/sun.awt=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-exports=java.naming/com.sun.jndi.url.ldap=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-exports=java.naming/com.sun.jndi.url.ldaps=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-exports=jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED", expectedCount); - if (getJavaVersion() <= 12) { - // for condition see WFCORE-4296 - java.base/com.sun.net.ssl.internal.ssl isn't available since JDK13 - assertArgumentExists(command, "--add-opens=java.base/com.sun.net.ssl.internal.ssl=ALL-UNNAMED", expectedCount); - } - assertArgumentExists(command, "--add-opens=java.base/java.lang=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.base/java.io=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.base/java.net=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.base/java.security=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.base/java.util=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.base/java.util.concurrent=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.management/javax.management=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-opens=java.naming/javax.naming=ALL-UNNAMED", expectedCount); - assertArgumentExists(command, "--add-modules=java.se", expectedCount); - } - - private static int getJavaVersion() { - return Runtime.version().feature(); - } - - private void testModularJvmArguments(final Collection command, final int expectedCount) { - testEnhancedSecurityManager(command, expectedCount); - testJPMSArguments(command, expectedCount); - } - - private static void assertArgumentExists(final Collection args, final String arg, final int expectedCount) { - int count = 0; - for (String value : args) { - if (value.equals(arg)) { - count++; - } - } - Assert.assertEquals(String.format("Expected %d %s arguments, found %d", expectedCount, arg, count), expectedCount, count); - } - -} diff --git a/launcher/src/test/java/org/wildfly/core/launcher/JvmTest.java b/launcher/src/test/java/org/wildfly/core/launcher/JvmTest.java deleted file mode 100644 index bb4aedfdedb..00000000000 --- a/launcher/src/test/java/org/wildfly/core/launcher/JvmTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Collections; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author James R. Perkins - */ -public class JvmTest { - - @Test - public void testReleaseFile() throws Exception { - testReleaseFile("", false); - testReleaseFile("1.8.0", false); - testReleaseFile("1.8.0_191", false); - testReleaseFile("9", true); - testReleaseFile("9.0", true); - testReleaseFile("9.0.1", true); - testReleaseFile("10", true); - testReleaseFile("10.0", true); - testReleaseFile("10.0.2", true); - testReleaseFile("11", true); - testReleaseFile("11.0.1", true); - } - - private static void testReleaseFile(final String version, final boolean expectedValue) throws IOException { - final Path javaHome = createFakeJavaHome(version); - try { - Assert.assertEquals(String.format("Expected version %s to %s a modular JVM", version, (expectedValue ? "be" : "not be")), - expectedValue, Jvm.of(javaHome).isModular()); - } finally { - Files.walkFileTree(javaHome, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); - } - } - - private static Path createFakeJavaHome(final String version) throws IOException { - final Path javaHome = Files.createTempDirectory("fake-java-home"); - Files.createFile(Files.createDirectory(javaHome.resolve("bin")).resolve(Environment.isWindows() ? "java.exe" : "java")); - final Path releaseFile = javaHome.resolve("release"); - Files.write(releaseFile, Collections.singleton(String.format("JAVA_VERSION=\"%s\"%n", version)), StandardCharsets.UTF_8); - return javaHome; - } -} diff --git a/launcher/src/test/java/org/wildfly/core/launcher/LauncherTest.java b/launcher/src/test/java/org/wildfly/core/launcher/LauncherTest.java deleted file mode 100644 index d1895af6ebf..00000000000 --- a/launcher/src/test/java/org/wildfly/core/launcher/LauncherTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.core.launcher; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - * @author James R. Perkins - */ -public class LauncherTest { - - private Path stdout; - - @Before - public void setup() throws IOException { - stdout = Files.createTempFile("stdout", ".txt"); - } - - @After - public void deleteStdout() throws IOException { - if (stdout != null) { - Files.deleteIfExists(stdout); - } - } - - @Test - public void checkSingleNullEnvironmentVariable() throws Exception { - final TestCommandBuilder commandBuilder = new TestCommandBuilder(); - checkProcess(Launcher.of(commandBuilder).addEnvironmentVariable("TEST", null)); - } - - @Test - public void checkNullEnvironmentVariables() throws Exception { - final TestCommandBuilder commandBuilder = new TestCommandBuilder(); - final Map env = new HashMap<>(); - env.put("TEST", null); - env.put("TEST_2", "test2"); - checkProcess(Launcher.of(commandBuilder).addEnvironmentVariables(env)); - } - - private void checkProcess(final Launcher launcher) throws IOException, InterruptedException { - Process process = null; - try { - process = launcher.setRedirectErrorStream(true).redirectOutput(stdout).launch(); - Assert.assertNotNull("Process should not be null", process); - Assert.assertTrue("Process should have exited within 5 seconds", process.waitFor(5, TimeUnit.SECONDS)); - Assert.assertEquals(String.format("Process should have exited with an exit code of 0:%n%s", Files.readString(stdout)), - 0, process.exitValue()); - } finally { - ProcessHelper.destroyProcess(process); - } - } - - /** - * @author James R. Perkins - */ - private static class TestCommandBuilder implements CommandBuilder { - @Override - public List buildArguments() { - return List.of(); - } - - @Override - public List build() { - return List.of(Jvm.current().getCommand(), "-version"); - } - } -} diff --git a/pom.xml b/pom.xml index f947628c6c4..5a7d122f09c 100644 --- a/pom.xml +++ b/pom.xml @@ -241,6 +241,7 @@ 1.7.0.Final 1.3.0.Final 1.0.3.Final + 1.0.0.Beta1 8.0.2.Final 2.2.5.Final 2.2.2.Final @@ -283,7 +284,6 @@ installation-manager io jmx - launcher model-test network patching @@ -1547,11 +1547,6 @@ wildfly-jmx ${project.version} - - org.wildfly.core - wildfly-launcher - ${project.version} - org.wildfly.core wildfly-jar-runtime @@ -1680,6 +1675,11 @@ wildfly-config-gen ${version.org.wildfly.galleon-plugins} + + org.wildfly.launcher + wildfly-launcher + ${version.org.wildfly.launcher} + org.wildfly.legacy.test wildfly-legacy-spi diff --git a/testsuite/scripts/pom.xml b/testsuite/scripts/pom.xml index 2c2787ab312..1dcc47c9e00 100644 --- a/testsuite/scripts/pom.xml +++ b/testsuite/scripts/pom.xml @@ -28,6 +28,13 @@ ${project.build.directory}${file.separator}test.log + + + org.wildfly.launcher + wildfly-launcher + + + diff --git a/testsuite/shared/pom.xml b/testsuite/shared/pom.xml index 6d2156816b2..60516d8e31c 100644 --- a/testsuite/shared/pom.xml +++ b/testsuite/shared/pom.xml @@ -96,14 +96,14 @@ org.wildfly.core wildfly-controller-client - - org.wildfly.core - wildfly-launcher - org.wildfly.core wildfly-host-controller + + org.wildfly.launcher + wildfly-launcher + io.smallrye jandex diff --git a/testsuite/test-runner/pom.xml b/testsuite/test-runner/pom.xml index f8b2d7d97b7..87a4fd1f272 100644 --- a/testsuite/test-runner/pom.xml +++ b/testsuite/test-runner/pom.xml @@ -47,10 +47,6 @@ org.wildfly.common wildfly-common - - org.wildfly.core - wildfly-launcher - org.wildfly.core wildfly-network @@ -60,6 +56,10 @@ jakarta.inject-api test + + org.wildfly.launcher + wildfly-launcher + org.jboss.logmanager jboss-logmanager