Beehive
  1. Beehive
  2. BEEHIVE-1028

Controls in pageflows do not appear to be receiving lifecycle events in the proper order

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.0, 1.0.1
    • Fix Version/s: 1.0.1
    • Component/s: NetUI
    • Labels:
      None

      Description

      So I have a small webapp which basically consists of a pageflow and a jdbc control. The single jsp in the web app invokes an action in the page flow as:

      <tr><td><img src="doRenderChart.do?versionName=9.2Beta&projectName=Workshop&componentName=W-IDE&JFWidth=500&JFHeight=300" border="0"/></td></tr>

      It does this 10 or 11 times to build a table which contains images generated by the action using the jdbc control to retrieve data from a database. Typically (although not always) at least one of the images will not be generated due to an SQL Error throw by the jdbc control. The error is that the SQLConnection has been closed.

      Here is a portion of the tomcat log, I've added some debugging statements in the ControlContainerContext class to help me see what was going on, the doRenderChart() is the page flow action being called by the jsp. It appears the control's begin and end events are not fired in the right order, causing (in some instances) the control to be unititialzed before a call has been completed.

      log4j:WARN Please initialize the log4j system properly.
      BEGIN_CONTEXT: THREAD ID = 34
      END_CONTEXT: THREAD ID = 34
      BEGIN_CONTEXT: THREAD ID = 34

            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=null
              BEGIN_CONTEXT: THREAD ID = 35
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-IDE
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Docs
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-IDECore
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-External
              BEGIN_CONTEXT: THREAD ID = 35
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 35
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Project
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Javelin
              BEGIN_CONTEXT: THREAD ID = 35
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-RuntimeControls
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-RuntimeNetUI
              BEGIN_CONTEXT: THREAD ID = 35
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 35
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Upgrade
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              BEGIN_CONTEXT: THREAD ID = 33
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=null
            • Leave: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              BEGIN_CONTEXT: THREAD ID = 33
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Docs
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-IDE
              BEGIN_CONTEXT: THREAD ID = 33
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              BEGIN_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 33
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-External
            • Leave: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              BEGIN_CONTEXT: THREAD ID = 33
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-IDECore
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Project
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 33
              calling version=9.2Beta project=Workshop component=W-Javelin
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              BEGIN_CONTEXT: THREAD ID = 33
              BEGIN_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-RuntimeControls
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              BEGIN_CONTEXT: THREAD ID = 33
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-RuntimeNetUI
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Upgrade
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              END_CONTEXT: THREAD ID = 33
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              Listening for transport dt_shmem at address: jdbconn
              BEGIN_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=null
            • Leave: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Docs
            • Leave: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-External
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-IDE
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              BEGIN_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-IDECore
            • Leave: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
            • Enter: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 34
              calling version=9.2Beta project=Workshop component=W-Project
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Javelin
              BEGIN_CONTEXT: THREAD ID = 35
            • Leave: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 35
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-RuntimeControls
              BEGIN_CONTEXT: THREAD ID = 34
            • Leave: doRenderChart() ****
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-RuntimeNetUI
              BEGIN_CONTEXT: THREAD ID = 35
            • Leave: doRenderChart() ****
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 35
              BEGIN_CONTEXT: THREAD ID = 35
            • Enter: doRenderChart() ****
              calling version=9.2Beta project=Workshop component=W-Upgrade
            • Leave: doRenderChart() ****
              BEGIN_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 35
              END_CONTEXT: THREAD ID = 34
              END_CONTEXT: THREAD ID = 34
      1. jira1028Simplified.zip
        10 kB
        Rich Feit
      2. beehive1028.zip
        3.16 MB
        Chad Schoettger

        Activity

        Chad Schoettger created issue -
        Chad Schoettger made changes -
        Field Original Value New Value
        Summary Controls in pageflows do not appear to be recieving lifecycle events in the proper order Controls in pageflows do not appear to be receiving lifecycle events in the proper order
        Hide
        Chad Schoettger added a comment -

        attached web app to reproduce this issue.

        Show
        Chad Schoettger added a comment - attached web app to reproduce this issue.
        Chad Schoettger made changes -
        Attachment beehive1028.zip [ 12321296 ]
        Hide
        Eddie O'Neil added a comment -

        Chad, from the repro application, what is both the expected and observed behavior here?

        Show
        Eddie O'Neil added a comment - Chad, from the repro application, what is both the expected and observed behavior here?
        Hide
        Eddie O'Neil added a comment -

        Adding 1.1 to the affects version.

        Show
        Eddie O'Neil added a comment - Adding 1.1 to the affects version.
        Eddie O'Neil made changes -
        Affects Version/s 1.1 [ 12310333 ]
        Hide
        Chad Schoettger added a comment -

        Appears to be a pageflow issue, assigning to Rich.

        Show
        Chad Schoettger added a comment - Appears to be a pageflow issue, assigning to Rich.
        Chad Schoettger made changes -
        Assignee Chad Schoettger [ chad_s ] Rich Feit [ rich ]
        Hide
        Rich Feit added a comment -

        Hey Chad, when I run /Controller.jpf, I get the following output:

              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****
              • Enter: doRenderChart() ****
              • Leave: doRenderChart() ****

        This seems OK – what should I be looking for?

        Show
        Rich Feit added a comment - Hey Chad, when I run /Controller.jpf, I get the following output: Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** Enter: doRenderChart() **** Leave: doRenderChart() **** This seems OK – what should I be looking for?
        Rich Feit made changes -
        Assignee Rich Feit [ rich ] Chad Schoettger [ chad_s ]
        Hide
        Rich Feit added a comment -

        OK, I've actually added this code in my control:

        @Context
        ResourceContext resourceContext;

        @EventHandler(field="resourceContext",
        eventSet=ResourceContext.ResourceEvents.class,
        eventName="onAcquire")
        public void onAcquire()

        { System.err.println("&&&&& onAcquire"); }

        @EventHandler(field="resourceContext",
        eventSet=ResourceContext.ResourceEvents.class,
        eventName="onRelease")
        public void onRelease()

        { System.err.println("&&&&& onRelease"); }

        So the question is, how should "&&&&& onAcquire" and "&&&&& onRelease" be interleaved in the rest of the output? You can kick this back to me with that info – thanks.

        Show
        Rich Feit added a comment - OK, I've actually added this code in my control: @Context ResourceContext resourceContext; @EventHandler(field="resourceContext", eventSet=ResourceContext.ResourceEvents.class, eventName="onAcquire") public void onAcquire() { System.err.println("&&&&& onAcquire"); } @EventHandler(field="resourceContext", eventSet=ResourceContext.ResourceEvents.class, eventName="onRelease") public void onRelease() { System.err.println("&&&&& onRelease"); } So the question is, how should "&&&&& onAcquire" and "&&&&& onRelease" be interleaved in the rest of the output? You can kick this back to me with that info – thanks.
        Hide
        Rich Feit added a comment -

        Chad, I'm attaching a Controls-only webapp that proves one of three things:

        1) This is fundamentally a problem with Controls.
        2) At least one piece of the problem is within Controls.
        3) The NetUI framework is using Controls incorrectly, since it uses Controls in the way that this repro app uses Controls.

        Hopefully you or someone else can tell me whether it's 1/2, or 3.

        Basically, the issue involves using the same instance of a Control from two separate threads. To reproduce the problem:

        • Deploy the attached app to Tomcat.
        • Hit http://localhost:8080/jira1028Simplified/one.jsp.
        • Make sure your Tomcat console is visible.
        • Click the "go" link in the browser (to eliminate variables, please use Firefox, not IE or Mozilla).
        • When you see "Click again!" on the console, click the "go" link again.

        You'll see the following output (the numbers are thread-IDs). Notice that there's only one call to each of onAcquire/onRelease (on the first thread), even though dummyControlMethod gets called from both threads.

        34 onAcquire
        34 begin dummyControlMethod
        34 end dummyControlMethod
        35 begin dummyControlMethod
        34 onRelease
        35 end dummyControlMethod

        Show
        Rich Feit added a comment - Chad, I'm attaching a Controls-only webapp that proves one of three things: 1) This is fundamentally a problem with Controls. 2) At least one piece of the problem is within Controls. 3) The NetUI framework is using Controls incorrectly, since it uses Controls in the way that this repro app uses Controls. Hopefully you or someone else can tell me whether it's 1/2, or 3. Basically, the issue involves using the same instance of a Control from two separate threads. To reproduce the problem: Deploy the attached app to Tomcat. Hit http://localhost:8080/jira1028Simplified/one.jsp . Make sure your Tomcat console is visible. Click the "go" link in the browser (to eliminate variables, please use Firefox, not IE or Mozilla). When you see "Click again!" on the console, click the "go" link again. You'll see the following output (the numbers are thread-IDs). Notice that there's only one call to each of onAcquire/onRelease (on the first thread), even though dummyControlMethod gets called from both threads. 34 onAcquire 34 begin dummyControlMethod 34 end dummyControlMethod 35 begin dummyControlMethod 34 onRelease 35 end dummyControlMethod
        Hide
        Rich Feit added a comment -

        The repro app. Note that you will have to change the value of beehive.home in build.properties for this to build.

        Show
        Rich Feit added a comment - The repro app. Note that you will have to change the value of beehive.home in build.properties for this to build.
        Rich Feit made changes -
        Attachment jira1028Simplified.zip [ 12321355 ]
        Hide
        Rich Feit added a comment -

        Note that the bad behavior exists even if I make dummyControlMethod synchronized:

        34 onAcquire
        34 begin dummyControlMethod
        34 end dummyControlMethod
        34 onRelease
        35 begin dummyControlMethod
        35 end dummyControlMethod

        Show
        Rich Feit added a comment - Note that the bad behavior exists even if I make dummyControlMethod synchronized: 34 onAcquire 34 begin dummyControlMethod 34 end dummyControlMethod 34 onRelease 35 begin dummyControlMethod 35 end dummyControlMethod
        Hide
        Chad Schoettger added a comment -

        After further investigation this appears to be a problem with the ControlFilter and PageFlow.

        Basically what is happening is:

        *) The bean context is being stored in the session.
        *) When the context's 'beginContext()' method is called, it is passed the current request and response as parameters - which ties the bean context to a particular servlet request/response.
        *) If another thread with the same session makes a request, the same bean context is used but if the bean context associated with the first thread has not completed its servlet request/response information is overwritten by the second thread's request.

        I belive that the core isssue here is that it is improper to store a bean context in a session, since the bean context works on a per-request scope, but at any given time there may be multiple requests made on a single session.\

        My recommendation would be to remove the ability to store the bean context in the session, and just create a new bean context for each request recieved. This is a fairly straightforward modification to the ControlFilter but may need some additional investigation on the page flow side of things.

        Show
        Chad Schoettger added a comment - After further investigation this appears to be a problem with the ControlFilter and PageFlow. Basically what is happening is: *) The bean context is being stored in the session. *) When the context's 'beginContext()' method is called, it is passed the current request and response as parameters - which ties the bean context to a particular servlet request/response. *) If another thread with the same session makes a request, the same bean context is used but if the bean context associated with the first thread has not completed its servlet request/response information is overwritten by the second thread's request. I belive that the core isssue here is that it is improper to store a bean context in a session, since the bean context works on a per-request scope, but at any given time there may be multiple requests made on a single session.\ My recommendation would be to remove the ability to store the bean context in the session, and just create a new bean context for each request recieved. This is a fairly straightforward modification to the ControlFilter but may need some additional investigation on the page flow side of things.
        Hide
        Rich Feit added a comment -

        The main question would be: is it OK to maintain a reference to a control that lives longer than a context that it's resided in? Since Control member variables in page flows end up stored in the session, each one would get put into a different context for each request. If it's OK to have a longer-lived Control, then it sounds like this will work.

        If you take that approach (making it invalid to store the context in the session), then I assume you'd deprecate the Servlet init param that enables this behavior in ServletBeanContext?

        Show
        Rich Feit added a comment - The main question would be: is it OK to maintain a reference to a control that lives longer than a context that it's resided in? Since Control member variables in page flows end up stored in the session, each one would get put into a different context for each request. If it's OK to have a longer-lived Control, then it sounds like this will work. If you take that approach (making it invalid to store the context in the session), then I assume you'd deprecate the Servlet init param that enables this behavior in ServletBeanContext?
        Hide
        Chad Schoettger added a comment -

        Commited fix to ControlFilter for this bug. Fix consists of removing the 'useSession' initParam for the ControlFiler and creating a new ControlBeanContext for each request the ControlFilter recieves.

        This fix in no way resolves this issue for pageflows.

        Show
        Chad Schoettger added a comment - Commited fix to ControlFilter for this bug. Fix consists of removing the 'useSession' initParam for the ControlFiler and creating a new ControlBeanContext for each request the ControlFilter recieves. This fix in no way resolves this issue for pageflows.
        Daryl Olander made changes -
        Fix Version/s 1.0.1 [ 12310717 ]
        Hide
        Daryl Olander added a comment -

        I reworked how the ControlContainerContext inside of the page flow runtime works to fix a number of problems that could have caused problems. The following is a brief description of this fix.

        There are now two sets of ControlContainerContext (CCC) objects. For page flows and faces backing files, the CCC is scoped into the lifetime of the page flow. For all shared flows (and global app) there is a single CCC.

        In order to handle the property beginContext/endContext, we now do the beginContext/endContext in the three single threaded execution sections where page flow code runs. These are the around onCreate, beforeAction/Action/afterAction, and then JSP rendering. In each of these sections will will run beginContext and endContext. In addition, there is a single lock object that is obtained to gain access to the shared flow CCC.

        The result is that we now provide single threaded access to a shared flow (assuming that there is a control in some shared flow). In addition, we will serialize execution of thread within the session. We also run the proper resource event lifecycle on the controls.

        Show
        Daryl Olander added a comment - I reworked how the ControlContainerContext inside of the page flow runtime works to fix a number of problems that could have caused problems. The following is a brief description of this fix. There are now two sets of ControlContainerContext (CCC) objects. For page flows and faces backing files, the CCC is scoped into the lifetime of the page flow. For all shared flows (and global app) there is a single CCC. In order to handle the property beginContext/endContext, we now do the beginContext/endContext in the three single threaded execution sections where page flow code runs. These are the around onCreate, beforeAction/Action/afterAction, and then JSP rendering. In each of these sections will will run beginContext and endContext. In addition, there is a single lock object that is obtained to gain access to the shared flow CCC. The result is that we now provide single threaded access to a shared flow (assuming that there is a control in some shared flow). In addition, we will serialize execution of thread within the session. We also run the proper resource event lifecycle on the controls.
        Daryl Olander made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Hide
        Alejandro Ramirez added a comment -

        Please verify

        Show
        Alejandro Ramirez added a comment - Please verify
        Alejandro Ramirez made changes -
        Assignee Chad Schoettger [ chad_s ] Yongqin Xu [ yongqxu ]
        Hide
        Yongqin Xu added a comment -

        re-run the web app, the connection closed exception does not happen anymore.

        Show
        Yongqin Xu added a comment - re-run the web app, the connection closed exception does not happen anymore.
        Yongqin Xu made changes -
        Status Resolved [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            Yongqin Xu
            Reporter:
            Chad Schoettger
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development