RE: ServerSocket not being closed properly.
At 7:19 PM -0700 04/23/2001, [EMAIL PROTECTED] wrote: On Mon, 23 Apr 2001, Arun Katkere wrote: In general you need to do something to unblock the accept thread, and 3.2 doesn't have this in. Yes, I remember now. You're absolutely right. You need serverSocket.setSoTimeout() to break the accept periodically. Here's how I did it in my app. Notice the comment: apparently I got this from an early version of Tomcat. public void run() { if (serverSocket != null) // original is server { isListening = true; while(isListening) { try { Socket clientSocket = serverSocket.accept(); SocketServer clone = (SocketServer)clone(); clone.serverSocket = null; clone.clientSocket = clientSocket; clone.thread = new Thread(clone, name+Clone); clone.thread.start(); } catch (InterruptedIOException e) { /** * Ignore periodic SO_TIMEOUT interrupts * Without this the accept call never returns when the serversocket * is closed, and all subsequent runs fail with port 8082 busy. * I found this in the Tomcat http server code. */ } catch (Throwable e) { e.printStackTrace(); isListening = false; } } } else run(clientSocket); } void startServer(int port) throws UserFault { if (thread == null) { try { serverSocket = new ServerSocket(port); serverSocket.setSoTimeout(WAKEUP_INTERVAL); } catch (IOException e) { throw UserFault.errEnablerPortBusy(port); } thread = new Thread(this, name+Master); isListening = true; thread.start(); } } -- --- Brad Cox, Ph.D.; [EMAIL PROTECTED] Phone: 703 361 4751 Cell: 703 919-9623 http://virtualschool.edu
RE: ServerSocket not being closed properly.
On Tue, 24 Apr 2001, Brad Cox PhD wrote: At 7:19 PM -0700 04/23/2001, [EMAIL PROTECTED] wrote: On Mon, 23 Apr 2001, Arun Katkere wrote: In general you need to do something to unblock the accept thread, and 3.2 doesn't have this in. Yes, I remember now. You're absolutely right. You need serverSocket.setSoTimeout() to break the accept periodically. Here's how I did it in my app. Hi Brad, Yes, I remember about setSoTimeout() - I never liked that solution. If you set it to 5 min then stop() may take up to 5 minutes ( since it has to wait for the accept() socket to timeout). Multiply by 3 sockets... ( well, on average is probably half ). Anyway - a cleaner solution ( IMHO ) is to just set stoped and do a bogus connection. That's what I did in 3.3 - and seems to work fine. The module creating the socket can do that easily - and I think it's much cleaner than periodically breaking accept() ( and gives fast response, without having to wait for the timeout to stop ) Costin Notice the comment: apparently I got this from an early version of Tomcat. public void run() { if (serverSocket != null) // original is server { isListening = true; while(isListening) { try { Socket clientSocket = serverSocket.accept(); SocketServer clone = (SocketServer)clone(); clone.serverSocket = null; clone.clientSocket = clientSocket; clone.thread = new Thread(clone, name+Clone); clone.thread.start(); } catch (InterruptedIOException e) { /** * Ignore periodic SO_TIMEOUT interrupts * Without this the accept call never returns when the serversocket * is closed, and all subsequent runs fail with port 8082 busy. * I found this in the Tomcat http server code. */ } catch (Throwable e) { e.printStackTrace(); isListening = false; } } } else run(clientSocket); } void startServer(int port) throws UserFault { if (thread == null) { try { serverSocket = new ServerSocket(port); serverSocket.setSoTimeout(WAKEUP_INTERVAL); } catch (IOException e) { throw UserFault.errEnablerPortBusy(port); } thread = new Thread(this, name+Master); isListening = true; thread.start(); } }
RE: ServerSocket not being closed properly.
At 7:23 AM -0700 04/24/2001, [EMAIL PROTECTED] wrote: Anyway - a cleaner solution ( IMHO ) is to just set stoped and do a bogus connection. That's what I did in 3.3 - and seems to work fine. That does sound better. I really hope this gets nailed ASAP. I suspect the present configuration complexity, exacerbated by the lack of configuration validation, could be fixed with a simple gui. This might go far towards turning around the bad press Tomcat has been getting of late, but this problem is fatal to gui wrappers. -- --- Brad Cox, Ph.D.; [EMAIL PROTECTED] Phone: 703 361 4751 Cell: 703 919-9623 http://virtualschool.edu
RE: ServerSocket not being closed properly.
On Tue, 24 Apr 2001, Brad Cox wrote: At 7:23 AM -0700 04/24/2001, [EMAIL PROTECTED] wrote: Anyway - a cleaner solution ( IMHO ) is to just set stoped and do a bogus connection. That's what I did in 3.3 - and seems to work fine. That does sound better. I really hope this gets nailed ASAP. I suspect the present configuration complexity, exacerbated by the lack of configuration validation, could be fixed with a simple gui. There are few ideas that can be used for configuration validation, and the best ( IMHO ) is to run the sanity test after every change in the config file. ( maybe watchdog too ). In 3.3 we package all the tests as self-contained wars, and the admin has a web-based runner - but it needs more polishing to make it really easy to use. I don't think anything else will work - XML validation doesn't help too much ( since tomcat is a collection of modules - and the user can add any custom module, the problem is to validate that the configured collection of modules works fine ) We could also do small smog-tests at startup ( few internal requests, etc), but that's not too good ( affects tomcat on each startup, and it's not complete anyway ). Regarding the configuration complexity - the main problem is the fact that in few cases the module order is important ( this is true for Apache 1.3 also, and Apache2.0 improves a bit with the new position parameter). Tomcat 3.3 takes a similar aproach with Apache2.0, by letting the module register itself in the right position in each chain - the current architecture should provide all the needed elements. The only problem is that each module must be modified to take advantage of the new API, and this takes time ( and it's not a top priority - fixing the existing bugs and releasing a stable 3.3.0 is more important IMHO ). BTW, 3.3 also has a (reasonably) well defined state, that should allow restart, adding/removing of configs, etc. Since the connectors are pluged in as regular modules, the architecture allow them to reconfigure the server ( either by config re-generation as in the current code, or by automaticly sending the config via ajp14 as proposed ). Again - the modules must take advantage of that, and it takes time and work. Most of the effort has been put into the lower-level architecure and modularity - and not in individual modules. The idea is that in time we can rewrite individual modules ( for example the mapper is a big target for optimizations, etc ), and improve various spots. This might go far towards turning around the bad press Tomcat has been getting of late, but this problem is fatal to gui wrappers. Well, the bad press is right in many aspects - we do need an installer and better admin gui. At least on Linux the RPM install does a lot of magic ( and can do even more, there are few ideas to improve it ), but a windows installer will do a lot. Fact is - we do improve - and that's what matters ( for me ). I don't think anyone claims the first versions of apache were easy to install ( or even the latest ). Costin
RE: ServerSocket not being closed properly.
At 9:50 AM -0700 04/24/2001, [EMAIL PROTECTED] wrote: here are few ideas that can be used for configuration validation, and the best ( IMHO ) is to run the sanity test after every change in the config file. ( maybe watchdog too ). In 3.3 we package all the tests as self-contained wars, and the admin has a web-based runner - but it needs more polishing to make it really easy to use. That's roughly how I meant for a gui to work. A few text boxes for options every novice must touch and run the tests automatically on save. Novice-only stuff to make sure it runs out-of-box; eexperts will dicker the config files directly. Regarding the configuration complexity - the main problem is the fact that in few cases the module order is important ( this is true for Apache 1.3 also, and Apache2.0 improves a bit with the new position parameter). This may be a big problem, but its not the main one for mortals. XML validation only ensures that the configs are syntactically correct. Without semantic validation (like your test suite could provide), tomcat reports common errors, mispelling a context name, classpath problems, etc, by throwing NullPointerExceptions and the like from very low level code. Usually the stack trace provides no way of connecting the error with the config error that is causing it. I seem to get bitten by a half dozen or so variations on this theme every time I install a new release, which involves a week of frustrated guessing each time. The only solution I've found is to load the Tomcat sources into Visual Age and treating each release as a low-level debugging exercise. Most of the effort has been put into the lower-level architecure and modularity - and not in individual modules. The idea is that in time we can rewrite individual modules ( for example the mapper is a big target for optimizations, etc ), and improve various spots. That's about repairing/redesigning the bowels of the mine. I'm saying tomcat needs some work on the sales office. Its not either-or; both need work. Fact is - we do improve - and that's what matters ( for me ). I don't think anyone claims the first versions of apache were easy to install ( or even the latest ). Indeed! And thanks for listening! -- --- Brad Cox, Ph.D.; [EMAIL PROTECTED] Phone: 703 361 4751 Cell: 703 919-9623 http://virtualschool.edu
RE: ServerSocket not being closed properly.
On Tue, 24 Apr 2001, Brad Cox wrote: In 3.3 we package all the tests as self-contained wars, and the admin has a web-based runner - but it needs more polishing to make it really easy to use. That's roughly how I meant for a gui to work. A few text boxes for options every novice must touch and run the tests automatically on save. Novice-only stuff to make sure it runs out-of-box; eexperts will dicker the config files directly. I fully agree - the /admin provides few informations and services, but it's user interface is very bad ( and not only from a graphical point of view ), and incomplete. I do add new pages and features - every time I have some time - but it needs much more. Probably someday I'll start a major refactoring for /admin - at least separate the server side and the ui, clean up the taglibs, etc. For a non-web-based GUI it should be possible to control tomcat via URL requests ( or direct calls ). Regarding the configuration complexity - the main problem is the fact that in few cases the module order is important ( this is true for Apache 1.3 also, and Apache2.0 improves a bit with the new position parameter). This may be a big problem, but its not the main one for mortals. XML validation only ensures that the configs are syntactically correct. Without semantic validation (like your test suite could provide), tomcat reports common errors, mispelling a context name, classpath problems, etc, by throwing NullPointerExceptions and the like from very low level code. Usually the stack trace provides no way of Agree - but remember this is open-source, with all it's benefits and problems. It would be nice to have better error messages - if someone would write the code ( or at least more docs ). Probably a good solution would be to stop using server.xml as a user-modifiable config file, and work on a GUI that will expose only a controled set of options. ( advanced users will still edit server.xml, but most users shouldn't touch it ). One way or another - tomcat is a collection of modules, like apache. The config file is not setting some tunnable parameters, but it's wiring up the whole tomcat. It has a lot of power - but it's probably not the best thing for users. Most of the effort has been put into the lower-level architecure and modularity - and not in individual modules. The idea is that in time we can rewrite individual modules ( for example the mapper is a big target for optimizations, etc ), and improve various spots. That's about repairing/redesigning the bowels of the mine. I'm saying tomcat needs some work on the sales office. Its not either-or; both need work. Yes, but I can hardly find time for one. I would love to work on both - but so far I coulnd't find people to help on the /admin, and I'll not start it alone. ( well, Larry and few others helped a lot - but he seems to have even less free time than I have ). Fact is - we do improve - and that's what matters ( for me ). I don't think anyone claims the first versions of apache were easy to install ( or even the latest ). Indeed! And thanks for listening! Well, thanks for the feedback - and even more thanks if that leads to some code contributions. Costin
RE: ServerSocket not being closed properly.
At 12:49 PM -0700 04/24/2001, [EMAIL PROTECTED] wrote: Yes, but I can hardly find time for one. I would love to work on both - but so far I coulnd't find people to help on the /admin, and I'll not start it alone. ( well, Larry and few others helped a lot - but he seems to have even less free time than I have ). Fact is - we do improve - and that's what matters ( for me ). I don't think anyone claims the first versions of apache were easy to install ( or even the latest ). Indeed! And thanks for listening! Well, thanks for the feedback - and even more thanks if that leads to some code contributions. That's what I had in mind for the gui. Gotta stay focused on my app for now but this should be done real soon now. ;) -- --- Brad Cox, Ph.D.; [EMAIL PROTECTED] Phone: 703 361 4751 Cell: 703 919-9623 http://virtualschool.edu
RE: ServerSocket not being closed properly.
I think you have a lucky VM/OS - close() on the accepting socket doesn't stop the accept() thread ( at least not on Linux/JDK1.3 ). That's right on Linux Redhat 6.2 and glibc 2.1.x and IBM JDK 1.3. But it seems to work fine on Redhat 7.0 which use a glibc 2.2. But the fundamental step for the Linux community is kernel 2.4 found for example in Redhat 7.1, and I consider that Redhat 7.0 is just an interim release.
RE: ServerSocket not being closed properly.
In my experience (having started/stopped Tomcat engine programatically via ContextManager API in a loop 100s of times), server socket is always closed correctly. And looking at 3.2.2 beta 3 source code, both PoolTcpEndpoint and SimpleTcpEndpoint close the server socket during shutdownEndpoint(). BTW, doesn't your doStop() below kill the VM because there is a System.exit() in Ajp12ConnectionHandler shutdown? -arun ps: Each invocation leaves some threads running, which is bug 1418 (http://nagoya.apache.org/bugzilla/show_bug.cgi?id=1418), resolved for 3.3 (not 3.2.2). There is also some memory leak which I haven't had a chance to track down, yet. -Original Message- From: Brad Cox PhD [mailto:[EMAIL PROTECTED]] Sent: Monday, April 23, 2001 6:04 PM To: [EMAIL PROTECTED] Subject: ServerSocket not being closed properly. At 7:06 PM -0500 04/23/2001, Marc Saegesser wrote: I was just about to call the vote for the final release of Tomcat 3.2.2 ... While you're at it, could you ensure that tomcat closes its server socket instead of relying on the system to do it when the VM exits? This is a long-standing problem that interferes with running tomcat inside IBM's VisualAge, or (equivalently) building java GUIs for starting and stopping the server. Here's what I've been using in a GUI for starting and stopping tomcat. private void doStart(String[] args) { org.apache.tomcat.startup.Tomcat.main(args); } private void doStop() { String[] stopArgs = new String[] { -stop }; org.apache.tomcat.startup.Tomcat.main(stopArgs); } The buttons work the first time they're used. The start buttons fails the second times (either by the same GUI or by any other means during the same VisualAge session) because the server socket is still being held open by the lack of an explicit close. The only way I've found to clear the problem is to exit VisualAge altogether; a SLOOO process. I've seen the same problem in my own applications. The fix was to be SURE that the ServerSocket is closed EXPLICITLY rather than leaving it to the operating system to do when the process exits. This session console log may help locate the problem. 2001-04-24 08:51:00 - ContextManager: Adding context Ctx( /examples ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /admin ) 2001-04-24 08:51:01 - Ctx( /svlt ): Set debug to 9 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /svlt ) Starting tomcat. Check logs/tomcat.log for error messages 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /test ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /digiprop ) 2001-04-24 08:51:02 - Ctx( /svlt ): XmlReader - init /svlt /digiprop 2001-04-24 08:51:02 - Ctx( /svlt ): Reading /digiprop/WEB-INF/web.xml 2001-04-24 08:51:02 - Ctx( /svlt ): Loading -2147483646 jsp 2001-04-24 08:51:02 - Ctx( /svlt ): Loading 1 flush 2001-04-24 08:51:03 - Ctx( /svlt ): Loading 1 page 2001-04-24 08:51:03 - Ctx( /svlt ): Loading 1 login FATAL:java.net.SocketException: Address already in use java.net.SocketException: Address already in use java.lang.Throwable(java.lang.String) java.lang.Exception(java.lang.String) java.io.IOException(java.lang.String) java.net.SocketException(java.lang.String) void java.net.PlainSocketImpl.socketBind(java.net.InetAddress, int) void java.net.PlainSocketImpl.bind(java.net.InetAddress, int) java.net.ServerSocket(int, int, java.net.InetAddress) java.net.ServerSocket(int, int) java.net.ServerSocket org.apache.tomcat.net.DefaultServerSocketFactory.createSocket(int, int) void org.apache.tomcat.service.PoolTcpEndpoint.startEndpoint() void org.apache.tomcat.service.PoolTcpConnector.start() void org.apache.tomcat.core.ContextManager.start() void org.apache.tomcat.startup.Tomcat.execute(java.lang.String []) void org.apache.tomcat.startup.Tomcat.main(java.lang.String []) void digiprop.site.TomcatView.doStart() void digiprop.site.TomcatView.connEtoC2(java.awt.event.ActionEvent) void digiprop.site.TomcatView$IvjEventHandler.actionPerformed(java. awt.event.ActionEvent) void java.awt.Button.processActionEvent(java.awt.event.ActionEvent) void java.awt.Button.processEvent(java.awt.AWTEvent) void java.awt.Component.dispatchEventImpl(java.awt.AWTEvent) void java.awt.Component.dispatchEvent(java.awt.AWTEvent) void java.awt.EventDispatchThread.run() -- --- Brad Cox, Ph.D.; [EMAIL PROTECTED] Phone: 703 361 4751 Cell: 703 919-9623 http://virtualschool.edu
Re: ServerSocket not being closed properly.
Fixed for 3.3, I'm not sure it's very easy for 3.2.2. The threads are waiting in accept, so one solution is to set stopped and make a dummy connection. The problem is that there are few places that need to be fixed to support stop/start ( another bug was that logger and session expirer threads don't stop ). It may be a bit too much for 3.2.2, but probably can be done for an eventual 3.2.3 if it's important. Costin On Mon, 23 Apr 2001, Brad Cox PhD wrote: At 7:06 PM -0500 04/23/2001, Marc Saegesser wrote: I was just about to call the vote for the final release of Tomcat 3.2.2 ... While you're at it, could you ensure that tomcat closes its server socket instead of relying on the system to do it when the VM exits? This is a long-standing problem that interferes with running tomcat inside IBM's VisualAge, or (equivalently) building java GUIs for starting and stopping the server. Here's what I've been using in a GUI for starting and stopping tomcat. private void doStart(String[] args) { org.apache.tomcat.startup.Tomcat.main(args); } private void doStop() { String[] stopArgs = new String[] { -stop }; org.apache.tomcat.startup.Tomcat.main(stopArgs); } The buttons work the first time they're used. The start buttons fails the second times (either by the same GUI or by any other means during the same VisualAge session) because the server socket is still being held open by the lack of an explicit close. The only way I've found to clear the problem is to exit VisualAge altogether; a SLOOO process. I've seen the same problem in my own applications. The fix was to be SURE that the ServerSocket is closed EXPLICITLY rather than leaving it to the operating system to do when the process exits. This session console log may help locate the problem. 2001-04-24 08:51:00 - ContextManager: Adding context Ctx( /examples ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /admin ) 2001-04-24 08:51:01 - Ctx( /svlt ): Set debug to 9 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /svlt ) Starting tomcat. Check logs/tomcat.log for error messages 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /test ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /digiprop ) 2001-04-24 08:51:02 - Ctx( /svlt ): XmlReader - init /svlt /digiprop 2001-04-24 08:51:02 - Ctx( /svlt ): Reading /digiprop/WEB-INF/web.xml 2001-04-24 08:51:02 - Ctx( /svlt ): Loading -2147483646 jsp 2001-04-24 08:51:02 - Ctx( /svlt ): Loading 1 flush 2001-04-24 08:51:03 - Ctx( /svlt ): Loading 1 page 2001-04-24 08:51:03 - Ctx( /svlt ): Loading 1 login FATAL:java.net.SocketException: Address already in use java.net.SocketException: Address already in use java.lang.Throwable(java.lang.String) java.lang.Exception(java.lang.String) java.io.IOException(java.lang.String) java.net.SocketException(java.lang.String) void java.net.PlainSocketImpl.socketBind(java.net.InetAddress, int) void java.net.PlainSocketImpl.bind(java.net.InetAddress, int) java.net.ServerSocket(int, int, java.net.InetAddress) java.net.ServerSocket(int, int) java.net.ServerSocket org.apache.tomcat.net.DefaultServerSocketFactory.createSocket(int, int) void org.apache.tomcat.service.PoolTcpEndpoint.startEndpoint() void org.apache.tomcat.service.PoolTcpConnector.start() void org.apache.tomcat.core.ContextManager.start() void org.apache.tomcat.startup.Tomcat.execute(java.lang.String []) void org.apache.tomcat.startup.Tomcat.main(java.lang.String []) void digiprop.site.TomcatView.doStart() void digiprop.site.TomcatView.connEtoC2(java.awt.event.ActionEvent) void digiprop.site.TomcatView$IvjEventHandler.actionPerformed(java.awt.event.ActionEvent) void java.awt.Button.processActionEvent(java.awt.event.ActionEvent) void java.awt.Button.processEvent(java.awt.AWTEvent) void java.awt.Component.dispatchEventImpl(java.awt.AWTEvent) void java.awt.Component.dispatchEvent(java.awt.AWTEvent) void java.awt.EventDispatchThread.run()
RE: ServerSocket not being closed properly.
At 6:37 PM -0700 04/23/2001, Arun Katkere wrote: In my experience (having started/stopped Tomcat engine programatically via ContextManager API in a loop 100s of times), server socket is always closed correctly. And looking at 3.2.2 beta 3 source code, both PoolTcpEndpoint and SimpleTcpEndpoint close the server socket during shutdownEndpoint(). Could you provide sample code? Better yet, an explanation for the symptoms I provided? I'm inferring the cause but the symptoms are 100% rock solid. BTW, doesn't your doStop() below kill the VM because there is a System.exit() in Ajp12ConnectionHandler shutdown? It does kill the GUI, but System.exit() doesn't kill VisualAge. Hadnn't dug into this gui problem because the gui is useless after doStop anyway. ps: Each invocation leaves some threads running, which is bug 1418 (http://nagoya.apache.org/bugzilla/show_bug.cgi?id=1418), resolved for 3.3 (not 3.2.2). There is also some memory leak which I haven't had a chance to track down, yet. -Original Message- From: Brad Cox PhD [mailto:[EMAIL PROTECTED]] Sent: Monday, April 23, 2001 6:04 PM To: [EMAIL PROTECTED] Subject: ServerSocket not being closed properly. At 7:06 PM -0500 04/23/2001, Marc Saegesser wrote: I was just about to call the vote for the final release of Tomcat 3.2.2 ... While you're at it, could you ensure that tomcat closes its server socket instead of relying on the system to do it when the VM exits? This is a long-standing problem that interferes with running tomcat inside IBM's VisualAge, or (equivalently) building java GUIs for starting and stopping the server. Here's what I've been using in a GUI for starting and stopping tomcat. private void doStart(String[] args) { org.apache.tomcat.startup.Tomcat.main(args); } private void doStop() { String[] stopArgs = new String[] { -stop }; org.apache.tomcat.startup.Tomcat.main(stopArgs); } The buttons work the first time they're used. The start buttons fails the second times (either by the same GUI or by any other means during the same VisualAge session) because the server socket is still being held open by the lack of an explicit close. The only way I've found to clear the problem is to exit VisualAge altogether; a SLOOO process. I've seen the same problem in my own applications. The fix was to be SURE that the ServerSocket is closed EXPLICITLY rather than leaving it to the operating system to do when the process exits. This session console log may help locate the problem. 2001-04-24 08:51:00 - ContextManager: Adding context Ctx( /examples ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /admin ) 2001-04-24 08:51:01 - Ctx( /svlt ): Set debug to 9 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /svlt ) Starting tomcat. Check logs/tomcat.log for error messages 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /test ) 2001-04-24 08:51:01 - ContextManager: Adding context Ctx( /digiprop ) 2001-04-24 08:51:02 - Ctx( /svlt ): XmlReader - init /svlt /digiprop 2001-04-24 08:51:02 - Ctx( /svlt ): Reading /digiprop/WEB-INF/web.xml 2001-04-24 08:51:02 - Ctx( /svlt ): Loading -2147483646 jsp 2001-04-24 08:51:02 - Ctx( /svlt ): Loading 1 flush 2001-04-24 08:51:03 - Ctx( /svlt ): Loading 1 page 2001-04-24 08:51:03 - Ctx( /svlt ): Loading 1 login FATAL:java.net.SocketException: Address already in use java.net.SocketException: Address already in use java.lang.Throwable(java.lang.String) java.lang.Exception(java.lang.String) java.io.IOException(java.lang.String) java.net.SocketException(java.lang.String) void java.net.PlainSocketImpl.socketBind(java.net.InetAddress, int) void java.net.PlainSocketImpl.bind(java.net.InetAddress, int) java.net.ServerSocket(int, int, java.net.InetAddress) java.net.ServerSocket(int, int) java.net.ServerSocket org.apache.tomcat.net.DefaultServerSocketFactory.createSocket(int, int) void org.apache.tomcat.service.PoolTcpEndpoint.startEndpoint() void org.apache.tomcat.service.PoolTcpConnector.start() void org.apache.tomcat.core.ContextManager.start() void org.apache.tomcat.startup.Tomcat.execute(java.lang.String []) void org.apache.tomcat.startup.Tomcat.main(java.lang.String []) void digiprop.site.TomcatView.doStart() void digiprop.site.TomcatView.connEtoC2(java.awt.event.ActionEvent) void digiprop.site.TomcatView$IvjEventHandler.actionPerformed(java. awt.event.ActionEvent) void java.awt.Button.processActionEvent(java.awt.event.ActionEvent) void java.awt.Button.processEvent(java.awt.AWTEvent) void java.awt.Component.dispatchEventImpl(java.awt.AWTEvent) void java.awt.Component.dispatchEvent(java.awt.AWTEvent) void java.awt.EventDispatchThread.run() -- --- Brad