Skip to content

Commit

Permalink
[WFCORE-4748] Allow the MODULE_OPTS to be set and if an -javaagent: i…
Browse files Browse the repository at this point in the history
…s found in the options automatically add jboss-modules as an agent to the VM.

https://issues.redhat.com/browse/WFCORE-4748
  • Loading branch information
jamezp committed Apr 14, 2020
1 parent 5dd1633 commit 35db97c
Show file tree
Hide file tree
Showing 35 changed files with 1,369 additions and 262 deletions.
Expand Up @@ -138,6 +138,7 @@ public enum Element {
MANAGEMENT_CLIENT_CONTENT("management-client-content"),
MANAGEMENT_INTERFACES("management-interfaces"),
MEMBERSHIP_FILTER("membership-filter"),
MODULE_OPTIONS("module-options"),
MULTICAST("multicast"),

NAME("name"),
Expand Down
12 changes: 10 additions & 2 deletions core-feature-pack/src/main/resources/content/bin/standalone.bat
Expand Up @@ -270,10 +270,18 @@ if not "%PRESERVE_JAVA_OPT%" == "true" (


rem Set the module options
set "MODULE_OPTS="
set "MODULE_OPTS=%MODULE_OPTS%"
if "%SECMGR%" == "true" (
set "MODULE_OPTS=-secmgr"
set "MODULE_OPTS=%MODULE_OPTS% -secmgr"
)
setlocal EnableDelayedExpansion
rem Add -client to the JVM options, if supported (32 bit VM), and not overridden
echo "!MODULE_OPTS!" | findstr /I \-javaagent: > nul
if not errorlevel == 1 (
set AGENT_PARAM=-javaagent:"!JBOSS_HOME!\jboss-modules.jar"
set "JAVA_OPTS=!AGENT_PARAM! !JAVA_OPTS!"
)
setlocal DisableDelayedExpansion

echo ===============================================================================
echo.
Expand Down
Expand Up @@ -84,3 +84,6 @@ fi

# Uncomment and edit to use a custom java.security file to override all the Java security properties
#JAVA_OPTS="$JAVA_OPTS -Djava.security.properties==/path/to/custom/java.security"

# Uncomment to add a Java agent
# MODULE_OPTS="-javaagent:agent.jar"
Expand Up @@ -82,3 +82,6 @@ rem # Uncomment and edit to use a custom java.security file to override all the
rem set "JAVA_OPTS=%JAVA_OPTS% -Djava.security.properties==C:\path\to\custom\java.security"

:JAVA_OPTS_SET

rem # Uncomment to add a Java agent
rem set "MODULE_OPTS=-javaagent:agent.jar"
Expand Up @@ -82,3 +82,6 @@ if (-Not $JAVA_OPTS) {

# Uncomment this out to control garbage collection logging
# $GC_LOG=$true

# Uncomment to add a Java agent
# $MODULE_OPTS="-javaagent:agent.jar"
Expand Up @@ -18,6 +18,11 @@ Write-Debug "debug is: $global:DEBUG_MODE"
Write-Debug "debug port: $global:DEBUG_PORT"
Write-Debug "sec mgr: $SECMGR"

$MODULE_OPTS = Get-Env MODULE_OPTS $null
if ($MODULE_OPTS -like "*-javaagent:*") {
$JAVA_OPTS += "-javaagent:$JBOSS_HOME\jboss-modules.jar"
}
Write-Debug "MODULE_OPTS: $MODULE_OPTS"
if ($SECMGR) {
$MODULE_OPTS +="-secmgr";
}
Expand Down
Expand Up @@ -309,10 +309,14 @@ if [ "x$SECURITY_MANAGER_SET" != "x" ]; then
fi

# Set up the module arguments
MODULE_OPTS=""
MODULE_OPTS="$MODULE_OPTS"
if [ "$SECMGR" = "true" ]; then
MODULE_OPTS="$MODULE_OPTS -secmgr";
fi
AGENT_SET=$(echo "$MODULE_OPTS" | $GREP "\-javaagent:")
if [ "x$AGENT_SET" != "x" ]; then
JAVA_OPTS="-javaagent:\"${JBOSS_HOME}/jboss-modules.jar\" ${JAVA_OPTS}"
fi

# Display our environment
echo "========================================================================="
Expand Down
Expand Up @@ -34,6 +34,7 @@
import static org.jboss.as.host.controller.model.jvm.JvmAttributes.LAUNCH_COMMAND;
import static org.jboss.as.host.controller.model.jvm.JvmAttributes.MAX_HEAP_SIZE;
import static org.jboss.as.host.controller.model.jvm.JvmAttributes.MAX_PERMGEN_SIZE;
import static org.jboss.as.host.controller.model.jvm.JvmAttributes.MODULE_OPTIONS;
import static org.jboss.as.host.controller.model.jvm.JvmAttributes.OPTIONS;
import static org.jboss.as.host.controller.model.jvm.JvmAttributes.PERMGEN_SIZE;
import static org.jboss.as.host.controller.model.jvm.JvmAttributes.STACK_SIZE;
Expand Down Expand Up @@ -138,6 +139,9 @@ private void jvmResourceTest(String configFile) throws Exception {
// Get rid of launchCommand attribute to prove we can resource transform without it
ModelNode op = Util.getWriteAttributeOperation(ADDRESS, LAUNCH_COMMAND.getName(), new ModelNode());
mainServices.executeOperation(op, ModelController.OperationTransactionControl.COMMIT);
// TODO (jrp) this seems required, but we should understand why
op = Util.getWriteAttributeOperation(ADDRESS, MODULE_OPTIONS.getName(), new ModelNode());
mainServices.executeOperation(op, ModelController.OperationTransactionControl.COMMIT);
checkCoreModelTransformation(mainServices,
modelVersion,
fixer,
Expand All @@ -153,15 +157,18 @@ private FailedOperationTransformationConfig getConfig() {
.addFailedAttribute(ADDRESS,
FailedOperationTransformationConfig.ChainedConfig.createBuilder(AGENT_PATH, HEAP_SIZE, JAVA_HOME, MAX_HEAP_SIZE,
PERMGEN_SIZE, MAX_PERMGEN_SIZE, STACK_SIZE, OPTIONS, ENVIRONMENT_VARIABLES,
ENV_CLASSPATH_IGNORED, AGENT_LIB, JAVA_AGENT, LAUNCH_COMMAND)
ENV_CLASSPATH_IGNORED, AGENT_LIB, JAVA_AGENT, LAUNCH_COMMAND, MODULE_OPTIONS)
.addConfig(new FailedOperationTransformationConfig.RejectExpressionsConfig(AGENT_PATH, HEAP_SIZE, JAVA_HOME, MAX_HEAP_SIZE,
PERMGEN_SIZE, MAX_PERMGEN_SIZE, STACK_SIZE, OPTIONS, ENVIRONMENT_VARIABLES,
ENV_CLASSPATH_IGNORED, AGENT_LIB, JAVA_AGENT))
.addConfig(new FailedOperationTransformationConfig.NewAttributesConfig(LAUNCH_COMMAND))
.addConfig(new FailedOperationTransformationConfig.NewAttributesConfig(LAUNCH_COMMAND, MODULE_OPTIONS))
.build());
} else if (isFailLaunchCommand()) {
result = new FailedOperationTransformationConfig()
.addFailedAttribute(ADDRESS, new FailedOperationTransformationConfig.NewAttributesConfig(LAUNCH_COMMAND));
.addFailedAttribute(ADDRESS, new FailedOperationTransformationConfig.NewAttributesConfig(LAUNCH_COMMAND, MODULE_OPTIONS));
} else if (modelVersion.getMajor() <= 12) {
result = new FailedOperationTransformationConfig()
.addFailedAttribute(ADDRESS, new FailedOperationTransformationConfig.NewAttributesConfig(MODULE_OPTIONS));
} else {
result = FailedOperationTransformationConfig.NO_FAILURES;
}
Expand Down Expand Up @@ -190,6 +197,8 @@ public ModelNode fixModel(ModelNode modelNode) {
modelNode.remove(SOCKET_BINDING_GROUP);
if (!isIgnoredResourceListAvailableAtRegistration()) {
modelNode.get(SERVER_GROUP, "test", JVM, "full").remove(LAUNCH_COMMAND.getName());
// TODO (jrp) this seems wrong too
modelNode.get(SERVER_GROUP, "test", JVM, "full").remove(MODULE_OPTIONS.getName());
}
return isFailExpressions() ? resolve(modelNode) : modelNode;
}
Expand Down
Expand Up @@ -32,6 +32,7 @@
import static org.jboss.as.domain.controller.resources.ServerGroupResourceDefinition.MANAGEMENT_SUBSYSTEM_ENDPOINT;
import static org.jboss.as.domain.controller.resources.ServerGroupResourceDefinition.SOCKET_BINDING_DEFAULT_INTERFACE;
import static org.jboss.as.domain.controller.resources.ServerGroupResourceDefinition.SOCKET_BINDING_PORT_OFFSET;
import static org.jboss.as.host.controller.model.jvm.JvmAttributes.MODULE_OPTIONS;

import java.util.List;
import java.util.function.Predicate;
Expand Down Expand Up @@ -123,7 +124,8 @@ public void testRejectTransformersEAP() throws Exception {
FailedOperationTransformationConfig.ChainedConfig.createBuilder(MANAGEMENT_SUBSYSTEM_ENDPOINT, SOCKET_BINDING_PORT_OFFSET, SOCKET_BINDING_DEFAULT_INTERFACE)
.addConfig(new FailedOperationTransformationConfig.RejectExpressionsConfig(MANAGEMENT_SUBSYSTEM_ENDPOINT, SOCKET_BINDING_PORT_OFFSET))
.addConfig(new FailedOperationTransformationConfig.NewAttributesConfig(SOCKET_BINDING_DEFAULT_INTERFACE))
.build().setReadOnly(MANAGEMENT_SUBSYSTEM_ENDPOINT)));
.build().setReadOnly(MANAGEMENT_SUBSYSTEM_ENDPOINT))
.addFailedAttribute(serverGroupAddress.append("jvm", "full"), new FailedOperationTransformationConfig.NewAttributesConfig(MODULE_OPTIONS)));

//check that we reject /server-group=main-server-group:suspend-servers(timeout=?)
OperationTransformer.TransformedOperation transOp = mainServices.transformOperation(modelVersion, Util.createOperation("suspend-servers", serverGroupAddress));
Expand Down
Expand Up @@ -20,6 +20,9 @@
<variable name="name2" value="value2"/>
</environment-variables>
<launch-command prefix="command-prefix"/>
<module-options>
<option value="-javaagent:jboss-modules.jar"/>
</module-options>
</jvm>
<!-- Needed for the add operation -->
<socket-binding-group ref="test-sockets"/>
Expand Down
Expand Up @@ -20,6 +20,9 @@
<variable name="name2" value="${mytest.value2:value2}"/>
</environment-variables>
<launch-command prefix="${mytest.value:command-prefix}"/>
<module-options>
<option value="${mytest.agent.value:-javaagent:jboss-modules.jar}"/>
</module-options>
</jvm>
<!-- Needed for the add operation -->
<socket-binding-group ref="test-sockets"/>
Expand Down
Expand Up @@ -31,6 +31,9 @@
<variable name="name1" value="value1"/>
<variable name="name2" value="value2"/>
</environment-variables>
<module-options>
<option value="-javaagent:jboss-modules.jar"/>
</module-options>
</jvm>

<socket-binding-group ref="test-sockets" port-offset="10" default-interface="public-two"/>
Expand Down
Expand Up @@ -22,6 +22,7 @@

package org.jboss.as.domain.controller.transformers;

import static org.jboss.as.domain.controller.transformers.KernelAPIVersion.VERSION_12_0;
import static org.jboss.as.domain.controller.transformers.KernelAPIVersion.VERSION_1_7;
import static org.jboss.as.domain.controller.transformers.KernelAPIVersion.VERSION_1_8;
import static org.jboss.as.domain.controller.transformers.KernelAPIVersion.VERSION_2_0;
Expand Down Expand Up @@ -146,7 +147,7 @@ private static void registerChainedManagementTransformers(TransformerRegistry re

private static void registerChainedServerGroupTransformers(TransformerRegistry registry) {
ChainedTransformationDescriptionBuilder builder = ServerGroupTransformers.buildTransformerChain();
registerChainedTransformer(registry, builder, VERSION_8_0, VERSION_7_0, VERSION_6_0, VERSION_5_0, VERSION_4_1, VERSION_4_0, VERSION_3_0, VERSION_2_1, VERSION_2_0, VERSION_1_8, VERSION_1_7);
registerChainedTransformer(registry, builder, VERSION_12_0, VERSION_8_0, VERSION_7_0, VERSION_6_0, VERSION_5_0, VERSION_4_1, VERSION_4_0, VERSION_3_0, VERSION_2_1, VERSION_2_0, VERSION_1_8, VERSION_1_7);
}

private static void registerProfileTransformers(TransformerRegistry registry) {
Expand Down
Expand Up @@ -26,6 +26,7 @@
import org.jboss.as.controller.transform.description.DiscardAttributeChecker;
import org.jboss.as.controller.transform.description.RejectAttributeChecker;
import org.jboss.as.controller.transform.description.ResourceTransformationDescriptionBuilder;
import org.jboss.as.host.controller.model.jvm.JvmAttributes;
import org.jboss.as.host.controller.model.jvm.JvmResourceDefinition;

/**
Expand All @@ -44,4 +45,18 @@ public static void registerTransformers2_1_AndBelow(ResourceTransformationDescri
.addRejectCheck(RejectAttributeChecker.DEFINED, LAUNCH_COMMAND)
.end();
}


public static void registerTransformers12_AndBelow(ResourceTransformationDescriptionBuilder parent) {
parent.addChildResource(JvmResourceDefinition.GLOBAL.getPathElement())
.getAttributeBuilder()
.setDiscard(DiscardAttributeChecker.UNDEFINED, JvmAttributes.MODULE_OPTIONS)
.addRejectCheck(RejectAttributeChecker.DEFINED, JvmAttributes.MODULE_OPTIONS)
.end();
parent.addChildResource(JvmResourceDefinition.SERVER.getPathElement())
.getAttributeBuilder()
.setDiscard(DiscardAttributeChecker.UNDEFINED, JvmAttributes.MODULE_OPTIONS)
.addRejectCheck(RejectAttributeChecker.DEFINED, JvmAttributes.MODULE_OPTIONS)
.end();
}
}
Expand Up @@ -47,8 +47,12 @@ static ChainedTransformationDescriptionBuilder buildTransformerChain() {
//////////////////////////////////
//The EAP/AS 7.x chains

// module-options was introduced in 13, WildFly 20
ResourceTransformationDescriptionBuilder current130 = createBuilderFromCurrent(chainedBuilder, KernelAPIVersion.VERSION_12_0);
JvmTransformers.registerTransformers12_AndBelow(current130);

//timeout attribute renamed to suspend-timeout in Version 9.0. Must be renamed for 8.0 and below
ResourceTransformationDescriptionBuilder currentTo80 = createBuilderFromCurrent(chainedBuilder, KernelAPIVersion.VERSION_8_0);
ResourceTransformationDescriptionBuilder currentTo80 = createBuilder(chainedBuilder, KernelAPIVersion.VERSION_12_0, KernelAPIVersion.VERSION_8_0);
DomainServerLifecycleHandlers.registerTimeoutToSuspendTimeoutRename(currentTo80);

// kill-servers and destroy-servers are rejected since 5.0 and below
Expand Down
Expand Up @@ -292,6 +292,8 @@ private List<String> getServerLaunchCommand(boolean includeProcessId, boolean fo
command.addAll(commandPrefix);
}

final String jbossModulesJar = getAbsolutePath(environment.getHomeDir(), "jboss-modules.jar");

JvmType localJvmType = getJvmType(forLaunch);

command.add(localJvmType.getJavaExecutable());
Expand All @@ -304,6 +306,11 @@ private List<String> getServerLaunchCommand(boolean includeProcessId, boolean fo
command.add("-D[" + ManagedServer.getServerProcessId(processId) + "]");
}

// If the module options include a Java agent we'll add jboss-modules.jar by default
if (jvmElement.getModuleOptionsElement().contains("\\-javaagent:.*")) {
command.add("-javaagent:" + jbossModulesJar);
}

JvmOptionsBuilderFactory.getInstance(localJvmType).addOptions(jvmElement, command);

Map<String, String> bootTimeProperties = getAllSystemProperties(true);
Expand Down Expand Up @@ -375,13 +382,14 @@ private List<String> getServerLaunchCommand(boolean includeProcessId, boolean fo
}

command.add("-jar");
command.add(getAbsolutePath(environment.getHomeDir(), "jboss-modules.jar"));
command.add(jbossModulesJar);
command.add("-mp");
command.add(environment.getModulePath());
// Enable the security manager if required
if (environment.isSecurityManagerEnabled()){
command.add("-secmgr");
}
command.addAll(jvmElement.getModuleOptionsElement().getOptions());
command.add("org.jboss.as.server");

if(suspend) {
Expand Down
Expand Up @@ -32,7 +32,6 @@
import java.net.URL;
import java.nio.file.Path;
import java.util.concurrent.ExecutionException;

import javax.security.sasl.SaslException;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
Expand Down Expand Up @@ -1452,4 +1451,14 @@ void noDomainControllerConfigurationProvidedForAdminOnly(String policyAttribute,
@Message(id = 215, value = "Could not find java executable under %s.")
IllegalStateException cannotFindJavaExe(String binDir);

/**
* Creates an exception inidcating the module options is not allowed.
*
* @param option the option that is not allowed
*
* @return an {@link OperationFailedException} for the error
*/
@Message(id = 216, value = "The module option %s is not allowed.")
OperationFailedException moduleOptionNotAllowed(String option);

}
Expand Up @@ -21,6 +21,7 @@
*/
package org.jboss.as.host.controller.model.jvm;

import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import javax.xml.stream.XMLStreamException;
Expand All @@ -29,6 +30,7 @@
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.AttributeMarshaller;
import org.jboss.as.controller.ModelVersion;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PropertiesAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
Expand All @@ -38,6 +40,7 @@
import org.jboss.as.controller.operations.validation.EnumValidator;
import org.jboss.as.controller.operations.validation.StringLengthValidator;
import org.jboss.as.controller.parsing.Element;
import org.jboss.as.host.controller.logging.HostControllerLogger;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;

Expand Down Expand Up @@ -116,6 +119,31 @@ public class JvmAttributes {
.setXmlName(JvmAttributes.JVM_LAUNCH_COMMAND)
.addAccessConstraint(SensitiveTargetAccessConstraintDefinition.JVM)
.build();
/**
* Module options are resolved in ManagedServerBootCmdFactory before the JVM is launched.
*/
public static final AttributeDefinition MODULE_OPTIONS = new StringListAttributeDefinition.Builder("module-options")
.setElementValidator(new ModuleOptionsValidator())
.setRequired(false)
.setAllowExpression(true)
.setAttributeMarshaller(new AttributeMarshaller() {
@Override
public void marshallAsElement(AttributeDefinition attribute, ModelNode resourceModel, boolean marshallDefault, XMLStreamWriter writer) throws XMLStreamException {
if (resourceModel.hasDefined(attribute.getName())) {
List<ModelNode> list = resourceModel.get(attribute.getName()).asList();
if (!list.isEmpty()) {
writer.writeStartElement(attribute.getName());
for (ModelNode child : list) {
writer.writeEmptyElement(Element.OPTION.getLocalName());
writer.writeAttribute(ModelDescriptionConstants.VALUE, child.asString());
}
writer.writeEndElement();
}
}
}
})
.addAccessConstraint(SensitiveTargetAccessConstraintDefinition.JVM)
.build();
/**
* JVM options are resolved in ManagedServerBootCmdFactory before the JVM is launched.
*/
Expand Down Expand Up @@ -201,14 +229,32 @@ public void marshallAsElement(AttributeDefinition attribute, ModelNode resourceM

private static final AttributeDefinition[] GLOBAL_ATTRIBUTES = new AttributeDefinition[] {
AGENT_LIB, AGENT_PATH, ENV_CLASSPATH_IGNORED, ENVIRONMENT_VARIABLES, JAVA_AGENT, JAVA_HOME,
LAUNCH_COMMAND, OPTIONS, STACK_SIZE, TYPE, HEAP_SIZE, MAX_HEAP_SIZE, PERMGEN_SIZE, MAX_PERMGEN_SIZE};
LAUNCH_COMMAND, MODULE_OPTIONS, OPTIONS, STACK_SIZE, TYPE, HEAP_SIZE, MAX_HEAP_SIZE, PERMGEN_SIZE, MAX_PERMGEN_SIZE};

private static final AttributeDefinition[] SERVER_ATTRIBUTES = new AttributeDefinition[] {
AGENT_LIB, AGENT_PATH, ENV_CLASSPATH_IGNORED, ENVIRONMENT_VARIABLES, JAVA_AGENT, JAVA_HOME,
LAUNCH_COMMAND, OPTIONS, STACK_SIZE, TYPE, HEAP_SIZE, MAX_HEAP_SIZE, PERMGEN_SIZE, MAX_PERMGEN_SIZE,
LAUNCH_COMMAND, MODULE_OPTIONS, OPTIONS, STACK_SIZE, TYPE, HEAP_SIZE, MAX_HEAP_SIZE, PERMGEN_SIZE, MAX_PERMGEN_SIZE,
DEBUG_ENABLED, DEBUG_OPTIONS};

static AttributeDefinition[] getAttributes(boolean server) {
return server ? SERVER_ATTRIBUTES : GLOBAL_ATTRIBUTES;
}



private static class ModuleOptionsValidator extends StringLengthValidator {
private final List<String> valuesNotAllowed = Arrays.asList("-mp", "--modulepath", "-secmgr");
public ModuleOptionsValidator() {
super(1, true, true);
}

@Override
public void validateParameter(final String parameterName, final ModelNode value) throws OperationFailedException {
super.validateParameter(parameterName, value);
final String option = value.asString();
if (valuesNotAllowed.contains(option)) {
throw HostControllerLogger.ROOT_LOGGER.moduleOptionNotAllowed(option);
}
}
}
}

0 comments on commit 35db97c

Please sign in to comment.