1 /*
2 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.nio.channels.spi;
27
28 import java.io.IOException;
29 import java.net.ProtocolFamily;
30 import java.nio.channels.*;
31 import java.security.AccessController;
32 import java.security.PrivilegedAction;
33 import java.util.Iterator;
34 import java.util.ServiceLoader;
35 import java.util.ServiceConfigurationError;
36 import sun.security.action.GetPropertyAction;
37
38
39 /**
40 * Service-provider class for selectors and selectable channels.
41 *
42 * <p> A selector provider is a concrete subclass of this class that has a
43 * zero-argument constructor and implements the abstract methods specified
44 * below. A given invocation of the Java virtual machine maintains a single
45 * system-wide default provider instance, which is returned by the {@link
46 * #provider() provider} method. The first invocation of that method will locate
47 * the default provider as specified below.
48 *
49 * <p> The system-wide default provider is used by the static {@code open}
50 * methods of the {@link java.nio.channels.DatagramChannel#open
51 * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link
52 * java.nio.channels.Selector#open Selector}, {@link
53 * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link
54 * java.nio.channels.SocketChannel#open SocketChannel} classes. It is also
55 * used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()}
56 * method. A program may make use of a provider other than the default provider
57 * by instantiating that provider and then directly invoking the {@code open}
58 * methods defined in this class.
59 *
60 * <p> All of the methods in this class are safe for use by multiple concurrent
61 * threads. </p>
62 *
63 *
64 * @author Mark Reinhold
65 * @author JSR-51 Expert Group
66 * @since 1.4
67 */
68
69 public abstract class SelectorProvider {
70
71 private static final Object lock = new Object();
72 private static SelectorProvider provider = null;
73
74 private static Void checkPermission() {
75 SecurityManager sm = System.getSecurityManager();
76 if (sm != null)
77 sm.checkPermission(new RuntimePermission("selectorProvider"));
78 return null;
79 }
80 private SelectorProvider(Void ignore) { }
81
82 /**
83 * Initializes a new instance of this class.
84 *
85 * @throws SecurityException
86 * If a security manager has been installed and it denies
87 * {@link RuntimePermission}{@code ("selectorProvider")}
88 */
89 protected SelectorProvider() {
90 this(checkPermission());
91 }
92
93 private static boolean loadProviderFromProperty() {
94 String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
95 if (cn == null)
96 return false;
97 try {
98 @SuppressWarnings("deprecation")
99 Object tmp = Class.forName(cn, true,
100 ClassLoader.getSystemClassLoader()).newInstance();
101 provider = (SelectorProvider)tmp;
102 return true;
103 } catch (ClassNotFoundException x) {
104 throw new ServiceConfigurationError(null, x);
105 } catch (IllegalAccessException x) {
106 throw new ServiceConfigurationError(null, x);
107 } catch (InstantiationException x) {
108 throw new ServiceConfigurationError(null, x);
109 } catch (SecurityException x) {
110 throw new ServiceConfigurationError(null, x);
111 }
112 }
113
114 private static boolean loadProviderAsService() {
115
116 ServiceLoader<SelectorProvider> sl =
117 ServiceLoader.load(SelectorProvider.class,
118 ClassLoader.getSystemClassLoader());
119 Iterator<SelectorProvider> i = sl.iterator();
120 for (;;) {
121 try {
122 if (!i.hasNext())
123 return false;
124 provider = i.next();
125 return true;
126 } catch (ServiceConfigurationError sce) {
127 if (sce.getCause() instanceof SecurityException) {
128 // Ignore the security exception, try the next provider
129 continue;
130 }
131 throw sce;
132 }
133 }
134 }
135
136 /**
137 * Returns the system-wide default selector provider for this invocation of
138 * the Java virtual machine.
139 *
140 * <p> The first invocation of this method locates the default provider
141 * object as follows: </p>
142 *
143 * <ol>
144 *
145 * <li><p> If the system property
146 * {@systemProperty java.nio.channels.spi.SelectorProvider} is defined
147 * then it is taken to be the fully-qualified name of a concrete provider
148 * class. The class is loaded and instantiated; if this process fails then
149 * an unspecified error is thrown. </p></li>
150 *
151 * <li><p> If a provider class has been installed in a jar file that is
152 * visible to the system class loader, and that jar file contains a
153 * provider-configuration file named
154 * {@code java.nio.channels.spi.SelectorProvider} in the resource
155 * directory {@code META-INF/services}, then the first class name
156 * specified in that file is taken. The class is loaded and
157 * instantiated; if this process fails then an unspecified error is
158 * thrown. </p></li>
159 *
160 * <li><p> Finally, if no provider has been specified by any of the above
161 * means then the system-default provider class is instantiated and the
162 * result is returned. </p></li>
163 *
164 * </ol>
165 *
166 * <p> Subsequent invocations of this method return the provider that was
167 * returned by the first invocation. </p>
168 *
169 * @return The system-wide default selector provider
170 */
171 public static SelectorProvider provider() {
172 synchronized (lock) {
173 if (provider != null)
174 return provider;
175 return AccessController.doPrivileged(
176 new PrivilegedAction<>() {
177 public SelectorProvider run() {
178 if (loadProviderFromProperty())
179 return provider;
180 if (loadProviderAsService())
181 return provider;
182 provider = sun.nio.ch.DefaultSelectorProvider.create();
183 return provider;
184 }
185 });
186 }
187 }
188
189 /**
190 * Opens a datagram channel.
191 *
192 * @return The new channel
193 *
194 * @throws IOException
195 * If an I/O error occurs
196 */
197 public abstract DatagramChannel openDatagramChannel()
198 throws IOException;
199
200 /**
201 * Opens a datagram channel.
202 *
203 * @param family
204 * The protocol family
205 *
206 * @return A new datagram channel
207 *
208 * @throws UnsupportedOperationException
209 * If the specified protocol family is not supported
210 * @throws IOException
211 * If an I/O error occurs
212 *
213 * @since 1.7
214 */
215 public abstract DatagramChannel openDatagramChannel(ProtocolFamily family)
216 throws IOException;
217
218 /**
219 * Opens a pipe.
220 *
221 * @return The new pipe
222 *
223 * @throws IOException
224 * If an I/O error occurs
225 */
226 public abstract Pipe openPipe()
227 throws IOException;
228
229 /**
230 * Opens a selector.
231 *
232 * @return The new selector
233 *
234 * @throws IOException
235 * If an I/O error occurs
236 */
237 public abstract AbstractSelector openSelector()
238 throws IOException;
239
240 /**
241 * Opens a server-socket channel.
242 *
243 * @return The new channel
244 *
245 * @throws IOException
246 * If an I/O error occurs
247 */
248 public abstract ServerSocketChannel openServerSocketChannel()
249 throws IOException;
250
251 /**
252 *
253 * @param family The protocol family
254 *
255 * @return A new stream channel
256 *
257 * @throws IOException
258 * If an I/O error occurs
259 */
260 public abstract ServerSocketChannel openServerSocketChannel(ProtocolFamily family)
261 throws IOException;
262
263 /**
264 * Opens a socket channel.
265 *
266 * @return The new channel
267 *
268 * @throws IOException
269 * If an I/O error occurs
270 */
271 public abstract SocketChannel openSocketChannel()
272 throws IOException;
273
274 /**
275 * Opens a socket channel.
276 *
277 * @param family The protocol family
278 *
279 * @return The new channel
280 *
281 * @throws IOException
282 * If an I/O error occurs
283 */
284 public abstract SocketChannel openSocketChannel(ProtocolFamily family)
285 throws IOException;
286
287 /**
288 * Returns the channel inherited from the entity that created this
289 * Java virtual machine.
290 *
291 * <p> On many operating systems a process, such as a Java virtual
292 * machine, can be started in a manner that allows the process to
293 * inherit a channel from the entity that created the process. The
294 * manner in which this is done is system dependent, as are the
295 * possible entities to which the channel may be connected. For example,
296 * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to
297 * start programs to service requests when a request arrives on an
298 * associated network port. In this example, the process that is started,
299 * inherits a channel representing a network socket.
300 *
301 * <p> In cases where the inherited channel represents a network socket
302 * then the {@link java.nio.channels.Channel Channel} type returned
303 * by this method is determined as follows:
304 *
305 * <ul>
306 *
307 * <li><p> If the inherited channel represents a stream-oriented connected
308 * socket then a {@link java.nio.channels.SocketChannel SocketChannel} is
309 * returned. The socket channel is, at least initially, in blocking
310 * mode, bound to a socket address, and connected to a peer.
311 * </p></li>
312 *
313 * <li><p> If the inherited channel represents a stream-oriented listening
314 * socket then a {@link java.nio.channels.ServerSocketChannel
315 * ServerSocketChannel} is returned. The server-socket channel is, at
316 * least initially, in blocking mode, and bound to a socket address.
317 * </p></li>
318 *
319 * <li><p> If the inherited channel is a datagram-oriented socket
320 * then a {@link java.nio.channels.DatagramChannel DatagramChannel} is
321 * returned. The datagram channel is, at least initially, in blocking
322 * mode, and bound to a socket address.
323 * </p></li>
324 *
325 * </ul>
326 *
327 * <p> In addition to the network-oriented channels described, this method
328 * may return other kinds of channels in the future.
329 *
330 * <p> The first invocation of this method creates the channel that is
331 * returned. Subsequent invocations of this method return the same
332 * channel. </p>
333 *
334 * @return The inherited channel, if any, otherwise {@code null}.
335 *
336 * @throws IOException
337 * If an I/O error occurs
338 *
339 * @throws SecurityException
340 * If a security manager has been installed and it denies
341 * {@link RuntimePermission}{@code ("inheritedChannel")}
342 *
343 * @since 1.5
344 */
345 public Channel inheritedChannel() throws IOException {
346 return null;
347 }
348
349 }