adamfisk/LittleProxy — pull request #140 by infofinity (2014-04-09 22:28:43+00:00)
Title: Throw an exception during server bind if it fails.

Creating a proxy server like so:

DefaultHttpProxyServer.bootstrap()
.withPort(port)
.withListenOnAllAddresses(true)
.withAllowLocalOnly(false)
.withFiltersSource(new LittleproxyExtensions())
.withConnectTimeout(config.getHttpClientConnectTimeout())
.start();

If the address is already in use, there was no BindException thrown. Tracked it down to the doStart call in DefaultHttpProxyServer seemingly not checking for failure on the bind. Not sure if the proposed solution is the best or correct way. Decided to just throw a RuntimeException because otherwise the start method signature would need to add throws Throwable and that would break existing code that overrides it.

Example run with the new code:

2014-04-09 15:26:41,636 INFO [main] Starting proxy at address: 0.0.0.0/0.0.0.0:8080 - [impl.DefaultHttpProxyServer.start (DefaultHttpProxyServer.java:281)]
2014-04-09 15:26:41,639 INFO [main] Proxy listening with TCP transport - [impl.DefaultHttpProxyServer.doStart (DefaultHttpProxyServer.java:310)]
2014-04-09 15:26:41,704 ERROR [main] Error in main - [proxy.BaseProxyServer.run (BaseProxyServer.java:54)]
java.lang.RuntimeException: java.net.BindException: Address already in use
at org.littleshoot.proxy.impl.DefaultHttpProxyServer.doStart(DefaultHttpProxyServer.java:339)
at org.littleshoot.proxy.impl.DefaultHttpProxyServer.start(DefaultHttpProxyServer.java:285)
at org.littleshoot.proxy.impl.DefaultHttpProxyServer.access$1400(DefaultHttpProxyServer.java:81)
at org.littleshoot.proxy.impl.DefaultHttpProxyServer$DefaultHttpProxyServerBootstrap.start(DefaultHttpProxyServer.java:753)
at com.test.proxy.littleproxy.Server.startServer(Server.java:50)
at com.test.proxy.BaseProxyServer.run(BaseProxyServer.java:48)
at com.test.proxy.littleproxy.Server.main(Server.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:344)
at sun.nio.ch.Net.bind(Net.java:336)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:199)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:102)
at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:479)
at io.netty.channel.DefaultChannelPipeline$HeadHandler.bind(DefaultChannelPipeline.java:1000)
at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:457)
at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:442)
at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:842)
at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:194)
at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:338)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:722)
2014-04-09 15:26:41,707 INFO [Thread-7] Shutting down proxy - [impl.DefaultHttpProxyServer.stop (DefaultHttpProxyServer.java:487)]
2014-04-09 15:26:41,707 INFO [Thread-7] Closing all channels... - [impl.DefaultHttpProxyServer.stop (DefaultHttpProxyServer.java:493)]
2014-04-09 15:26:41,714 INFO [Thread-7] Shutting down event loops - [impl.DefaultHttpProxyServer.stop (DefaultHttpProxyServer.java:511)]
2014-04-09 15:26:43,934 INFO [Thread-7] Done shutting down proxy - [impl.DefaultHttpProxyServer.stop (DefaultHttpProxyServer.java:530)]

Process finished with exit code 1