49 public class CloseServerSocketOnTermination { |
49 public class CloseServerSocketOnTermination { |
50 |
50 |
51 private static long TIMEOUT = 5000; |
51 private static long TIMEOUT = 5000; |
52 |
52 |
53 public static void main(String[] args) throws Exception { |
53 public static void main(String[] args) throws Exception { |
54 System.err.println("\nRegression test for bug 4924577\n"); |
54 System.err.println("\nRegression test for bug 4924577\n"); |
55 |
55 |
56 RMISocketFactory.setFailureHandler(new RMIFailureHandler() { |
56 RMISocketFactory.setFailureHandler(new RMIFailureHandler() { |
57 public boolean failure(Exception e) { return false; } |
57 public boolean failure(Exception e) { return false; } |
58 }); |
58 }); |
59 |
59 |
60 tryWith(new IOException()); |
60 tryWith(new IOException()); |
61 tryWith(new NullPointerException()); |
61 tryWith(new NullPointerException()); |
62 tryWith(new OutOfMemoryError()); |
62 tryWith(new OutOfMemoryError()); |
63 tryWith(new NoClassDefFoundError()); |
63 tryWith(new NoClassDefFoundError()); |
64 tryWith(new InternalError()); |
64 tryWith(new InternalError()); |
65 tryWith(new Throwable()); |
65 tryWith(new Throwable()); |
66 |
66 |
67 System.err.println("TEST PASSED"); |
67 System.err.println("TEST PASSED"); |
68 } |
68 } |
69 |
69 |
70 private static void tryWith(Throwable t) throws Exception { |
70 private static void tryWith(Throwable t) throws Exception { |
71 Remote impl = new Remote() { }; |
71 Remote impl = new Remote() { }; |
72 try { |
72 try { |
73 CountDownLatch latch = new CountDownLatch(1); |
73 CountDownLatch latch = new CountDownLatch(1); |
74 UnicastRemoteObject.exportObject(impl, 0, null, new SSF(t, latch)); |
74 UnicastRemoteObject.exportObject(impl, 0, null, new SSF(t, latch)); |
75 if (!latch.await(TIMEOUT, TimeUnit.MILLISECONDS)) { |
75 if (!latch.await(TIMEOUT, TimeUnit.MILLISECONDS)) { |
76 throw new Error("server socket not closed"); |
76 throw new Error("server socket not closed"); |
77 } |
77 } |
78 } finally { |
78 } finally { |
79 UnicastRemoteObject.unexportObject(impl, true); |
79 UnicastRemoteObject.unexportObject(impl, true); |
80 } |
80 } |
81 } |
81 } |
82 |
82 |
83 private static class SSF implements RMIServerSocketFactory { |
83 private static class SSF implements RMIServerSocketFactory { |
84 private final Throwable acceptFailure; |
84 private final Throwable acceptFailure; |
85 private final CountDownLatch closedLatch; |
85 private final CountDownLatch closedLatch; |
86 SSF(Throwable acceptFailure, CountDownLatch closedLatch) { |
86 SSF(Throwable acceptFailure, CountDownLatch closedLatch) { |
87 this.acceptFailure = acceptFailure; |
87 this.acceptFailure = acceptFailure; |
88 this.closedLatch = closedLatch; |
88 this.closedLatch = closedLatch; |
89 } |
89 } |
90 public ServerSocket createServerSocket(int port) throws IOException { |
90 public ServerSocket createServerSocket(int port) throws IOException { |
91 return new ServerSocket(port) { |
91 return new ServerSocket(port) { |
92 private int acceptInvocations = 0; |
92 private int acceptInvocations = 0; |
93 public synchronized Socket accept() throws IOException { |
93 public synchronized Socket accept() throws IOException { |
94 if (acceptInvocations++ == 0) { |
94 if (acceptInvocations++ == 0) { |
95 throwException(acceptFailure); |
95 throwException(acceptFailure); |
96 } |
96 } |
97 return super.accept(); |
97 return super.accept(); |
98 } |
98 } |
99 public void close() throws IOException { |
99 public void close() throws IOException { |
100 closedLatch.countDown(); |
100 closedLatch.countDown(); |
101 super.close(); |
101 super.close(); |
102 } |
102 } |
103 }; |
103 }; |
104 } |
104 } |
105 |
105 |
106 // hack to throw an arbitrary (possibly checked) Throwable |
106 // hack to throw an arbitrary (possibly checked) Throwable |
107 private static void throwException(Throwable t) { |
107 private static void throwException(Throwable t) { |
108 try { |
108 try { |
109 toThrow.set(t); |
109 toThrow.set(t); |
110 Thrower.class.newInstance(); |
110 Thrower.class.newInstance(); |
111 } catch (IllegalAccessException e) { |
111 } catch (IllegalAccessException e) { |
112 throw new AssertionError(); |
112 throw new AssertionError(); |
113 } catch (InstantiationException e) { |
113 } catch (InstantiationException e) { |
114 throw new AssertionError(); |
114 throw new AssertionError(); |
115 } finally { |
115 } finally { |
116 toThrow.remove(); |
116 toThrow.remove(); |
117 } |
117 } |
118 } |
118 } |
119 private static ThreadLocal<Throwable> toThrow = |
119 private static ThreadLocal<Throwable> toThrow = |
120 new ThreadLocal<Throwable>(); |
120 new ThreadLocal<Throwable>(); |
121 private static class Thrower { |
121 private static class Thrower { |
122 Thrower() throws Throwable { throw toThrow.get(); } |
122 Thrower() throws Throwable { throw toThrow.get(); } |
123 } |
123 } |
124 } |
124 } |
125 } |
125 } |