Skip to content

Commit

Permalink
WELD-1802 An exception during context deactivation/dissociation should
Browse files Browse the repository at this point in the history
not abort further procesing
  • Loading branch information
mkouba authored and jharting committed Dec 4, 2014
1 parent 6808b11 commit 8e41320
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 37 deletions.
11 changes: 6 additions & 5 deletions impl/src/main/java/org/jboss/weld/logging/ServletLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@

import static org.jboss.weld.logging.WeldLogger.WELD_PROJECT_CODE;

import javax.enterprise.context.spi.Context;
import javax.servlet.http.HttpServletRequest;

import org.jboss.logging.Logger;
import org.jboss.logging.Logger.Level;
import org.jboss.logging.annotations.Cause;
Expand Down Expand Up @@ -60,8 +57,8 @@ public interface ServletLogger extends WeldLogger {
void webXmlMappingPatternIgnored(String pattern);

@LogMessage(level = Level.WARN)
@Message(id = 712, value = "Unable to dissociate context {0} when destroying request {1}", format = Format.MESSAGE_FORMAT)
void unableToDissociateContext(Context context, HttpServletRequest request);
@Message(id = 712, value = "Unable to dissociate context {0} from the storage {1}", format = Format.MESSAGE_FORMAT)
void unableToDissociateContext(Object context, Object storage);

@Message(id = 713, value = "Unable to inject ServletContext. None is associated with {0}, {1}", format = Format.MESSAGE_FORMAT)
IllegalStateException cannotInjectServletContext(ClassLoader classLoader, ServletContextService service);
Expand All @@ -78,4 +75,8 @@ public interface ServletLogger extends WeldLogger {
@Message(id = 716, value = "Running in Servlet 2.x environment. Asynchronous request support is disabled.")
void servlet2Environment();

@LogMessage(level = Level.WARN)
@Message(id = 717, value = "Unable to deactivate context {0} when destroying request {1}", format = Format.MESSAGE_FORMAT)
void unableToDeactivateContext(Object context, Object request);

}
Original file line number Diff line number Diff line change
Expand Up @@ -138,30 +138,35 @@ private boolean isContextActivatedInRequest(HttpServletRequest request) {
}

protected void deactivateConversationContext(HttpServletRequest request) {
ConversationContext conversationContext = httpConversationContext();
if (conversationContext.isActive()) {
// Only deactivate the context if one is already active, otherwise we get Exceptions
if (conversationContext instanceof LazyHttpConversationContextImpl) {
LazyHttpConversationContextImpl lazyConversationContext = (LazyHttpConversationContextImpl) conversationContext;
if (!lazyConversationContext.isInitialized()) {
// if this lazy conversation has not been touched yet, just deactivate it
lazyConversationContext.deactivate();
return;
try {
ConversationContext conversationContext = httpConversationContext();
if (conversationContext.isActive()) {
// Only deactivate the context if one is already active, otherwise we get Exceptions
if (conversationContext instanceof LazyHttpConversationContextImpl) {
LazyHttpConversationContextImpl lazyConversationContext = (LazyHttpConversationContextImpl) conversationContext;
if (!lazyConversationContext.isInitialized()) {
// if this lazy conversation has not been touched yet, just deactivate it
lazyConversationContext.deactivate();
return;
}
}
}
boolean isTransient = conversationContext.getCurrentConversation().isTransient();
if (ConversationLogger.LOG.isTraceEnabled()) {
boolean isTransient = conversationContext.getCurrentConversation().isTransient();
if (ConversationLogger.LOG.isTraceEnabled()) {
if (isTransient) {
ConversationLogger.LOG.cleaningUpTransientConversation();
} else {
ConversationLogger.LOG.cleaningUpConversation(conversationContext.getCurrentConversation().getId());
}
}
conversationContext.invalidate();
conversationContext.deactivate();
if (isTransient) {
ConversationLogger.LOG.cleaningUpTransientConversation();
} else {
ConversationLogger.LOG.cleaningUpConversation(conversationContext.getCurrentConversation().getId());
conversationDestroyedEvent.fire(request);
}
}
conversationContext.invalidate();
conversationContext.deactivate();
if (isTransient) {
conversationDestroyedEvent.fire(request);
}
} catch (Exception e) {
ServletLogger.LOG.unableToDeactivateContext(httpConversationContext(), request);
ServletLogger.LOG.catchingDebug(e);
}
}

Expand Down
42 changes: 30 additions & 12 deletions impl/src/main/java/org/jboss/weld/servlet/HttpContextLifecycle.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

import org.jboss.weld.Container;
import org.jboss.weld.bootstrap.api.Service;
import org.jboss.weld.context.BoundContext;
import org.jboss.weld.context.ManagedContext;
import org.jboss.weld.context.cache.RequestScopedCache;
import org.jboss.weld.context.http.HttpRequestContext;
import org.jboss.weld.context.http.HttpRequestContextImpl;
Expand Down Expand Up @@ -279,24 +281,21 @@ public void requestDestroyed(HttpServletRequest request) {
if (!servletApi.isAsyncSupported() || !servletApi.isAsyncStarted(request)) {
getRequestContext().invalidate();
}
getRequestContext().deactivate();

safelyDeactivate(getRequestContext(), request);
// fire @Destroyed(RequestScoped.class)
requestDestroyedEvent.fire(request);
getSessionContext().deactivate();

safelyDeactivate(getSessionContext(), request);
// fire @Destroyed(SessionScoped.class)
if (!getSessionContext().isValid()) {
sessionDestroyedEvent.fire((HttpSession) request.getAttribute(HTTP_SESSION));
}
} finally {
getRequestContext().dissociate(request);

safelyDissociate(getRequestContext(), request);
// WFLY-1533 Underlying HTTP session may be invalid
try {
getSessionContext().dissociate(request);
} catch (Exception e) {
ServletLogger.LOG.unableToDissociateContext(getSessionContext(), request);
ServletLogger.LOG.catchingDebug(e);
}
safelyDissociate(getSessionContext(), request);

// Catch block is inside the activator method so that we're able to log the context
conversationContextActivator.disassociateConversationContext(request);

Expand All @@ -312,6 +311,10 @@ public void setConversationActivationEnabled(boolean conversationActivationEnabl
this.conversationActivationEnabled = conversationActivationEnabled;
}

@Override
public void cleanup() {
}

/**
* Some Servlet containers fire HttpServletListeners for include requests (inner requests caused by calling the include method of RequestDispatcher). This
* causes problems with context shut down as context manipulation is not reentrant. This method detects if this request is an included request or not.
Expand All @@ -338,7 +341,22 @@ private boolean isRequestDestroyed(HttpServletRequest request) {
return request.getAttribute(REQUEST_DESTROYED) != null;
}

@Override
public void cleanup() {
private <T> void safelyDissociate(BoundContext<T> context, T storage) {
try {
context.dissociate(storage);
} catch(Exception e) {
ServletLogger.LOG.unableToDissociateContext(context, storage);
ServletLogger.LOG.catchingDebug(e);
}
}

private void safelyDeactivate(ManagedContext context, HttpServletRequest request) {
try {
context.deactivate();
} catch(Exception e) {
ServletLogger.LOG.unableToDeactivateContext(context, request);
ServletLogger.LOG.catchingDebug(e);
}
}

}

0 comments on commit 8e41320

Please sign in to comment.