Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[master] Fix for AS7-5969 #3455

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -39,6 +39,7 @@
import org.jboss.as.security.plugins.SecurityDomainContext;
import org.jboss.as.security.service.JaccService;
import org.jboss.as.security.service.SecurityDomainService;
import org.jboss.as.server.Services;
import org.jboss.as.server.deployment.Attachments;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnit;
Expand Down Expand Up @@ -285,6 +286,11 @@ private void processDeployment(final String hostName, final WarMetaData warMetaD
.addDependencies(deploymentUnit.getAttachmentList(Attachments.WEB_DEPENDENCIES))
.addDependency(JndiNamingDependencyProcessor.serviceName(deploymentUnit.getServiceName()));

// inject the server executor which can be used by the WebDeploymentService for blocking tasks in start/stop
// of that service
Services.addServerExecutorDependency(webappBuilder, webappService.getServerExecutorInjector(), false);


// add any dependencies required by the setup action
for (final SetupAction action : setupActions) {
webappBuilder.addDependencies(action.dependencies());
Expand Down
Expand Up @@ -27,6 +27,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

Expand All @@ -38,6 +39,7 @@
import org.jboss.as.server.deployment.AttachmentKey;
import org.jboss.as.server.deployment.SetupAction;
import org.jboss.as.web.ThreadSetupBindingListener;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.AbstractServiceListener;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceController;
Expand All @@ -62,6 +64,8 @@ public class WebDeploymentService implements Service<StandardContext> {
private final WebInjectionContainer injectionContainer;
private final List<SetupAction> setupActions;
final List<ServletContextAttribute> attributes;
// used for blocking tasks in this Service's start/stop
private final InjectedValue<ExecutorService> serverExecutor = new InjectedValue<ExecutorService>();

public WebDeploymentService(final StandardContext context, final WebInjectionContainer injectionContainer, final List<SetupAction> setupActions,
final List<ServletContextAttribute> attributes) {
Expand All @@ -76,7 +80,57 @@ InjectedValue<Realm> getRealm() {
}

@Override
public synchronized void start(StartContext startContext) throws StartException {
public synchronized void start(final StartContext startContext) throws StartException {
// https://issues.jboss.org/browse/AS7-5969 WebDeploymentService start can trigger the web app context initialization
// which involves blocking tasks like servlet context initialization, startup servlet
// initialization lifecycles and such. Hence this needs to be done asynchronously
// to prevent the MSC threads from blocking
startContext.asynchronous();
serverExecutor.getValue().submit(new Runnable() {
@Override
public void run() {
try {
doStart();
startContext.complete();
} catch (Throwable e) {
startContext.failed(new StartException(e));
}
}
});
}

@Override
public synchronized void stop(final StopContext stopContext) {
// https://issues.jboss.org/browse/AS7-5969 WebDeploymentService stop can trigger the web app context destruction
// which involves blocking tasks like servlet context destruction, startup servlet
// destruction lifecycles and such. Hence this needs to be done asynchronously
// to prevent the MSC threads from blocking
stopContext.asynchronous();
serverExecutor.getValue().submit(new Runnable() {
@Override
public void run() {
try {
doStop();
} finally {
stopContext.complete();
}
}
});
}

@Override
public synchronized StandardContext getValue() throws IllegalStateException {
if (context == null) {
throw new IllegalStateException();
}
return context;
}

Injector<ExecutorService> getServerExecutorInjector() {
return this.serverExecutor;
}

private void doStart() throws StartException {
if (attributes != null) {
final ServletContext context = this.context.getServletContext();
for (ServletContextAttribute attribute : attributes) {
Expand Down Expand Up @@ -111,8 +165,7 @@ public synchronized void start(StartContext startContext) throws StartException
}
}

@Override
public synchronized void stop(StopContext stopContext) {
private void doStop() {
WEB_LOGGER.unregisterWebapp(context.getName());
try {
context.stop();
Expand All @@ -124,14 +177,7 @@ public synchronized void stop(StopContext stopContext) {
} catch (Exception e) {
WEB_LOGGER.destroyContextFailed(e);
}
}

@Override
public synchronized StandardContext getValue() throws IllegalStateException {
if (context == null) {
throw new IllegalStateException();
}
return context;
}

/**
Expand Down