[
https://issues.jboss.org/browse/WFLY-12815?page=com.atlassian.jira.plugin...
]
Matěj Novotný edited comment on WFLY-12815 at 11/27/19 10:00 AM:
-----------------------------------------------------------------
Quickly reading this issue (going to read it some more for sure), I'd like to comment
on your second point.
{quote}(2) Program in your WAR application a sessionDestroyed listener that will be
broken.
In our case whenever the session is timing out, we have some code that explodes in wildfly
and not in weblogic because it expected for the RequestScope context to be active, but
apparently in wildfly when Undertow to start killing of a session the request scope
context is not made active so that caused our session destroyed handling to break{quote}
CDI spec is not clear on the order in which these are destroyed, or more precisely on
whether you can rely on certain scope being active during destruction of another scope.
Weld (at least in WildFly) tries to destroy scopes with "shorter life span"
first meaning request scope gets destroyed before session scope which in turn goes before
application scope (if you are shutting down app). Hence the behavior you see; it's
actually inteded. I am not sure if weblogic added some manual scope activation, but to me
it seems logical the way I described it above so that req. context cannot
"outlive" session context.
Since you already played with this quite a lot, do you happen to have a reproducer project
to share?
I also find it weird that there are two session contexts active because the way
{{HttpSessionDestructionContext}} gets activated is visible
[
here|https://github.com/weld/core/blob/master/modules/web/src/main/java/o...].
It should only happen in case there is no session context already. Also take a glance at
the javadoc of this class which explains how and why its done.
The actual on/off toggling of http contexts is done via
[
WeldInitialListener|https://github.com/weld/core/blob/master/modules/web/...]
which delegates most logic to
[HttpContextLifecycle|https://github.com/weld/core/blob/master/modules/web/src/main/java/org/jboss/weld/module/web/servlet/HttpContextLifecycle.java].
Now, if I understood the problem, then the situation will only happen if you deliberately
try and "corrupt" all the threads by using inactive scopes on them and them you
try and start new session on one of those threads. That's pretty fishy code in the
first place, but we should still look into why this happens.
If you have the reproducer, then [this is where {{HttpSessionDestructionContext}} gets
destroyed|https://github.com/weld/core/blob/master/modules/web/src/main/j...].
The possible issue could be the ordering of {{WeldInitialListener}} and
{{WeldTerminalListener}} - basically you need {{WeldTerminalListener}} to be the last
registered and hence first invoked; this will get you the special context activated. Then,
after some other optional listeners, comes {{WeldInitialListener}} (registered first,
called last) that will attempt to terminate this special context.
At least that's how I understand it from a glance into the code, if you toss me a
reproducer, I'll try and go deeper.
Meanwhile, I'll try to dig up where WFLY registers those listeners.
EDIT: In WFLY, those listeners are register in
[{{WebIntegrationProcessor}}|https://github.com/wildfly/wildfly/blob/master/weld/subsystem/src/main/java/org/jboss/as/weld/deployment/processors/WebIntegrationProcessor.java]
and that seems to be done in correct way.
was (Author: manovotn):
Quickly reading this issue (going to read it some more for sure), I'd like to comment
on your second point.
{quote}(2) Program in your WAR application a sessionDestroyed listener that will be
broken.
In our case whenever the session is timing out, we have some code that explodes in wildfly
and not in weblogic because it expected for the RequestScope context to be active, but
apparently in wildfly when Undertow to start killing of a session the request scope
context is not made active so that caused our session destroyed handling to break{quote}
CDI spec is not clear on the order in which these are destroyed, or more precisely on
whether you can rely on certain scope being active during destruction of another scope.
Weld (at least in WildFly) tries to destroy scopes with "shorter life span"
first meaning request scope gets destroyed before session scope which in turn goes before
application scope (if you are shutting down app). Hence the behavior you see; it's
actually inteded. I am not sure if weblogic added some manual scope activation, but to me
it seems logical the way I described it above so that req. context cannot
"outlive" session context.
Since you already played with this quite a lot, do you happen to have a reproducer project
to share?
I also find it weird that there are two session contexts active because the way
{{HttpSessionDestructionContext}} gets activated is visible
[
here|https://github.com/weld/core/blob/master/modules/web/src/main/java/o...].
It should only happen in case there is no session context already. Also take a glance at
the javadoc of this class which explains how and why its done.
The actual on/off toggling of http contexts is done via
[
WeldInitialListener|https://github.com/weld/core/blob/master/modules/web/...]
which delegates most logic to
[HttpContextLifecycle|https://github.com/weld/core/blob/master/modules/web/src/main/java/org/jboss/weld/module/web/servlet/HttpContextLifecycle.java].
Now, if I understood the problem, then the situation will only happen if you deliberately
try and "corrupt" all the threads by using inactive scopes on them and them you
try and start new session on one of those threads. That's pretty fishy code in the
first place, but we should still look into why this happens.
If you have the reproducer, then [this is where {{HttpSessionDestructionContext}} gets
destroyed|https://github.com/weld/core/blob/master/modules/web/src/main/j...].
The possible issue could be the ordering of {{WeldInitialListener}} and
{{WeldTerminalListener}} - basically you need {{WeldTerminalListener}} to be the last
registered and hence first invoked; this will get you the special context activated. Then,
after some other optional listeners, comes {{WeldInitialListener}} (registered first,
called last) that will attempt to terminate this special context.
At least that's how I understand it from a glance into the code, if you toss me a
reproducer, I'll try and go deeper.
Meanwhile, I'll try to dig up where WFLY registers those listeners.
Wildfly 13 - Thread local state corrupted by deployed application
explosion during session timeout leading to WELD-001304 - More than one context active
for scope type javax.enterprise.context.SessionScoped
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key: WFLY-12815
URL:
https://issues.jboss.org/browse/WFLY-12815
Project: WildFly
Issue Type: Bug
Components: CDI / Weld
Affects Versions: 13.0.0.Final
Environment: Environment independent the issue, it is purely a logical problem
Reporter: NUNO GODINHO DE MATOS
Assignee: Matěj Novotný
Priority: Major
The full description of the problem can be seen in stack overflow.
Please consulder the issue:
https://stackoverflow.com/questions/58930939/wildflt-13-weld-001304-more-...
SUMMARY:
(1) Setup you wildfly to have a session timeout of 1 minute - so that you can esaily make
your http sessions timeout
(2) Program in your WAR application a sessionDestroyed listener that will be broken.
In our case whenever the session is timing out, we have some code that explodes in
wildfly and not in weblogic because it expected for the RequestScope context to be active,
but apparently in wildfly when Undertow to start killing of a session the request scope
context is not made active so that caused our session destroyed handling to break
(3) Do this sufficient amount of times to corrupted as may threads in the thread pool as
possible
(4) Now try to interact with your application making use of some session scoped beans .
If you travel to ay sort of view that makes use of a session scoped bean that thread will
be broken with the exception that multiple session scope context implementation are
active.
But this exception will only come out and aply if the thread handling the HTTP request is
one of the threads that in the past were used by undertow to handle the session timeout.
The only threads that have been corrupted forever are those that had a broken sessin
timeout
Explanation for the issue:
- When the session timeout is being orchestrated by underdow, wildfly is activating a
special HttpSessionDescrutionContext and making it active.
This ACTIVE TRUE/FALSE flag is a ThreadLocal variable.
So the activation of the scope context is marked on the thread itself.
- When the thread blows up the thread context will remain for as long at the thread
lives
- in a future request the flag had that thread local variable active already.
So when the BeanManagaerImpl is hunting to the one and only active http session context
it finds the traditional happy path http session context active plust the
DestructionSession context that was activated in a previous call.
All of the illustrative stack traces that facilitate the comprehention of the issue are
shown in the stack overflow thread.
I am of the oppinion that errors like this can happen in the deployed applications.
It would not hurt if wildfly would somehow be able to ensure that the thread that hand an
explosion in a previous request is not corrupted when it is used to handle new requests.
Many thanks for having a look.
--
This message was sent by Atlassian Jira
(v7.13.8#713008)