Derby
  1. Derby
  2. DERBY-1465

NetworkServerControl.start() should throw an exception and not just print exceptions if the server fails to start

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Won't Fix
    • Affects Version/s: 10.1.2.1
    • Fix Version/s: None
    • Component/s: Network Server
    • Labels:
      None
    • Urgency:
      Normal
    • Issue & fix info:
      High Value Fix, Release Note Needed

      Description

      NetworkServerControl.start() will not throw an exception if another server is already running on the same port. I am not sure but think perhaps this was changed at one point to accomodate the derby.drda.startNetworkServer property so that the embedded server could continue to boot even if the network server failed to start, but I think this is wrong for normal usage.

      http://www.nabble.com/Questions-about-Network-Server-API-Behavior-p5055814.html

      1. DERBY-1465_diff.txt
        4 kB
        Kathey Marsden
      2. DERBY-1465_stat.txt
        0.3 kB
        Kathey Marsden
      3. DERBY-1465_diff.txt
        5 kB
        Kathey Marsden
      4. DERBY-1465_stat.txt
        0.2 kB
        Kathey Marsden
      5. releaseNote.html
        3 kB
        Kathey Marsden
      6. DERBY-1465.diff3
        4 kB
        Myrna van Lunteren
      7. releaseNote.html
        4 kB
        Myrna van Lunteren
      8. releaseNote.html
        4 kB
        Myrna van Lunteren
      9. DERBY-1465.diff4
        4 kB
        Myrna van Lunteren
      10. DERBY-1465.diff5
        4 kB
        Myrna van Lunteren
      11. DERBY-1465.diff6
        6 kB
        Myrna van Lunteren
      12. DERBY-1465.diff7
        5 kB
        Myrna van Lunteren
      13. DERBY-1465.diff8
        5 kB
        Myrna van Lunteren
      14. DERBY-1465hangibm142_12_29_08.txt
        17 kB
        Myrna van Lunteren
      15. DERBY-1465hangibm15_12_29_08.txt
        13 kB
        Myrna van Lunteren

        Issue Links

          Activity

          Hide
          John H. Embretsen added a comment -

          The relationship between the Network Server API and the derby.drda.startNetworkServer property (and its related functionality) is indeed puzzling. See my comment to DERBY-1326 (June 16th), particularly observation b), for another example:

          http://issues.apache.org/jira/browse/DERBY-1326#action_12416494

          Show
          John H. Embretsen added a comment - The relationship between the Network Server API and the derby.drda.startNetworkServer property (and its related functionality) is indeed puzzling. See my comment to DERBY-1326 (June 16th), particularly observation b), for another example: http://issues.apache.org/jira/browse/DERBY-1326#action_12416494
          Hide
          Kathey Marsden added a comment -

          Attached is a patch for this issue. I ran derbynetclientmats, derbynetmats and suites.All.
          I am a little unsure about this patch. I wait only 5 seconds for any error to occur on startup. It will catch the most common error that there is already another server on the same port, but still the server can't be verified as up until ping is successful. I'll submit another patch for DERBY-1467 which allows a timeout to be specified. That seems the preferred way to go.

          Show
          Kathey Marsden added a comment - Attached is a patch for this issue. I ran derbynetclientmats, derbynetmats and suites.All. I am a little unsure about this patch. I wait only 5 seconds for any error to occur on startup. It will catch the most common error that there is already another server on the same port, but still the server can't be verified as up until ping is successful. I'll submit another patch for DERBY-1467 which allows a timeout to be specified. That seems the preferred way to go.
          Hide
          Kathey Marsden added a comment -

          The patch attached has a conflict with DERBY-2671, so needs to be redone. Ignore the patch DERBY-1465_diff.txt

          Show
          Kathey Marsden added a comment - The patch attached has a conflict with DERBY-2671 , so needs to be redone. Ignore the patch DERBY-1465 _diff.txt
          Hide
          Kathey Marsden added a comment -

          Patch for this issue. start() will now wait until the server has been started. It will wait until just before the server started message prints to return and will throw an exception if one occurred. One possible problem with the existing. One possible problem with the existing code is that it prints "server started" before launching the client thread. If that needs to be moved, I will log it as a separate issue.

          derbynetmats, derbynetclientmats and suites.All passed.
          I'll commit this late today if I hear no comments, but I would appreciate if someone would take a look.

          Thanks

          Kathey

          Show
          Kathey Marsden added a comment - Patch for this issue. start() will now wait until the server has been started. It will wait until just before the server started message prints to return and will throw an exception if one occurred. One possible problem with the existing. One possible problem with the existing code is that it prints "server started" before launching the client thread. If that needs to be moved, I will log it as a separate issue. derbynetmats, derbynetclientmats and suites.All passed. I'll commit this late today if I hear no comments, but I would appreciate if someone would take a look. Thanks Kathey
          Hide
          Kathey Marsden added a comment -

          Committed revision 540779

          Show
          Kathey Marsden added a comment - Committed revision 540779
          Hide
          Daniel John Debrunner added a comment -

          Should the thread you create via this start method be a daemon thread? I couldn't really tell either way from the diff.

          Is it possible to add some comments to the code you added while it's fresh in your mind? At least on the
          serverStartComplete variable and its wait/notify. Give future readers some clue as to what is going on.

          Show
          Daniel John Debrunner added a comment - Should the thread you create via this start method be a daemon thread? I couldn't really tell either way from the diff. Is it possible to add some comments to the code you added while it's fresh in your mind? At least on the serverStartComplete variable and its wait/notify. Give future readers some clue as to what is going on.
          Hide
          Kathey Marsden added a comment -

          Thanks Dan for looking.

          I don't think it should be a daemon thread if I understand the concept of a daemon thread correctly. I don't want the jvm to exit while this thread is running. I'll add comments for serverStartComplete.

          Show
          Kathey Marsden added a comment - Thanks Dan for looking. I don't think it should be a daemon thread if I understand the concept of a daemon thread correctly. I don't want the jvm to exit while this thread is running. I'll add comments for serverStartComplete.
          Hide
          Daniel John Debrunner added a comment -

          Could you also explain the lifetime of this new thread then?

          Does this change mean that starting the network server now has an extra Thread for the lifetime of the network server?

          Does it mean a change in behaviour where previously the JVM could exit but now it cannot until the network server is shutdown?

          Show
          Daniel John Debrunner added a comment - Could you also explain the lifetime of this new thread then? Does this change mean that starting the network server now has an extra Thread for the lifetime of the network server? Does it mean a change in behaviour where previously the JVM could exit but now it cannot until the network server is shutdown?
          Hide
          Kathey Marsden added a comment -

          Dan asked:
          >Could you also explain the lifetime of this new thread then?
          >Does this change mean that starting the network server now has an extra Thread for the lifetime of the network server?

          No. We used to start with DRDAServerStarter which made a thread to start network server. Now NetworkServerControl

          old:
          NetworkServerControl.start() called DRDAServerStarter which started a thread calling blockingStart. blockingStart would log any exceptions.

          new:
          NetworkServerControl.start() creates its own thread calling blockingStart and throws any exceptions that occur during the startup phase. To determine the end of the startup phase it waits on serverStartComplete.
          If start is successful ...
          When blockingStart gets to the point that it would print the server is up, it notifies serverStartComplete so the start method can return or throw any exception that occurred and waits to be shutdown.

          If start fais....
          blockingStart will throw an exception, notify serverStartComplete and the thread will end.

          Show
          Kathey Marsden added a comment - Dan asked: >Could you also explain the lifetime of this new thread then? >Does this change mean that starting the network server now has an extra Thread for the lifetime of the network server? No. We used to start with DRDAServerStarter which made a thread to start network server. Now NetworkServerControl old: NetworkServerControl.start() called DRDAServerStarter which started a thread calling blockingStart. blockingStart would log any exceptions. new: NetworkServerControl.start() creates its own thread calling blockingStart and throws any exceptions that occur during the startup phase. To determine the end of the startup phase it waits on serverStartComplete. If start is successful ... When blockingStart gets to the point that it would print the server is up, it notifies serverStartComplete so the start method can return or throw any exception that occurred and waits to be shutdown. If start fais.... blockingStart will throw an exception, notify serverStartComplete and the thread will end.
          Hide
          Daniel John Debrunner added a comment -

          The old thread was started as a daemon thread, in derby's daemon thread group, but this new thread isn't (for either).

          I think Bryan was trying to clean up the code to start the network server, I wonder if that has progressed to be useable, because this is adding another mechanism to start the server in already confused code.

          There are a couple of timing bugs in the wait code:

          • There is a chance the server can fail to start but the start method will not throw any exceptions.
            This is because the waiter is notified before 'runtimeException' is set, thus the waiter may see runtimeException as null and not throw an exception.
          • There is a chance the start() method will hang, if the spawned thread reaches the notifyAll() before the start() call reaches the wait().
            The standard way to avoid this is to include boolean state information, so that the sync calls are like:

          synchronized (serverStartComplete)

          { completedBoot = true; serverStartComplete.notifyAll(); }

          synchronized(serverStartComplete)

          { while (!completedBoot ) serverStartComplete.wait(); }

          I wonder if the code could be modifed slightly to use the old thread, rather than creating a new thread ...

          Show
          Daniel John Debrunner added a comment - The old thread was started as a daemon thread, in derby's daemon thread group, but this new thread isn't (for either). I think Bryan was trying to clean up the code to start the network server, I wonder if that has progressed to be useable, because this is adding another mechanism to start the server in already confused code. There are a couple of timing bugs in the wait code: There is a chance the server can fail to start but the start method will not throw any exceptions. This is because the waiter is notified before 'runtimeException' is set, thus the waiter may see runtimeException as null and not throw an exception. There is a chance the start() method will hang, if the spawned thread reaches the notifyAll() before the start() call reaches the wait(). The standard way to avoid this is to include boolean state information, so that the sync calls are like: synchronized (serverStartComplete) { completedBoot = true; serverStartComplete.notifyAll(); } synchronized(serverStartComplete) { while (!completedBoot ) serverStartComplete.wait(); } I wonder if the code could be modifed slightly to use the old thread, rather than creating a new thread ...
          Hide
          Kathey Marsden added a comment -

          There are some issues with the change noted in Dan's comments. Backing out the change and reopen until those can be resolved.

          Show
          Kathey Marsden added a comment - There are some issues with the change noted in Dan's comments. Backing out the change and reopen until those can be resolved.
          Hide
          Kathey Marsden added a comment -

          Dan said
          >I think Bryan was trying to clean up the code to start the network server, I wonder if that has progressed to be >useable, because this is adding another mechanism to start the server in already confused code.

          I think actually it was Bernt who was working on rewriting NetworkServerControlImpl. I agree that it makes sense to wait until that work is done and see if it perhaps resolves this issue. My hope was to get it resolved for 10.3 because we already have a bunch of Network Server incompatible changes and if this is going to affect anyone, it is better to have one big hit with 10.3 instead of hitting users again with 10.4. Bernt do you ...
          1) expect your rewrite of NetworkServerControlImpl to go in for 10.3?
          2) think your changes will address this issue.

          Kathey

          Show
          Kathey Marsden added a comment - Dan said >I think Bryan was trying to clean up the code to start the network server, I wonder if that has progressed to be >useable, because this is adding another mechanism to start the server in already confused code. I think actually it was Bernt who was working on rewriting NetworkServerControlImpl. I agree that it makes sense to wait until that work is done and see if it perhaps resolves this issue. My hope was to get it resolved for 10.3 because we already have a bunch of Network Server incompatible changes and if this is going to affect anyone, it is better to have one big hit with 10.3 instead of hitting users again with 10.4. Bernt do you ... 1) expect your rewrite of NetworkServerControlImpl to go in for 10.3? 2) think your changes will address this issue. Kathey
          Hide
          Bernt M. Johnsen added a comment -

          1) I am not going to finish the rewrite of NetworkServerControlImpl for 10.3 (DERBY-2412). My approach to keep the internal code an chop the class into smaller pieces proved not to solve the basic problems. We need to rewrite some basic mechanisms (e.g. exception handling and reporting) first. I plan to do the rewrite for the next release.
          2) Yes (or at least make it much easier to fix it).

          Show
          Bernt M. Johnsen added a comment - 1) I am not going to finish the rewrite of NetworkServerControlImpl for 10.3 ( DERBY-2412 ). My approach to keep the internal code an chop the class into smaller pieces proved not to solve the basic problems. We need to rewrite some basic mechanisms (e.g. exception handling and reporting) first. I plan to do the rewrite for the next release. 2) Yes (or at least make it much easier to fix it).
          Hide
          Kathey Marsden added a comment -

          Per Dan's recommendation, I think I will hold off on this issue until Bernt's changes go in. Unassigning myself for now.

          Show
          Kathey Marsden added a comment - Per Dan's recommendation, I think I will hold off on this issue until Bernt's changes go in. Unassigning myself for now.
          Hide
          Myrna van Lunteren added a comment -

          Since Bernt has now (see update to DERBY-2412) no plans to complete redesign of NetworkServerControlImpl, I was thinking it might make sense to revisit this issue.

          However, I am not sure about one of Dan's comments:
          " wonder if the code could be modifed slightly to use the old thread, rather than creating a new thread ... "

          I can imagine DRDAServerStarter.boot(...) carrying an additional parameter to indicate whether to throw an exception or not, is that what was meant? Or is there another solution?

          Show
          Myrna van Lunteren added a comment - Since Bernt has now (see update to DERBY-2412 ) no plans to complete redesign of NetworkServerControlImpl, I was thinking it might make sense to revisit this issue. However, I am not sure about one of Dan's comments: " wonder if the code could be modifed slightly to use the old thread, rather than creating a new thread ... " I can imagine DRDAServerStarter.boot(...) carrying an additional parameter to indicate whether to throw an exception or not, is that what was meant? Or is there another solution?
          Hide
          Myrna van Lunteren added a comment -

          I'm attaching a patch for this issue...
          It's basically Kathey's latest patch, but with the synchronization changes suggested by Dan, and the Thread has been made a daemon thread.
          There's also some extra comments.

          I tried to make DRDAServerStarter.boot carry an extra parameter, and based on that parameter, exceptions got thrown as well as logged, but the exception in the test (NSinSameJVMTest fixture testShutdown has a new test case) came from DRDAServerStarter.run (invocationException), which did not allow me to throw a standard exception. Also, I felt the code got more convoluted and expansive.

          Anyone have another suggestion on how to fix this, or how Dan's comment ("maybe the code could be slightly modified to use the old thread") could be interpreted?

          Show
          Myrna van Lunteren added a comment - I'm attaching a patch for this issue... It's basically Kathey's latest patch, but with the synchronization changes suggested by Dan, and the Thread has been made a daemon thread. There's also some extra comments. I tried to make DRDAServerStarter.boot carry an extra parameter, and based on that parameter, exceptions got thrown as well as logged, but the exception in the test (NSinSameJVMTest fixture testShutdown has a new test case) came from DRDAServerStarter.run (invocationException), which did not allow me to throw a standard exception. Also, I felt the code got more convoluted and expansive. Anyone have another suggestion on how to fix this, or how Dan's comment ("maybe the code could be slightly modified to use the old thread") could be interpreted?
          Hide
          Myrna van Lunteren added a comment -

          No suggestions/comments so far.
          suites.All ran without failures. I plan to commit this tomorrow.

          Show
          Myrna van Lunteren added a comment - No suggestions/comments so far. suites.All ran without failures. I plan to commit this tomorrow.
          Hide
          Myrna van Lunteren added a comment -

          I committed the latest patch with revision 718616.

          Now - this issue has 'release note needed' flagged, but I'm not certain why
          It does need to be in the release notes, of course, but does this need a special explanation? It seems to me, that either way, the server is not started (as it's already started), and we're still also printing the exceptions, so I have some trouble seeing how this could affect existing applications. Any thoughts?

          Show
          Myrna van Lunteren added a comment - I committed the latest patch with revision 718616. Now - this issue has 'release note needed' flagged, but I'm not certain why It does need to be in the release notes, of course, but does this need a special explanation? It seems to me, that either way, the server is not started (as it's already started), and we're still also printing the exceptions, so I have some trouble seeing how this could affect existing applications. Any thoughts?
          Hide
          Kathey Marsden added a comment -

          Applications may have only been expecting exceptions when they ping the server to see if it is is up, not from start() since start would always succeed before. Applications need to be prepared for an exception to be thrown from start().

          Show
          Kathey Marsden added a comment - Applications may have only been expecting exceptions when they ping the server to see if it is is up, not from start() since start would always succeed before. Applications need to be prepared for an exception to be thrown from start().
          Hide
          Myrna van Lunteren added a comment -

          Attaching a first attempt at a release note.

          Show
          Myrna van Lunteren added a comment - Attaching a first attempt at a release note.
          Hide
          Myrna van Lunteren added a comment -

          pretty much the same release note, but replace reference to NetworkServerControlImpl.start() with NetworkServerControl.start()

          Show
          Myrna van Lunteren added a comment - pretty much the same release note, but replace reference to NetworkServerControlImpl.start() with NetworkServerControl.start()
          Hide
          Kathey Marsden added a comment -

          Release note looks fine to me.

          Show
          Kathey Marsden added a comment - Release note looks fine to me.
          Hide
          Myrna van Lunteren added a comment -

          I wanted to close this today, but I see in the nightlies that this has resulted in an intermittent failure - and with sun jdk 1.4.2, it's all over.
          I'll investigate.

          Show
          Myrna van Lunteren added a comment - I wanted to close this today, but I see in the nightlies that this has resulted in an intermittent failure - and with sun jdk 1.4.2, it's all over. I'll investigate.
          Hide
          Myrna van Lunteren added a comment -

          Attaching a patch that I think gets around the trouble the previous attempt caused in the nightly tests.

          However, I need to do some more research before I commit - I ran suites.All twice, once I got this failure:
          --------------------------------
          1) testStartStopManagementFromApplication(org.apache.derbyTesting.functionTests.tests.management.ManagementMBeanTest)junit.framework.AssertionFailedError: expected:<4> but was:<6>
          at org.apache.derbyTesting.functionTests.tests.management.ManagementMBeanTest.startStopManagement(ManagementMBeanTest.java:76)
          at org.apache.derbyTesting.functionTests.tests.management.ManagementMBeanTest.testStartStopManagementFromApplication(ManagementMBeanTest.java:56)
          --------------------------------
          I think I get this intermittently, so this may be unrelated.
          But once I got a hang after an error:
          --------------------------------
          testXAConnection used 0 ms EEjava.lang.Exception: DRDA_InvalidReplyTooShort.S:Invalid reply from network server: Insufficient data.
          at org.apache.derby.impl.drda.NetworkServerControlImpl.consolePropertyMessageWork(Unknown Source)
          at org.apache.derby.impl.drda.NetworkServerControlImpl.consolePropertyMessage(Unknown Source)
          at org.apache.derby.impl.drda.NetworkServerControlImpl.fillReplyBuffer(Unknown Source)
          at org.apache.derby.impl.drda.NetworkServerControlImpl.readResult(Unknown Source)
          at org.apache.derby.impl.drda.NetworkServerControlImpl.pingWithNoOpen(Unknown Source)
          at org.apache.derby.impl.drda.NetworkServerControlImpl.ping(Unknown Source)
          at org.apache.derby.drda.NetworkServerControl.ping(Unknown Source)
          at org.apache.derbyTesting.junit.NetworkServerTestSetup.pingForServerUp(NetworkServerTestSetup.java:561)
          at org.apache.derbyTesting.junit.NetworkServerTestSetup.pingForServerStart(NetworkServerTestSetup.java:630)
          at org.apache.derbyTesting.junit.NetworkServerTestSetup.setUp(NetworkServerTestSetup.java:191)
          at junit.extensions.TestSetup$1.protect(TestSetup.java:18)
          at junit.framework.TestResult.runProtected(TestResult.java:124)
          at junit.extensions.TestSetup.run(TestSetup.java:23)
          at org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57)
          at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
          at junit.extensions.TestSetup$1.protect(TestSetup.java:19)
          at junit.framework.TestResult.runProtected(TestResult.java:124)
          at junit.extensions.TestSetup.run(TestSetup.java:23)
          at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
          at junit.extensions.TestSetup$1.protect(TestSetup.java:19)
          at junit.framework.TestResult.runProtected(TestResult.java:124)
          at junit.extensions.TestSetup.run(TestSetup.java:23)
          at junit.framework.TestSuite.runTest(TestSuite.java:208)
          at junit.framework.TestSuite.run(TestSuite.java:203)
          at junit.framework.TestSuite.runTest(TestSuite.java:208)
          at junit.framework.TestSuite.run(TestSuite.java:203)
          at junit.framework.TestSuite.runTest(TestSuite.java:208)
          at junit.framework.TestSuite.run(TestSuite.java:203)
          at junit.framework.TestSuite.runTest(TestSuite.java:208)
          at junit.framework.TestSuite.run(TestSuite.java:203)
          at junit.textui.TestRunner.doRun(TestRunner.java:116)
          at junit.textui.TestRunner.start(TestRunner.java:172)
          at junit.textui.TestRunner.main(TestRunner.java:138)
          --------------------------------

          Show
          Myrna van Lunteren added a comment - Attaching a patch that I think gets around the trouble the previous attempt caused in the nightly tests. However, I need to do some more research before I commit - I ran suites.All twice, once I got this failure: -------------------------------- 1) testStartStopManagementFromApplication(org.apache.derbyTesting.functionTests.tests.management.ManagementMBeanTest)junit.framework.AssertionFailedError: expected:<4> but was:<6> at org.apache.derbyTesting.functionTests.tests.management.ManagementMBeanTest.startStopManagement(ManagementMBeanTest.java:76) at org.apache.derbyTesting.functionTests.tests.management.ManagementMBeanTest.testStartStopManagementFromApplication(ManagementMBeanTest.java:56) -------------------------------- I think I get this intermittently, so this may be unrelated. But once I got a hang after an error: -------------------------------- testXAConnection used 0 ms EEjava.lang.Exception: DRDA_InvalidReplyTooShort.S:Invalid reply from network server: Insufficient data. at org.apache.derby.impl.drda.NetworkServerControlImpl.consolePropertyMessageWork(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.consolePropertyMessage(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.fillReplyBuffer(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.readResult(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.pingWithNoOpen(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.ping(Unknown Source) at org.apache.derby.drda.NetworkServerControl.ping(Unknown Source) at org.apache.derbyTesting.junit.NetworkServerTestSetup.pingForServerUp(NetworkServerTestSetup.java:561) at org.apache.derbyTesting.junit.NetworkServerTestSetup.pingForServerStart(NetworkServerTestSetup.java:630) at org.apache.derbyTesting.junit.NetworkServerTestSetup.setUp(NetworkServerTestSetup.java:191) at junit.extensions.TestSetup$1.protect(TestSetup.java:18) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.extensions.TestSetup.run(TestSetup.java:23) at org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57) at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22) at junit.extensions.TestSetup$1.protect(TestSetup.java:19) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.extensions.TestSetup.run(TestSetup.java:23) at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22) at junit.extensions.TestSetup$1.protect(TestSetup.java:19) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.extensions.TestSetup.run(TestSetup.java:23) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at junit.textui.TestRunner.doRun(TestRunner.java:116) at junit.textui.TestRunner.start(TestRunner.java:172) at junit.textui.TestRunner.main(TestRunner.java:138) --------------------------------
          Hide
          Myrna van Lunteren added a comment -

          Attaching another patch - it has only 2 differences vs. patch diff4;
          1. setting runtimeException to null at the top of start (or the exception might not get cleared out)
          2. add some comments

          Show
          Myrna van Lunteren added a comment - Attaching another patch - it has only 2 differences vs. patch diff4; 1. setting runtimeException to null at the top of start (or the exception might not get cleared out) 2. add some comments
          Hide
          Myrna van Lunteren added a comment -

          I have not seen the hang anymore on my own machine; however, it seems that since my check-in of November 18, tests are hanging regularly in nightlies on windows, see: http://people.apache.org/~myrnavl/derby_test_results/main/windows/index.html

          I don't understand the hang, so I don't have a solution...

          I have two approaches currently;
          1. check in the latest patch
          2. back out my first change

          Or is there someone who can spot a mistake in the (patch) code?

          Show
          Myrna van Lunteren added a comment - I have not seen the hang anymore on my own machine; however, it seems that since my check-in of November 18, tests are hanging regularly in nightlies on windows, see: http://people.apache.org/~myrnavl/derby_test_results/main/windows/index.html I don't understand the hang, so I don't have a solution... I have two approaches currently; 1. check in the latest patch 2. back out my first change Or is there someone who can spot a mistake in the (patch) code?
          Hide
          Ole Solberg added a comment -

          I am also seeing this, after November 18, on

          Red Hat Enterprise Linux AS release 4 (Nahant Update 3) 64bits
          Linux 2.6.9-34.ELsmp #1 SMP Fri Feb 24 16:56:28 EST 2006 GNU/Linux
          and
          Solaris 10 5/08 s10x_u5wos_10 X86 64bits
          SunOS 5.10 Generic_127128-11

          with
          Sun Microsystems Inc.
          java version "1.5.0_14"
          Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
          Java HotSpot(TM) Client VM (build 1.5.0_14-b03, mixed mode)

          See e.g.
          http://dbtg.thresher.com/derby/test/trunk15/jvm1.5/testing/testlog/SunOS-5.10_i86pc-i386/722171-org.apache.derbyTesting.functionTests.suites.All_diff.txt

          Show
          Ole Solberg added a comment - I am also seeing this, after November 18, on Red Hat Enterprise Linux AS release 4 (Nahant Update 3) 64bits Linux 2.6.9-34.ELsmp #1 SMP Fri Feb 24 16:56:28 EST 2006 GNU/Linux and Solaris 10 5/08 s10x_u5wos_10 X86 64bits SunOS 5.10 Generic_127128-11 with Sun Microsystems Inc. java version "1.5.0_14" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03) Java HotSpot(TM) Client VM (build 1.5.0_14-b03, mixed mode) See e.g. http://dbtg.thresher.com/derby/test/trunk15/jvm1.5/testing/testlog/SunOS-5.10_i86pc-i386/722171-org.apache.derbyTesting.functionTests.suites.All_diff.txt
          Hide
          Myrna van Lunteren added a comment -

          I couldn't figure out off hand where the trouble is that causes the hang. Somehow, it seems there is no ClientThread running to handle the clients' requests, and thus, the whole thing hangs - can't start a new server, can't connect to the current one, can't shut it down.

          I've backed out the changes of revision 718616 with revision 722639.

          Sorry for all the trouble.

          Show
          Myrna van Lunteren added a comment - I couldn't figure out off hand where the trouble is that causes the hang. Somehow, it seems there is no ClientThread running to handle the clients' requests, and thus, the whole thing hangs - can't start a new server, can't connect to the current one, can't shut it down. I've backed out the changes of revision 718616 with revision 722639. Sorry for all the trouble.
          Hide
          Knut Anders Hatlen added a comment -

          I don't know why it hung, but since blockingStart() calls startNetworkServer() before the try/finally block, it's possible that an exception is thrown without completedBoot being set to true, which will leave the main thread waiting forever.

          It also looks like #718616 did not address this comment (by Dan):
          > - There is a chance the server can fail to start but the start method will not throw any exceptions.
          > This is because the waiter is notified before 'runtimeException' is set, thus the waiter may see runtimeException as null and not throw an exception.

          Show
          Knut Anders Hatlen added a comment - I don't know why it hung, but since blockingStart() calls startNetworkServer() before the try/finally block, it's possible that an exception is thrown without completedBoot being set to true, which will leave the main thread waiting forever. It also looks like #718616 did not address this comment (by Dan): > - There is a chance the server can fail to start but the start method will not throw any exceptions. > This is because the waiter is notified before 'runtimeException' is set, thus the waiter may see runtimeException as null and not throw an exception.
          Hide
          Myrna van Lunteren added a comment -

          Attaching a next iteration - DERBY-1465.diff6

          Dan's comment cited by Knut Anders:
          "There is a chance the server can fail to start but the start method will not throw any exceptions, because the waiter is notified before 'runtimeException' is set, thus the waiter may see runtimeException as null and not throw an exception"
          was actually addressed by patch 4.
          (patch 5 corrected the fact that the runtimeException never got set to null, so you'd get that message all the time).

          Patch 6 I think addresses the second logic issue spotted by Knut Anders:
          "since blockingStart() calls startNetworkServer() before the try/finally block, it's possible that an exception is thrown without completedBoot being set to true, which will leave the main thread waiting forever"
          This is addressed by (simply) setting completedBoot to true when an error is encountered.

          I ran NSinSameTest withouth problems 50 times (this at one time would reproduce the hang occassionally). I ran suitesall 4 times on 2 different windows machines, and derbyall once, and I hit the following known problems:

          • DERBY-654; derbyall: unit/T_RawStoreFactory.unit
            < – Unit Test T_RawStoreFactory finished
            2 add
            > There should be 0 observers, but we still have 1 observers.
            > Shutting down due to unit test failure.
            (maybe this is a j9 technology issue rather than j2me).
          • DERBY-3915:
            1) testReplication_Local_3_p3_StateNegativeTests
            (org.apache.derbyTesting.functionTests.tests.replicationTests.ReplicationRun_Local_3_p3)
            junit.framework.AssertionFailedError: Expected SQLState'08004', but got connection!
          • DERBY-3689:
            1) testAttributeAccumulatedConnectionCount(org.apache.derbyTesting.functionTests.tests.management.NetworkServerMBeanTest)
            java.security.PrivilegedActionException: javax.management.InstanceNotFoundException:
          • DERBY-3757:
            1) testStressMulti(org.apache.derbyTesting.functionTests.tests.multi.StressMultiTest)junit.framework.AssertionFailedError:
            Caused by:
            java.sql.SQLException: Java exception: 'ASSERT FAILED transaction table has null entry:
            org.apache.derby.shared.common.sanity.AssertFailure'.

          In addition, I got:
          1) ttestSetPortPriority(org.apache.derbyTesting.functionTests.tests.derbynet.ServerPropertiesTest)
          junit.framework.AssertionFailedError: failed to start server with port 1529
          at org.apache.derbyTesting.functionTests.tests.derbynet.ServerPropertiesTest.checkWhetherNeedToShutdown(ServerPropertiesTest.java:378)
          I think this is probably the same as DERBY-3873, or DERBY-2779, but because we now throw the Exception when the server doesn't start, we see the problem earlier. Which is exactly what this fix is intended to do.

          So I think this is ok now.

          Ready for review.

          Show
          Myrna van Lunteren added a comment - Attaching a next iteration - DERBY-1465 .diff6 Dan's comment cited by Knut Anders: "There is a chance the server can fail to start but the start method will not throw any exceptions, because the waiter is notified before 'runtimeException' is set, thus the waiter may see runtimeException as null and not throw an exception" was actually addressed by patch 4. (patch 5 corrected the fact that the runtimeException never got set to null, so you'd get that message all the time). Patch 6 I think addresses the second logic issue spotted by Knut Anders: "since blockingStart() calls startNetworkServer() before the try/finally block, it's possible that an exception is thrown without completedBoot being set to true, which will leave the main thread waiting forever" This is addressed by (simply) setting completedBoot to true when an error is encountered. I ran NSinSameTest withouth problems 50 times (this at one time would reproduce the hang occassionally). I ran suitesall 4 times on 2 different windows machines, and derbyall once, and I hit the following known problems: DERBY-654 ; derbyall: unit/T_RawStoreFactory.unit < – Unit Test T_RawStoreFactory finished 2 add > There should be 0 observers, but we still have 1 observers. > Shutting down due to unit test failure. (maybe this is a j9 technology issue rather than j2me). DERBY-3915 : 1) testReplication_Local_3_p3_StateNegativeTests (org.apache.derbyTesting.functionTests.tests.replicationTests.ReplicationRun_Local_3_p3) junit.framework.AssertionFailedError: Expected SQLState'08004', but got connection! DERBY-3689 : 1) testAttributeAccumulatedConnectionCount(org.apache.derbyTesting.functionTests.tests.management.NetworkServerMBeanTest) java.security.PrivilegedActionException: javax.management.InstanceNotFoundException: DERBY-3757 : 1) testStressMulti(org.apache.derbyTesting.functionTests.tests.multi.StressMultiTest)junit.framework.AssertionFailedError: Caused by: java.sql.SQLException: Java exception: 'ASSERT FAILED transaction table has null entry: org.apache.derby.shared.common.sanity.AssertFailure'. In addition, I got: 1) ttestSetPortPriority(org.apache.derbyTesting.functionTests.tests.derbynet.ServerPropertiesTest) junit.framework.AssertionFailedError: failed to start server with port 1529 at org.apache.derbyTesting.functionTests.tests.derbynet.ServerPropertiesTest.checkWhetherNeedToShutdown(ServerPropertiesTest.java:378) I think this is probably the same as DERBY-3873 , or DERBY-2779 , but because we now throw the Exception when the server doesn't start, we see the problem earlier. Which is exactly what this fix is intended to do. So I think this is ok now. Ready for review.
          Hide
          Knut Anders Hatlen added a comment -

          In patch 6, completedBoot is set to true in the catch block in
          startNetworkServer() after consolePropertyMessage() has been
          called. If I understand the code in consolePropertyMessage()
          correctly, it will in many cases throw an exception in addition to
          printing a message to the console, in which case completedBoot is not
          set to true. And I guess notifyAll() would have to be called there as
          well.

          Should completedBoot also be reset when runtimeException is reset?

          Perhaps this is a more robust approach:

          1) Remove the runtimeException instance variable, and don't set it
          in blockingStart()

          2) Move the setting of completedBoot out of the finally block in
          blockingStart(), and don't set it in startNetworkServer(), so that
          it's only set if there was no error

          3) Put this in the start() method:

          completedBoot = false; // reset before we boot
          final Exception[] exceptionHolder = new Exception[1];
          .
          .
          .
          Thread t = new Thread("NetworkServerControl") {
          public void run() {
          try

          { blockingStart(consoleWriter); }

          catch (Exception e) {
          synchronized (serverStartComplete)

          { exceptionHolder[0] = e; serverStartComplete.notifyAll(); }

          }
          }
          };
          .
          .
          .
          t.start();
          // wait until the server has started successfully
          // or an error has been detected
          synchronized (serverStartComplete) {
          while (!completedBoot && exceptionHolder[0] == null)

          { serverStartComplete.wait(); }

          }
          if (!completedBoot)

          { // boot was not successful, throw the exception throw exceptionHolder[0]; }

          With this approach, we make the tracking of the exception simpler (all
          exception handling is local to the start() method), and since
          completedBoot is only set on successful boot, we don't need to track
          down all error paths where it needs to be set.

          Show
          Knut Anders Hatlen added a comment - In patch 6, completedBoot is set to true in the catch block in startNetworkServer() after consolePropertyMessage() has been called. If I understand the code in consolePropertyMessage() correctly, it will in many cases throw an exception in addition to printing a message to the console, in which case completedBoot is not set to true. And I guess notifyAll() would have to be called there as well. Should completedBoot also be reset when runtimeException is reset? Perhaps this is a more robust approach: 1) Remove the runtimeException instance variable, and don't set it in blockingStart() 2) Move the setting of completedBoot out of the finally block in blockingStart(), and don't set it in startNetworkServer(), so that it's only set if there was no error 3) Put this in the start() method: completedBoot = false; // reset before we boot final Exception[] exceptionHolder = new Exception [1] ; . . . Thread t = new Thread("NetworkServerControl") { public void run() { try { blockingStart(consoleWriter); } catch (Exception e) { synchronized (serverStartComplete) { exceptionHolder[0] = e; serverStartComplete.notifyAll(); } } } }; . . . t.start(); // wait until the server has started successfully // or an error has been detected synchronized (serverStartComplete) { while (!completedBoot && exceptionHolder [0] == null) { serverStartComplete.wait(); } } if (!completedBoot) { // boot was not successful, throw the exception throw exceptionHolder[0]; } With this approach, we make the tracking of the exception simpler (all exception handling is local to the start() method), and since completedBoot is only set on successful boot, we don't need to track down all error paths where it needs to be set.
          Hide
          Myrna van Lunteren added a comment -

          Thanks for the suggestions.

          I implemented them with this latest patch.
          I saw no new failures with this and no hangs.

          Show
          Myrna van Lunteren added a comment - Thanks for the suggestions. I implemented them with this latest patch. I saw no new failures with this and no hangs.
          Hide
          Knut Anders Hatlen added a comment -

          Thanks for making the changes, Myrna.

          I think the entire synchronization block, including the call to notifyAll(), should be moved out of the finally block along with the setting of completedBoot to true in blockingStart(). It's probably going to work without that change, but the setting of completedBoot and the call to notifyAll() belong together logically, so I think it would be clearer if they were located the same place in the code.

          Otherwise, the patch looks good to me.

          Show
          Knut Anders Hatlen added a comment - Thanks for making the changes, Myrna. I think the entire synchronization block, including the call to notifyAll(), should be moved out of the finally block along with the setting of completedBoot to true in blockingStart(). It's probably going to work without that change, but the setting of completedBoot and the call to notifyAll() belong together logically, so I think it would be clearer if they were located the same place in the code. Otherwise, the patch looks good to me.
          Hide
          Knut Anders Hatlen added a comment -

          Just one tiny nit in the test. We have this code:

          + } catch (Exception e)

          { + assertTrue(e.getMessage().indexOf("java.net.BindException") > 1); + }

          Perhaps it's better with something like this (untested):

          catch (Exception e) {
          boolean ok = false;
          for (Throwable t = e; t != null; t = t.getCause()) {
          if (t instanceof java.net.BindException)

          { ok = true; break; }

          }
          if (!ok)

          { throw e; }

          }

          The advantage is that we keep the original exception if it's not the one we expected, and that we don't depend on the contents of the message text (don't know, but it may perhaps vary between different JVMs).

          Show
          Knut Anders Hatlen added a comment - Just one tiny nit in the test. We have this code: + } catch (Exception e) { + assertTrue(e.getMessage().indexOf("java.net.BindException") > 1); + } Perhaps it's better with something like this (untested): catch (Exception e) { boolean ok = false; for (Throwable t = e; t != null; t = t.getCause()) { if (t instanceof java.net.BindException) { ok = true; break; } } if (!ok) { throw e; } } The advantage is that we keep the original exception if it's not the one we expected, and that we don't depend on the contents of the message text (don't know, but it may perhaps vary between different JVMs).
          Hide
          Myrna van Lunteren added a comment -

          I'm still looking at the previous comment, but the last comment throws me for a loop.

          In the latest patch, using the exceptionHolder array as suggested and not using a global variable to hold the exception, we do not know what kind of exception it is in the start() method. So we can't actually check for the BindException class in the test, all we have there is a java.lang.Exception.

          When we use a global variable (we used runtimeException in earlier patches), and assign the Exception underlying the PrivilegedActionException at the top of the privilegedException block to it, then the cause of the Exception, at least for IOExceptions (i.e. in the case of the java.net.BindException the test is forcing) is saved off. Like so:
          } catch (PrivilegedActionException e) {
          Exception e1 = e.getException();
          runtimeException = e1;

          I could reinstate the runtimeException, and in the start() method do some tomfoolery like:
          if (runtimeException != null)
          exceptionHolder[0] = runtimeException;
          else
          exceptionHolder[0] = e;
          Then I can check for the bindException instance in the test...But that's reintroducing the global variable...
          What is the better approach?
          I do like the fact that with the global variable you can actually check for IOExceptions in the test (and thus app) code, gives more info/control...But maybe it's enough to have an Exception?

          Show
          Myrna van Lunteren added a comment - I'm still looking at the previous comment, but the last comment throws me for a loop. In the latest patch, using the exceptionHolder array as suggested and not using a global variable to hold the exception, we do not know what kind of exception it is in the start() method. So we can't actually check for the BindException class in the test, all we have there is a java.lang.Exception. When we use a global variable (we used runtimeException in earlier patches), and assign the Exception underlying the PrivilegedActionException at the top of the privilegedException block to it, then the cause of the Exception, at least for IOExceptions (i.e. in the case of the java.net.BindException the test is forcing) is saved off. Like so: } catch (PrivilegedActionException e) { Exception e1 = e.getException(); runtimeException = e1; I could reinstate the runtimeException, and in the start() method do some tomfoolery like: if (runtimeException != null) exceptionHolder [0] = runtimeException; else exceptionHolder [0] = e; Then I can check for the bindException instance in the test...But that's reintroducing the global variable... What is the better approach? I do like the fact that with the global variable you can actually check for IOExceptions in the test (and thus app) code, gives more info/control...But maybe it's enough to have an Exception?
          Hide
          Knut Anders Hatlen added a comment -

          Right, I assumed that the BindException was in the exception chain, but I see now that that's not the case. If we just want to preserve the exception in case it's an unexpected one in the test, we could simply do this and ignore that we don't really have a BindException in the chain:

          catch (Exception e) {
          if (e.getMessage().indexOf("java.net.BindException") == -1)

          { throw e; }

          }

          As to the issue of preserving the original exception when a BindException (or any other exception) is thrown, I think the problem here is that consolePropertyMessage() only takes the message to print as an argument. Since it in many cases generates and throws a new exception, it should also take the underlying exception as an argument, and it should either re-throw it or put it in the chain with initCause() so that we preserve the stack trace of the root cause. It doesn't have to be fixed as part of this issue, but I think it would be worth fixing.

          Show
          Knut Anders Hatlen added a comment - Right, I assumed that the BindException was in the exception chain, but I see now that that's not the case. If we just want to preserve the exception in case it's an unexpected one in the test, we could simply do this and ignore that we don't really have a BindException in the chain: catch (Exception e) { if (e.getMessage().indexOf("java.net.BindException") == -1) { throw e; } } As to the issue of preserving the original exception when a BindException (or any other exception) is thrown, I think the problem here is that consolePropertyMessage() only takes the message to print as an argument. Since it in many cases generates and throws a new exception, it should also take the underlying exception as an argument, and it should either re-throw it or put it in the chain with initCause() so that we preserve the stack trace of the root cause. It doesn't have to be fixed as part of this issue, but I think it would be worth fixing.
          Hide
          Myrna van Lunteren added a comment -

          Yes, it would be better if consolePropertyMessage passed on the underlying Exception.

          I'll create one last patch modifying just the start and blockingStart methods and changing the test - then (after one more test cycle) commit that.

          I can then look into the consolePropertyMessage change - and will decide then whether to do it as part of this issue in a follow up commit or log a new issue.

          Show
          Myrna van Lunteren added a comment - Yes, it would be better if consolePropertyMessage passed on the underlying Exception. I'll create one last patch modifying just the start and blockingStart methods and changing the test - then (after one more test cycle) commit that. I can then look into the consolePropertyMessage change - and will decide then whether to do it as part of this issue in a follow up commit or log a new issue.
          Hide
          Myrna van Lunteren added a comment -

          uploading patch diff8, which addresses further comments, as discussed, in the start and blockingStart methods of NetworkServerControlImpl, and the NSinSameJVMTest, but doesn't try to modify consolePropertyMessage method.

          suites.all passed without mishap.

          Show
          Myrna van Lunteren added a comment - uploading patch diff8, which addresses further comments, as discussed, in the start and blockingStart methods of NetworkServerControlImpl, and the NSinSameJVMTest, but doesn't try to modify consolePropertyMessage method. suites.all passed without mishap.
          Hide
          Knut Anders Hatlen added a comment -

          diff8 looks fine to me. +1 to commit.

          Show
          Knut Anders Hatlen added a comment - diff8 looks fine to me. +1 to commit.
          Hide
          Myrna van Lunteren added a comment -

          I committed diff8 with revision 729933. If no hangs are reported in a week I'll consider this part done...

          Show
          Myrna van Lunteren added a comment - I committed diff8 with revision 729933. If no hangs are reported in a week I'll consider this part done...
          Hide
          Myrna van Lunteren added a comment -

          Well, it seems there still is a hang.

          With ibm142 on another machine than where I ran my tests before, suites.All is hanging (it's been at it for about 11 hours, should take about 5 hours on this particular machine) - the test run seems wedged currently in testReplication_Local_existingTestsAsReplLoad.

          I'll back out my changes...(again). Apologies for the trouble.

          Show
          Myrna van Lunteren added a comment - Well, it seems there still is a hang. With ibm142 on another machine than where I ran my tests before, suites.All is hanging (it's been at it for about 11 hours, should take about 5 hours on this particular machine) - the test run seems wedged currently in testReplication_Local_existingTestsAsReplLoad. I'll back out my changes...(again). Apologies for the trouble.
          Hide
          Myrna van Lunteren added a comment -

          On Dec 30, I also ran with ibm15 and ibm16 on the same machine, and although ibm16 ran through without trouble, the ibm15 run got wedged in StressMultiTest.

          Show
          Myrna van Lunteren added a comment - On Dec 30, I also ran with ibm15 and ibm16 on the same machine, and although ibm16 ran through without trouble, the ibm15 run got wedged in StressMultiTest.
          Hide
          Myrna van Lunteren added a comment -

          Attaching stack traces of the javacore dump I caused to be generated while the test was hanging in the replication test.

          The db_master dir had a derby.log in it with the following:
          ---------------------
          2008-12-30 09:05:59.447 GMT : Could not listen on port 1527 on host 0.0.0.0:
          java.net.BindException: Address already in use: NET_Bind
          ---------------------

          This is probably one of the faster machines I run on...(2 cpu, 3.40 Ghz).

          Show
          Myrna van Lunteren added a comment - Attaching stack traces of the javacore dump I caused to be generated while the test was hanging in the replication test. The db_master dir had a derby.log in it with the following: --------------------- 2008-12-30 09:05:59.447 GMT : Could not listen on port 1527 on host 0.0.0.0: java.net.BindException: Address already in use: NET_Bind --------------------- This is probably one of the faster machines I run on...(2 cpu, 3.40 Ghz).
          Hide
          Myrna van Lunteren added a comment -

          Attaching a java core dump of the test run that hung with ibm15.

          I only now noticed that there were a number (15 to 20) of Errors both with ibm142 and ibm15, starting with the fixture testGrantAndRevoke. But of course there is no list of these at the bottom of the output, because I killed the test run...

          Unfortunately, there is no 'fail' directory, not sure why not...

          Show
          Myrna van Lunteren added a comment - Attaching a java core dump of the test run that hung with ibm15. I only now noticed that there were a number (15 to 20) of Errors both with ibm142 and ibm15, starting with the fixture testGrantAndRevoke. But of course there is no list of these at the bottom of the output, because I killed the test run... Unfortunately, there is no 'fail' directory, not sure why not...
          Hide
          Myrna van Lunteren added a comment -
          Show
          Myrna van Lunteren added a comment - I think this issue was possibly blocked by DERBY-4053 , or perhaps DERBY-4034 , or the additional bind error and hang described in https://issues.apache.org/jira/browse/DERBY-4155?focusedCommentId=12731086&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_12731086 .
          Hide
          Kathey Marsden added a comment -

          I have been thinking about this issue which I filed back in Jan, 2006. At the time it seemed to make sense, but now the compatibility risks seem significant, now that Derby has been out for years. I think by now folks have figured out that they need to ping the server to determine if it is up. If it now starts throwing an exception it might cause problems.

          I think Myrna's work on this issue has been valuable as it helped expose the issues mentioned in the previous comment, but I am beginning to think we should close this won't fix. There had been talk about a new API for network server to replace the one that we have, if we do that then the exception on start issue can be taken under consideration.

          Show
          Kathey Marsden added a comment - I have been thinking about this issue which I filed back in Jan, 2006. At the time it seemed to make sense, but now the compatibility risks seem significant, now that Derby has been out for years. I think by now folks have figured out that they need to ping the server to determine if it is up. If it now starts throwing an exception it might cause problems. I think Myrna's work on this issue has been valuable as it helped expose the issues mentioned in the previous comment, but I am beginning to think we should close this won't fix. There had been talk about a new API for network server to replace the one that we have, if we do that then the exception on start issue can be taken under consideration.
          Hide
          Myrna van Lunteren added a comment -

          Closing as won't fix after reporter's reconsidering.

          Show
          Myrna van Lunteren added a comment - Closing as won't fix after reporter's reconsidering.

            People

            • Assignee:
              Myrna van Lunteren
              Reporter:
              Kathey Marsden
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development