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 * Opens a socket channel.
253 *
254 * @return The new channel
255 *
256 * @throws IOException
257 * If an I/O error occurs
258 */
259 public abstract SocketChannel openSocketChannel()
260 throws IOException;
261
262 /**
263 * Returns the channel inherited from the entity that created this
264 * Java virtual machine.
265 *
266 * <p> On many operating systems a process, such as a Java virtual
267 * machine, can be started in a manner that allows the process to
268 * inherit a channel from the entity that created the process. The
269 * manner in which this is done is system dependent, as are the
270 * possible entities to which the channel may be connected. For example,
271 * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to
272 * start programs to service requests when a request arrives on an
273 * associated network port. In this example, the process that is started,
274 * inherits a channel representing a network socket.
275 *
276 * <p> In cases where the inherited channel represents a network socket
277 * then the {@link java.nio.channels.Channel Channel} type returned
278 * by this method is determined as follows:
279 *
280 * <ul>
281 *
282 * <li><p> If the inherited channel represents a stream-oriented connected
283 * socket then a {@link java.nio.channels.SocketChannel SocketChannel} is
284 * returned. The socket channel is, at least initially, in blocking
285 * mode, bound to a socket address, and connected to a peer.
286 * </p></li>
287 *
288 * <li><p> If the inherited channel represents a stream-oriented listening
289 * socket then a {@link java.nio.channels.ServerSocketChannel
290 * ServerSocketChannel} is returned. The server-socket channel is, at
291 * least initially, in blocking mode, and bound to a socket address.
292 * </p></li>
293 *
294 * <li><p> If the inherited channel is a datagram-oriented socket
295 * then a {@link java.nio.channels.DatagramChannel DatagramChannel} is
296 * returned. The datagram channel is, at least initially, in blocking
297 * mode, and bound to a socket address.
298 * </p></li>
299 *
300 * </ul>
301 *
302 * <p> In addition to the network-oriented channels described, this method
303 * may return other kinds of channels in the future.
304 *
305 * <p> The first invocation of this method creates the channel that is
306 * returned. Subsequent invocations of this method return the same
307 * channel. </p>
308 *
309 * @return The inherited channel, if any, otherwise {@code null}.
310 *
311 * @throws IOException
312 * If an I/O error occurs
313 *
314 * @throws SecurityException
315 * If a security manager has been installed and it denies
316 * {@link RuntimePermission}{@code ("inheritedChannel")}
317 *
318 * @since 1.5
319 */
320 public Channel inheritedChannel() throws IOException {
321 return null;
322 }
323
324 }