diff --git a/bootable-jar/runtime/src/main/java/org/wildfly/core/jar/runtime/Server.java b/bootable-jar/runtime/src/main/java/org/wildfly/core/jar/runtime/Server.java
index 16ccda0424e..e998374da8e 100644
--- a/bootable-jar/runtime/src/main/java/org/wildfly/core/jar/runtime/Server.java
+++ b/bootable-jar/runtime/src/main/java/org/wildfly/core/jar/runtime/Server.java
@@ -27,6 +27,7 @@
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.helpers.DelegatingModelControllerClient;
import org.jboss.as.server.Bootstrap;
+import org.jboss.as.server.ElapsedTime;
import org.jboss.as.server.Main;
import org.jboss.as.server.ServerEnvironment;
import org.jboss.as.server.ServerService;
@@ -147,7 +148,8 @@ public void exit(int status) {
});
// Determine the ServerEnvironment
- ServerEnvironment serverEnvironment = Main.determineEnvironment(cmdargs, systemProps, systemEnv, ServerEnvironment.LaunchType.STANDALONE, startTime).getServerEnvironment();
+ ServerEnvironment serverEnvironment = Main.determineEnvironment(cmdargs, systemProps, systemEnv,
+ ServerEnvironment.LaunchType.STANDALONE, ElapsedTime.startingFromJvmStart()).getServerEnvironment();
if (serverEnvironment == null) {
// Nothing to do
return;
diff --git a/embedded/src/main/java/org/wildfly/core/embedded/ChainedContext.java b/embedded/src/main/java/org/wildfly/core/embedded/ChainedContext.java
index 6c2b896504c..7d224bf1031 100644
--- a/embedded/src/main/java/org/wildfly/core/embedded/ChainedContext.java
+++ b/embedded/src/main/java/org/wildfly/core/embedded/ChainedContext.java
@@ -11,6 +11,8 @@
import org.wildfly.core.embedded.logging.EmbeddedLogger;
/**
+ * A {@link Context} that wraps other contexts and invokes them in the order they are {@link #add(Context) added}.
+ *
* @author James R. Perkins
*/
class ChainedContext implements Context {
diff --git a/embedded/src/main/java/org/wildfly/core/embedded/Configuration.java b/embedded/src/main/java/org/wildfly/core/embedded/Configuration.java
index f3c483f981a..d4cc5093960 100644
--- a/embedded/src/main/java/org/wildfly/core/embedded/Configuration.java
+++ b/embedded/src/main/java/org/wildfly/core/embedded/Configuration.java
@@ -19,7 +19,7 @@
import org.wildfly.core.embedded.logging.EmbeddedLogger;
/**
- * Represents a configuration for the embedded server.
+ * Represents a configuration for creating an {@link EmbeddedManagedProcess}.
*
* @author James R. Perkins
*/
diff --git a/embedded/src/main/java/org/wildfly/core/embedded/Context.java b/embedded/src/main/java/org/wildfly/core/embedded/Context.java
index 6ce135ecede..5de00bfb30b 100644
--- a/embedded/src/main/java/org/wildfly/core/embedded/Context.java
+++ b/embedded/src/main/java/org/wildfly/core/embedded/Context.java
@@ -6,7 +6,7 @@
package org.wildfly.core.embedded;
/**
- * A context used to activate and restore the environment for embedded containers.
+ * A context used to activate and restore the environment for an {@link EmbeddedManagedProcess}.
*
* @author James R. Perkins
*/
diff --git a/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedHostControllerFactory.java b/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedHostControllerFactory.java
index 73a0f9339de..90b392d2889 100644
--- a/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedHostControllerFactory.java
+++ b/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedHostControllerFactory.java
@@ -32,6 +32,7 @@
import org.jboss.as.controller.ProcessType;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.helpers.DelegatingModelControllerClient;
+import org.jboss.as.server.ElapsedTime;
import org.jboss.as.host.controller.DomainModelControllerService;
import org.jboss.as.host.controller.HostControllerEnvironment;
import org.jboss.as.host.controller.Main;
@@ -234,12 +235,12 @@ public void propertyChange(PropertyChangeEvent evt) {
@Override
public void start() throws EmbeddedProcessStartException {
+ ElapsedTime elapsedTime = ElapsedTime.startingFromNow();
ClassLoader tccl = SecurityActions.getTccl();
try {
SecurityActions.setTccl(embeddedModuleCL);
EmbeddedHostControllerBootstrap hostControllerBootstrap = null;
try {
- final long startTime = System.currentTimeMillis();
// Take control of server use of System.exit
SystemExiter.initialize(new SystemExiter.Exiter() {
@Override
@@ -249,7 +250,7 @@ public void exit(int status) {
});
// Determine the HostControllerEnvironment
- HostControllerEnvironment environment = createHostControllerEnvironment(jbossHomeDir, cmdargs, startTime);
+ HostControllerEnvironment environment = createHostControllerEnvironment(jbossHomeDir, cmdargs, elapsedTime);
FutureServiceContainer futureContainer = new FutureServiceContainer();
final byte[] authBytes = new byte[16];
@@ -400,7 +401,8 @@ private void exit() {
SystemExiter.initialize(SystemExiter.Exiter.DEFAULT);
}
- private static HostControllerEnvironment createHostControllerEnvironment(File jbossHome, String[] cmdargs, long startTime) {
+ private static HostControllerEnvironment createHostControllerEnvironment(File jbossHome, String[] cmdargs,
+ ElapsedTime elapsedTime) {
SecurityActions.setPropertyPrivileged(HostControllerEnvironment.HOME_DIR, jbossHome.getAbsolutePath());
List cmds = new ArrayList(Arrays.asList(cmdargs));
@@ -427,7 +429,7 @@ private static HostControllerEnvironment createHostControllerEnvironment(File jb
if (value != null)
cmds.add("-D" + prop + "=" + value);
}
- return Main.determineEnvironment(cmds.toArray(new String[cmds.size()]), startTime, ProcessType.EMBEDDED_HOST_CONTROLLER).getHostControllerEnvironment();
+ return Main.determineEnvironment(cmds.toArray(new String[cmds.size()]), elapsedTime, ProcessType.EMBEDDED_HOST_CONTROLLER).getHostControllerEnvironment();
}
diff --git a/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedProcessFactory.java b/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedProcessFactory.java
index 50b938499a3..5fd12279a0c 100644
--- a/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedProcessFactory.java
+++ b/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedProcessFactory.java
@@ -140,7 +140,14 @@ public static StandaloneServer createStandaloneServer(final Configuration config
setupVfsModule(moduleLoader);
- // Load the Embedded Server Module
+ // Load the org.wildfly.embedded module using the ModuleLoader from the Configuration
+ //
+ // Note that, depending on the Configuration, the classes in this module may be of a different
+ // version from those with the same name included in the archive that provides this
+ // EmbeddedProcessFactory class. The module must provide a factory class whose name matches SERVER_FACTORY
+ // that provides a 'create' method with the same parameter types as the one provided by the same class
+ // in this class's artifact, and that returns an object that provides methods with the same signatures
+ // as those in the EmbeddedManagedProcess interface included in this class's artifact.
final Module embeddedModule;
try {
embeddedModule = moduleLoader.loadModule(MODULE_ID_EMBEDDED);
@@ -148,7 +155,7 @@ public static StandaloneServer createStandaloneServer(final Configuration config
throw EmbeddedLogger.ROOT_LOGGER.moduleLoaderError(mle, MODULE_ID_EMBEDDED, moduleLoader);
}
- // Load the Embedded Server Factory via the modular environment
+ // Load the EmbeddedStandaloneServerFactory via the modular environment.
final ModuleClassLoader embeddedModuleCL = embeddedModule.getClassLoader();
final Class> embeddedServerFactoryClass;
final Class> standaloneServerClass;
@@ -238,7 +245,14 @@ public static HostController createHostController(final Configuration configurat
setupVfsModule(moduleLoader);
- // Load the Embedded Server Module
+ // Load the org.wildfly.embedded module using the ModuleLoader from the Configuration
+ //
+ // Note that, depending on the Configuration, the classes in this module may be of a different
+ // version from those with the same name included in the archive that provides this
+ // EmbeddedProcessFactory class. The module must provide a factory class whose name matches HOST_FACTORY
+ // that provides a 'create' method with the same parameter types as the one provided by the same class
+ // in this class's artifact, and that returns an object that provides methods with the same signatures
+ // as those in the EmbeddedManagedProcess interface included in this class's artifact.
final Module embeddedModule;
try {
embeddedModule = moduleLoader.loadModule(MODULE_ID_EMBEDDED);
@@ -246,7 +260,7 @@ public static HostController createHostController(final Configuration configurat
throw EmbeddedLogger.ROOT_LOGGER.moduleLoaderError(mle, MODULE_ID_EMBEDDED, moduleLoader);
}
- // Load the Embedded Server Factory via the modular environment
+ // Load the EmbeddedHostControllerFactory via the modular environment
final ModuleClassLoader embeddedModuleCL = embeddedModule.getClassLoader();
final Class> embeddedHostControllerFactoryClass;
final Class> hostControllerClass;
diff --git a/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedStandaloneServerFactory.java b/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedStandaloneServerFactory.java
index 32e044f7b0b..af60e960c6c 100644
--- a/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedStandaloneServerFactory.java
+++ b/embedded/src/main/java/org/wildfly/core/embedded/EmbeddedStandaloneServerFactory.java
@@ -29,6 +29,7 @@
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.helpers.DelegatingModelControllerClient;
import org.jboss.as.server.Bootstrap;
+import org.jboss.as.server.ElapsedTime;
import org.jboss.as.server.Main;
import org.jboss.as.server.ServerEnvironment;
import org.jboss.as.server.ServerService;
@@ -239,6 +240,7 @@ public ModelControllerClient getDelegate() {
@Override
public void start() throws EmbeddedProcessStartException {
+ ElapsedTime elapsedTime = ElapsedTime.startingFromNow();
ClassLoader tccl = SecurityActions.getTccl();
try {
SecurityActions.setTccl(embeddedModuleCL);
@@ -255,7 +257,8 @@ public void exit(int status) {
});
// Determine the ServerEnvironment
- ServerEnvironment serverEnvironment = Main.determineEnvironment(cmdargs, systemProps, systemEnv, ServerEnvironment.LaunchType.EMBEDDED, startTime).getServerEnvironment();
+ ServerEnvironment serverEnvironment = Main.determineEnvironment(cmdargs, systemProps, systemEnv,
+ ServerEnvironment.LaunchType.EMBEDDED, elapsedTime).getServerEnvironment();
if (serverEnvironment == null) {
// Nothing to do
return;
diff --git a/host-controller/src/main/java/org/jboss/as/host/controller/HostControllerEnvironment.java b/host-controller/src/main/java/org/jboss/as/host/controller/HostControllerEnvironment.java
index f7957902401..e81ad72e3cf 100644
--- a/host-controller/src/main/java/org/jboss/as/host/controller/HostControllerEnvironment.java
+++ b/host-controller/src/main/java/org/jboss/as/host/controller/HostControllerEnvironment.java
@@ -6,6 +6,7 @@
package org.jboss.as.host.controller;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE;
+import static org.jboss.as.server.ElapsedTime.startingFromNow;
import java.io.File;
import java.io.IOException;
@@ -25,6 +26,7 @@
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.ProcessType;
import org.jboss.as.controller.RunningMode;
+import org.jboss.as.server.ElapsedTime;
import org.jboss.as.controller.operations.common.ProcessEnvironment;
import org.jboss.as.controller.persistence.ConfigurationFile;
import org.jboss.as.host.controller.jvm.JvmType;
@@ -246,7 +248,7 @@ public class HostControllerEnvironment extends ProcessEnvironment {
private final HostRunningModeControl runningModeControl;
private final boolean securityManagerEnabled;
private final UUID hostControllerUUID;
- private final long startTime;
+ private final ElapsedTime elapsedTime;
private final ProcessType processType;
/** Only for test cases */
@@ -256,14 +258,14 @@ public HostControllerEnvironment(Map hostSystemProperties, boole
String initialHostConfig, RunningMode initialRunningMode, boolean backupDomainFiles, boolean useCachedDc, ProductConfig productConfig) {
this(hostSystemProperties, isRestart, modulePath, processControllerAddress, processControllerPort, hostControllerAddress, hostControllerPort, defaultJVM,
domainConfig, initialDomainConfig, hostConfig, initialHostConfig, initialRunningMode, backupDomainFiles, useCachedDc, productConfig, false,
- System.currentTimeMillis(), ProcessType.HOST_CONTROLLER, ConfigurationFile.InteractionPolicy.STANDARD, ConfigurationFile.InteractionPolicy.STANDARD);
+ startingFromNow(), ProcessType.HOST_CONTROLLER, ConfigurationFile.InteractionPolicy.STANDARD, ConfigurationFile.InteractionPolicy.STANDARD);
}
public HostControllerEnvironment(Map hostSystemProperties, boolean isRestart, String modulePath,
InetAddress processControllerAddress, Integer processControllerPort, InetAddress hostControllerAddress,
Integer hostControllerPort, String defaultJVM, String domainConfig, String initialDomainConfig, String hostConfig,
String initialHostConfig, RunningMode initialRunningMode, boolean backupDomainFiles, boolean useCachedDc,
- ProductConfig productConfig, boolean securityManagerEnabled, long startTime, ProcessType processType,
+ ProductConfig productConfig, boolean securityManagerEnabled, ElapsedTime elapsedTime, ProcessType processType,
ConfigurationFile.InteractionPolicy hostConfigInteractionPolicy, ConfigurationFile.InteractionPolicy domainConfigInteractionPolicy) {
this.hostSystemProperties = new HashMap<>(Assert.checkNotNullParam("hostSystemProperties", hostSystemProperties));
@@ -278,7 +280,7 @@ public HostControllerEnvironment(Map hostSystemProperties, boole
this.hostControllerPort = hostControllerPort;
this.isRestart = isRestart;
this.modulePath = modulePath;
- this.startTime = startTime;
+ this.elapsedTime = elapsedTime;
this.initialRunningMode = initialRunningMode;
this.runningModeControl = new HostRunningModeControl(initialRunningMode, RestartMode.SERVERS);
this.domainConfigInteractionPolicy = domainConfigInteractionPolicy;
@@ -782,7 +784,7 @@ public String getHostControllerName() {
* @return the time, in ms since the epoch
*/
public long getStartTime() {
- return startTime;
+ return elapsedTime.getStartTime();
}
@Override
@@ -868,6 +870,15 @@ boolean isSecurityManagerEnabled() {
return securityManagerEnabled;
}
+ /**
+ * Gets this Host Controller's {@link ElapsedTime} tracker.
+ *
+ * @return the elapsed time tracker. Will not be {@code null}.
+ */
+ ElapsedTime getElapsedTime() {
+ return elapsedTime;
+ }
+
/**
* Get a File from configuration.
* @param name the name of the property
diff --git a/host-controller/src/main/java/org/jboss/as/host/controller/HostControllerService.java b/host-controller/src/main/java/org/jboss/as/host/controller/HostControllerService.java
index 80ecc07745e..f8deb495d74 100644
--- a/host-controller/src/main/java/org/jboss/as/host/controller/HostControllerService.java
+++ b/host-controller/src/main/java/org/jboss/as/host/controller/HostControllerService.java
@@ -36,6 +36,7 @@
import org.jboss.as.remoting.HttpListenerRegistryService;
import org.jboss.as.remoting.management.ManagementRemotingServices;
import org.jboss.as.server.BootstrapListener;
+import org.jboss.as.server.ElapsedTime;
import org.jboss.as.server.FutureServiceContainer;
import org.jboss.as.server.Services;
import org.jboss.as.server.logging.ServerLogger;
@@ -78,8 +79,9 @@ public JBossThreadFactory run() {
private final ControlledProcessState processState;
private final String authCode;
private final CapabilityRegistry capabilityRegistry;
+ private final ElapsedTime elapsedTime;
private volatile FutureServiceContainer futureContainer;
- private volatile long startTime;
+ private volatile boolean everStopped;
public HostControllerService(final HostControllerEnvironment environment, final HostRunningModeControl runningModeControl,
final String authCode, final ControlledProcessState processState, FutureServiceContainer futureContainer) {
@@ -87,7 +89,7 @@ public HostControllerService(final HostControllerEnvironment environment, final
this.runningModeControl = runningModeControl;
this.authCode = authCode;
this.processState = processState;
- this.startTime = environment.getStartTime();
+ this.elapsedTime = environment.getElapsedTime();
this.futureContainer = futureContainer;
this.capabilityRegistry = new CapabilityRegistry(false);
}
@@ -99,8 +101,10 @@ public HostControllerService(final HostControllerEnvironment environment, final
@Override
public void start(StartContext context) throws StartException {
- //Moved to AbstractControllerService.start()
- // processState.setStarting();
+
+ // If this is a reload, track start time independently of the overall process elapsed time
+ ElapsedTime startupTime = everStopped ? elapsedTime.checkpoint() : elapsedTime;
+
final ProductConfig config = environment.getProductConfig();
final String prettyVersion = config.getPrettyVersionString();
final String banner = environment.getStability() == org.jboss.as.version.Stability.EXPERIMENTAL ? config.getBanner() : "";
@@ -149,14 +153,7 @@ public void start(StartContext context) throws StartException {
final ServiceContainer serviceContainer = myController.getServiceContainer();
- long startTime = this.startTime;
- if (startTime == -1) {
- startTime = System.currentTimeMillis();
- } else {
- this.startTime = -1;
- }
-
- final BootstrapListener bootstrapListener = new BootstrapListener(serviceContainer, startTime, serviceTarget, futureContainer, prettyVersion + " (Host Controller)", environment.getDomainTempDir());
+ final BootstrapListener bootstrapListener = new BootstrapListener(serviceContainer, startupTime, serviceTarget, futureContainer, prettyVersion + " (Host Controller)", environment.getDomainTempDir());
bootstrapListener.getStabilityMonitor().addController(myController);
// The first default services are registered before the bootstrap operations are executed.
@@ -209,6 +206,7 @@ public void stop(StopContext context) {
//processState.setStopping();
ServerLogger.AS_ROOT_LOGGER.serverStopped(prettyVersion, (int) (context.getElapsedTime() / 1000000L));
BootstrapListener.deleteStartupMarker(environment.getDomainTempDir());
+ everStopped = true;
}
@Override
diff --git a/host-controller/src/main/java/org/jboss/as/host/controller/Main.java b/host-controller/src/main/java/org/jboss/as/host/controller/Main.java
index a7f27164747..cd61ebc8d77 100644
--- a/host-controller/src/main/java/org/jboss/as/host/controller/Main.java
+++ b/host-controller/src/main/java/org/jboss/as/host/controller/Main.java
@@ -5,6 +5,8 @@
package org.jboss.as.host.controller;
+import static org.jboss.as.server.ElapsedTime.startingFromJvmStart;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -24,6 +26,7 @@
import org.jboss.as.controller.ProcessType;
import org.jboss.as.controller.RunningMode;
import org.jboss.as.controller.interfaces.InetAddressUtil;
+import org.jboss.as.server.ElapsedTime;
import org.jboss.as.controller.operations.common.ProcessEnvironment;
import org.jboss.as.controller.persistence.ConfigurationFile;
import org.jboss.as.host.controller.logging.HostControllerLogger;
@@ -124,9 +127,8 @@ public static HostControllerBootstrap create(String[] args, final String authCod
private HostControllerBootstrap boot(String[] args, final String authCode) {
try {
- // TODO make this settable via an embedding process
- final long startTime = Module.getStartTime();
- final HostControllerEnvironmentWrapper hostControllerEnvironmentWrapper = determineEnvironment(args, startTime);
+ final HostControllerEnvironmentWrapper hostControllerEnvironmentWrapper =
+ determineEnvironment(args, startingFromJvmStart(), ProcessType.HOST_CONTROLLER);
if (hostControllerEnvironmentWrapper.getHostControllerEnvironment() == null) {
usage(hostControllerEnvironmentWrapper.getProductConfig()); // In case there was an error determining the environment print the usage
if (hostControllerEnvironmentWrapper.getHostControllerEnvironmentStatus() == HostControllerEnvironmentWrapper.HostControllerEnvironmentStatus.ERROR) {
@@ -188,11 +190,9 @@ private static void usage(ProductConfig productConfig) {
CommandLineArgumentUsageImpl.printUsage(productConfig, STDOUT);
}
- public static HostControllerEnvironmentWrapper determineEnvironment(String[] args, long startTime) {
- return determineEnvironment(args, startTime, ProcessType.HOST_CONTROLLER);
- }
-
- public static HostControllerEnvironmentWrapper determineEnvironment(String[] args, long startTime, ProcessType processType) {
+ public static HostControllerEnvironmentWrapper determineEnvironment(String[] args,
+ ElapsedTime elapsedTime,
+ ProcessType processType) {
Integer pmPort = null;
InetAddress pmAddress = null;
final PCSocketConfig pcSocketConfig = new PCSocketConfig();
@@ -479,7 +479,7 @@ public static HostControllerEnvironmentWrapper determineEnvironment(String[] arg
return new HostControllerEnvironmentWrapper(new HostControllerEnvironment(hostSystemProperties, isRestart, modulePath,
pmAddress, pmPort, pcSocketConfig.getBindAddress(), pcSocketConfig.getBindPort(), defaultJVM, domainConfig,
initialDomainConfig, hostConfig, initialHostConfig, initialRunningMode, backupDomainFiles, cachedDc,
- productConfig, securityManagerEnabled, startTime, processType, hostConfigInteractionPolicy, domainConfigInteractionPolicy));
+ productConfig, securityManagerEnabled, elapsedTime, processType, hostConfigInteractionPolicy, domainConfigInteractionPolicy));
}
private static boolean isJavaSecurityManagerConfigured(final Map props) {
diff --git a/server/src/main/java/org/jboss/as/server/ApplicationServerService.java b/server/src/main/java/org/jboss/as/server/ApplicationServerService.java
index 663897bf8d6..70749133031 100644
--- a/server/src/main/java/org/jboss/as/server/ApplicationServerService.java
+++ b/server/src/main/java/org/jboss/as/server/ApplicationServerService.java
@@ -58,26 +58,29 @@ final class ApplicationServerService implements Service extraServices, final Bootstrap.Configuration configuration,
- final ControlledProcessState processState, final SuspendController suspendController) {
+ final ControlledProcessState processState, final SuspendController suspendController,
+ final ElapsedTime elapsedTime) {
this.extraServices = extraServices;
this.configuration = configuration;
runningModeControl = configuration.getRunningModeControl();
- startTime = configuration.getStartTime();
standalone = configuration.getServerEnvironment().isStandalone();
selfContained = configuration.getServerEnvironment().isSelfContained();
this.processState = processState;
this.suspendController = suspendController;
+ this.elapsedTime = elapsedTime;
}
@Override
public synchronized void start(final StartContext context) throws StartException {
- //Moved to AbstractControllerService.start()
- //processState.setStarting();
+ // If this is a reload, track start time independently of the overall process elapsed time
+ ElapsedTime startupTime = everStopped ? elapsedTime.checkpoint() : elapsedTime;
+
final Bootstrap.Configuration configuration = this.configuration;
final ServerEnvironment serverEnvironment = configuration.getServerEnvironment();
final ProductConfig config = serverEnvironment.getProductConfig();
@@ -128,15 +131,9 @@ public synchronized void start(final StartContext context) throws StartException
final ServiceContainer container = myController.getServiceContainer();
futureContainer = new FutureServiceContainer();
- long startTime = this.startTime;
- if (startTime == -1) {
- startTime = System.currentTimeMillis();
- } else {
- this.startTime = -1;
- }
CurrentServiceContainer.setServiceContainer(context.getController().getServiceContainer());
- final BootstrapListener bootstrapListener = new BootstrapListener(container, startTime, serviceTarget, futureContainer, prettyVersion, serverEnvironment.getServerTempDir());
+ final BootstrapListener bootstrapListener = new BootstrapListener(container, startupTime, serviceTarget, futureContainer, prettyVersion, serverEnvironment.getServerTempDir());
bootstrapListener.getStabilityMonitor().addController(myController);
// Install either a local or remote content repository
if(standalone) {
@@ -207,6 +204,7 @@ public synchronized void stop(final StopContext context) {
String prettyVersion = configuration.getServerEnvironment().getProductConfig().getPrettyVersionString();
ServerLogger.AS_ROOT_LOGGER.serverStopped(prettyVersion, (int) (context.getElapsedTime() / 1000000L));
BootstrapListener.deleteStartupMarker(configuration.getServerEnvironment().getServerTempDir());
+ everStopped = true;
}
@Override
diff --git a/server/src/main/java/org/jboss/as/server/Bootstrap.java b/server/src/main/java/org/jboss/as/server/Bootstrap.java
index e43d918bcbe..f7b3a0d9501 100644
--- a/server/src/main/java/org/jboss/as/server/Bootstrap.java
+++ b/server/src/main/java/org/jboss/as/server/Bootstrap.java
@@ -81,7 +81,6 @@ final class Configuration {
private ModuleLoader moduleLoader = Module.getBootModuleLoader();
private ConfigurationPersisterFactory configurationPersisterFactory;
- private long startTime;
public Configuration(final ServerEnvironment serverEnvironment) {
@@ -99,7 +98,6 @@ public Configuration(final ServerEnvironment serverEnvironment) {
.withSecurityIdentitySupplier(this.securityIdentitySupplier)
.build();
this.capabilityRegistry = new CapabilityRegistry(true);
- this.startTime = serverEnvironment.getStartTime();
}
/**
@@ -233,9 +231,12 @@ public synchronized void setConfigurationPersisterFactory(final ConfigurationPer
* Get the server start time to report in the logs.
*
* @return the server start time
+ *
+ * @deprecated Use {@link #getServerEnvironment()}.{@link ServerEnvironment#getStartTime() getStartTime()}
*/
+ @Deprecated(forRemoval = true)
public long getStartTime() {
- return startTime;
+ return serverEnvironment.getStartTime();
}
}
diff --git a/server/src/main/java/org/jboss/as/server/BootstrapImpl.java b/server/src/main/java/org/jboss/as/server/BootstrapImpl.java
index c3147ce3d73..333c6f27c5e 100644
--- a/server/src/main/java/org/jboss/as/server/BootstrapImpl.java
+++ b/server/src/main/java/org/jboss/as/server/BootstrapImpl.java
@@ -106,7 +106,8 @@ private AsyncFuture internalBootstrap(final Configuration conf
processStateNotifier, suspendController,
configuration.getRunningModeControl(),
configuration.getServerEnvironment().getLaunchType() != ServerEnvironment.LaunchType.APPCLIENT);
- final Service> applicationServerService = new ApplicationServerService(extraServices, configuration, processState, suspendController);
+ final Service> applicationServerService = new ApplicationServerService(extraServices, configuration, processState,
+ suspendController, configuration.getServerEnvironment().getElapsedTime());
tracker.addService(Services.JBOSS_AS, applicationServerService)
.install();
final ServiceController> rootService = container.getRequiredService(Services.JBOSS_AS);
diff --git a/server/src/main/java/org/jboss/as/server/BootstrapListener.java b/server/src/main/java/org/jboss/as/server/BootstrapListener.java
index f19248ee238..68acae36ec3 100644
--- a/server/src/main/java/org/jboss/as/server/BootstrapListener.java
+++ b/server/src/main/java/org/jboss/as/server/BootstrapListener.java
@@ -32,16 +32,16 @@ public final class BootstrapListener {
private final StabilityMonitor monitor = new StabilityMonitor();
private final ServiceContainer serviceContainer;
private final ServiceTarget serviceTarget;
- private final long startTime;
+ private final ElapsedTime elapsedTime;
private final String prettyVersion;
private final FutureServiceContainer futureContainer;
private final File tempDir;
private String startedCleanMessage;
private String startedWitErrorsMessage;
- public BootstrapListener(final ServiceContainer serviceContainer, final long startTime, final ServiceTarget serviceTarget, final FutureServiceContainer futureContainer, final String prettyVersion, final File tempDir) {
+ public BootstrapListener(final ServiceContainer serviceContainer, final ElapsedTime elapsedTime, final ServiceTarget serviceTarget, final FutureServiceContainer futureContainer, final String prettyVersion, final File tempDir) {
this.serviceContainer = serviceContainer;
- this.startTime = startTime;
+ this.elapsedTime = elapsedTime;
this.serviceTarget = serviceTarget;
this.prettyVersion = prettyVersion;
this.futureContainer = futureContainer;
@@ -66,7 +66,7 @@ public void generateBootStatistics(String... messages) {
Thread.currentThread().interrupt();
} finally {
serviceTarget.removeMonitor(monitor);
- final long bootstrapTime = System.currentTimeMillis() - startTime;
+ final long bootstrapTime = elapsedTime.getElapsedTime();
done(bootstrapTime, statistics, messages);
monitor.clear();
}
@@ -108,10 +108,10 @@ private void done(final long bootstrapTime, final StabilityStatistics statistics
}
if (failed == 0 && problem == 0) {
startedCleanMessage = ServerLogger.AS_ROOT_LOGGER.startedCleanMessage(prettyVersion, bootstrapTime, started, active + passive + onDemand + never + lazy, onDemand + passive + lazy, appendMessage);
- createStartupMarker("success", startTime);
+ createStartupMarker("success", elapsedTime.getStartTime());
} else {
startedWitErrorsMessage = ServerLogger.AS_ROOT_LOGGER.startedWitErrorsMessage(prettyVersion, bootstrapTime, started, active + passive + onDemand + never + lazy, failed + problem, onDemand + passive + lazy, appendMessage);
- createStartupMarker("error", startTime);
+ createStartupMarker("error", elapsedTime.getStartTime());
}
}
diff --git a/server/src/main/java/org/jboss/as/server/ElapsedTime.java b/server/src/main/java/org/jboss/as/server/ElapsedTime.java
new file mode 100644
index 00000000000..59f474a21d9
--- /dev/null
+++ b/server/src/main/java/org/jboss/as/server/ElapsedTime.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright The WildFly Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.jboss.as.server;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * Tracks elapsed time since either JVM start or a moment of initialization. The start point
+ * for the calculation can be 'reset', allowing the calculation provided by an instance to
+ * account for a conceptual 'restart'.
+ */
+public final class ElapsedTime {
+
+ /**
+ * Creates a tracker that tracks elapsed time since JVM start.
+ * @return the tracker. Will not return {@code null}.
+ */
+ public static ElapsedTime startingFromJvmStart() {
+ return new ElapsedTime(null);
+ }
+
+ /**
+ * Creates a tracker that tracks elapsed time since the invocation of this method.
+ * @return the tracker. Will not return {@code null}.
+ */
+ public static ElapsedTime startingFromNow() {
+ return new ElapsedTime(System.currentTimeMillis());
+ }
+
+ private volatile Long startTime;
+
+ // Guarded by this
+ private final Map checkpoints = new WeakHashMap<>();
+
+ private ElapsedTime(Long startTime) {
+ this.startTime = startTime;
+ }
+
+ /**
+ * Gets the tracker's start point.
+ *
+ * @return the start point for this tracker, in milliseconds since the epoch.
+ */
+ public long getStartTime() {
+ return startTime != null ? startTime : ManagementFactory.getRuntimeMXBean().getStartTime();
+ }
+
+ /**
+ * Get the elapsed time in milliseconds since this tracker's start point.
+ *
+ * @return the elapsed time
+ */
+ public long getElapsedTime() {
+ return startTime == null ? ManagementFactory.getRuntimeMXBean().getUptime() : System.currentTimeMillis() - startTime;
+ }
+
+ /**
+ * Reset this tracker to begin tracking from the {@link RuntimeMXBean#getStartTime() JVM start time}.
+ * Any ElapsedTime objects that were returned from this object's {@link #checkpoint()} method will also be reset.
+ * Meant for cases where the 'origin' moment may have changed and this tracker should be updated accordingly --
+ * for example, in a 'restored' JVM that supports some form of checkpoint and restore behavior.
+ */
+ public synchronized void reset() {
+ startTime = null;
+ for (ElapsedTime checkpoint : checkpoints.keySet()) {
+ checkpoint.reset();
+ }
+ }
+
+ /**
+ * Create an ElapsedTime that tracks elapsed time from the current time, but
+ * whose starting point will automatically be {@link #reset() reset} if this object is reset.
+ */
+ public synchronized ElapsedTime checkpoint() {
+ ElapsedTime checkpoint = ElapsedTime.startingFromNow();
+ checkpoints.put(checkpoint, null);
+ return checkpoint;
+ }
+
+
+}
diff --git a/server/src/main/java/org/jboss/as/server/Main.java b/server/src/main/java/org/jboss/as/server/Main.java
index a7a5775c7e7..bfcc8120b23 100644
--- a/server/src/main/java/org/jboss/as/server/Main.java
+++ b/server/src/main/java/org/jboss/as/server/Main.java
@@ -79,7 +79,7 @@ public static void main(String[] args) {
Module.registerURLStreamHandlerFactoryModule(Module.getBootModuleLoader().loadModule("org.jboss.vfs"));
ServerEnvironmentWrapper serverEnvironmentWrapper = determineEnvironment(args, WildFlySecurityManager.getSystemPropertiesPrivileged(),
WildFlySecurityManager.getSystemEnvironmentPrivileged(), ServerEnvironment.LaunchType.STANDALONE,
- Module.getStartTime());
+ ElapsedTime.startingFromJvmStart());
if (serverEnvironmentWrapper.getServerEnvironment() == null) {
if (serverEnvironmentWrapper.getServerEnvironmentStatus() == ServerEnvironmentWrapper.ServerEnvironmentStatus.ERROR) {
abort(null);
@@ -113,11 +113,11 @@ private static void abort(Throwable t) {
* @param systemProperties system properties
* @param systemEnvironment environment variables
* @param launchType how the process was launched
- * @param startTime time in ms since the epoch when the process was considered to be started
+ * @param elapsedTime tracker for elapsed time since the process was considered to be started
* @return the ServerEnvironment object
*/
public static ServerEnvironmentWrapper determineEnvironment(String[] args, Properties systemProperties, Map systemEnvironment,
- ServerEnvironment.LaunchType launchType, long startTime) {
+ ServerEnvironment.LaunchType launchType, ElapsedTime elapsedTime) {
final int argsLength = args.length;
String serverConfig = null;
String gitRepository = null;
@@ -412,7 +412,7 @@ public static ServerEnvironmentWrapper determineEnvironment(String[] args, Prope
// Re-create using updated properties
productConfig = ProductConfig.fromFilesystemSlot(Module.getBootModuleLoader(), WildFlySecurityManager.getPropertyPrivileged(ServerEnvironment.HOME_DIR, null), systemProperties);
return new ServerEnvironmentWrapper(new ServerEnvironment(hostControllerName, systemProperties, systemEnvironment,
- serverConfig, configInteractionPolicy, launchType, runningMode, productConfig, startTime, startSuspended,
+ serverConfig, configInteractionPolicy, launchType, runningMode, productConfig, elapsedTime, startSuspended,
startGracefully, gitRepository, gitBranch, gitAuthConfiguration, supplementalConfiguration));
}
diff --git a/server/src/main/java/org/jboss/as/server/ServerEnvironment.java b/server/src/main/java/org/jboss/as/server/ServerEnvironment.java
index 35646ff3eea..627a1d89dc4 100644
--- a/server/src/main/java/org/jboss/as/server/ServerEnvironment.java
+++ b/server/src/main/java/org/jboss/as/server/ServerEnvironment.java
@@ -299,22 +299,35 @@ public ProcessType getProcessType() {
private final ProductConfig productConfig;
private final RunningModeControl runningModeControl;
private final UUID serverUUID;
- private final long startTime;
+ private final ElapsedTime elapsedTime;
private final boolean startSuspended;
private final boolean startGracefully;
private final GitRepository repository;
private volatile Stability stability;
+ /** Only for test cases */
public ServerEnvironment(final String hostControllerName, final Properties props, final Map env, final String serverConfig,
final ConfigurationFile.InteractionPolicy configInteractionPolicy, final LaunchType launchType,
final RunningMode initialRunningMode, ProductConfig productConfig, boolean startSuspended) {
this(hostControllerName, props, env, serverConfig, configInteractionPolicy, launchType, initialRunningMode, productConfig,
- System.currentTimeMillis(), startSuspended, false, null, null, null, null);
+ ElapsedTime.startingFromNow(), startSuspended, false, null, null, null, null);
+ }
+
+ /** @deprecated use the variant that takes an {@link ElapsedTime elapsedTime} parameter instead of {@code long startTime}*/
+ @Deprecated(forRemoval = true)
+ public ServerEnvironment(final String hostControllerName, final Properties props, final Map env, final String serverConfig,
+ final ConfigurationFile.InteractionPolicy configurationInteractionPolicy, final LaunchType launchType,
+ final RunningMode initialRunningMode, ProductConfig productConfig, long startTime, boolean startSuspended,
+ final boolean startGracefully, final String gitRepository, final String gitBranch, final String gitAuthConfiguration,
+ final String supplementalConfiguration) {
+ this(hostControllerName, props, env, serverConfig, configurationInteractionPolicy, launchType, initialRunningMode,
+ productConfig, ElapsedTime.startingFromJvmStart(), startSuspended, startGracefully,
+ gitRepository, gitBranch, gitAuthConfiguration, supplementalConfiguration);
}
public ServerEnvironment(final String hostControllerName, final Properties props, final Map env, final String serverConfig,
final ConfigurationFile.InteractionPolicy configurationInteractionPolicy, final LaunchType launchType,
- final RunningMode initialRunningMode, ProductConfig productConfig, long startTime, boolean startSuspended,
+ final RunningMode initialRunningMode, ProductConfig productConfig, ElapsedTime elapsedTime, boolean startSuspended,
final boolean startGracefully, final String gitRepository, final String gitBranch, final String gitAuthConfiguration,
final String supplementalConfiguration) {
assert props != null;
@@ -330,7 +343,7 @@ public ServerEnvironment(final String hostControllerName, final Properties props
this.initialRunningMode = initialRunningMode == null ? RunningMode.NORMAL : initialRunningMode;
this.runningModeControl = new RunningModeControl(this.initialRunningMode);
- this.startTime = startTime;
+ this.elapsedTime = elapsedTime;
this.hostControllerName = hostControllerName;
if (standalone && hostControllerName != null) {
@@ -1088,7 +1101,7 @@ public UUID getInstanceUuid() {
* @return the time, in ms since the epoch
*/
public long getStartTime() {
- return startTime;
+ return elapsedTime.getStartTime();
}
public boolean useGit() {
@@ -1288,4 +1301,13 @@ public static String translateFileAlias(String alias, Stability stability) {
}
return "standalone-" + alias + ".xml";
}
+
+ /**
+ * Gets this server's {@link ElapsedTime} tracker.
+ *
+ * @return the elapsed time tracker. Will not be {@code null}.
+ */
+ ElapsedTime getElapsedTime() {
+ return elapsedTime;
+ }
}
diff --git a/server/src/main/java/org/jboss/as/server/ServerStartTask.java b/server/src/main/java/org/jboss/as/server/ServerStartTask.java
index e0d443d25e1..5ebdbfd6ab1 100644
--- a/server/src/main/java/org/jboss/as/server/ServerStartTask.java
+++ b/server/src/main/java/org/jboss/as/server/ServerStartTask.java
@@ -114,7 +114,7 @@ public AsyncFuture run(final List runService
// Create server environment on the server, so that the system properties are getting initialized on the right side
final ServerEnvironment providedEnvironment = new ServerEnvironment(hostControllerName, properties,
WildFlySecurityManager.getSystemEnvironmentPrivileged(), null, null, ServerEnvironment.LaunchType.DOMAIN,
- RunningMode.NORMAL, productConfig, Module.getStartTime(), suspend, gracefulStartup, null, null, null, null);
+ RunningMode.NORMAL, productConfig, ElapsedTime.startingFromJvmStart(), suspend, gracefulStartup, null, null, null, null);
DomainServerCommunicationServices.updateOperationID(initialOperationID);
// TODO perhaps have ConfigurationPersisterFactory as a Service