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.lang.reflect.InvocationTargetException; 30 import java.net.ProtocolFamily; 31 import java.nio.channels.Channel; 32 import java.nio.channels.DatagramChannel; 33 import java.nio.channels.Pipe; 34 import java.nio.channels.ServerSocketChannel; 35 import java.nio.channels.SocketChannel; 36 import java.security.AccessController; 37 import java.security.PrivilegedAction; 38 import java.util.Iterator; 39 import java.util.Objects; 40 import java.util.ServiceLoader; 41 import java.util.ServiceConfigurationError; 42 43 /** 44 * Service-provider class for selectors and selectable channels. 45 * 46 * <p> A selector provider is a concrete subclass of this class that has a 47 * zero-argument constructor and implements the abstract methods specified 48 * below. A given invocation of the Java virtual machine maintains a single 49 * system-wide default provider instance, which is returned by the {@link 50 * #provider() provider} method. The first invocation of that method will locate 51 * the default provider as specified below. 52 * 53 * <p> The system-wide default provider is used by the static {@code open} 54 * methods of the {@link java.nio.channels.DatagramChannel#open 55 * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link 56 * java.nio.channels.Selector#open Selector}, {@link 57 * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link 58 * java.nio.channels.SocketChannel#open SocketChannel} classes. It is also 59 * used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()} 60 * method. A program may make use of a provider other than the default provider 61 * by instantiating that provider and then directly invoking the {@code open} 62 * methods defined in this class. 63 * 64 * <p> All of the methods in this class are safe for use by multiple concurrent 65 * threads. </p> 66 * 67 * 68 * @author Mark Reinhold 69 * @author JSR-51 Expert Group 70 * @since 1.4 71 */ 72 73 public abstract class SelectorProvider { 74 75 private static Void checkPermission() { 76 SecurityManager sm = System.getSecurityManager(); 77 if (sm != null) 78 sm.checkPermission(new RuntimePermission("selectorProvider")); 79 return null; 80 } 81 private SelectorProvider(Void ignore) { } 82 83 /** 84 * Initializes a new instance of this class. 85 * 86 * @throws SecurityException 87 * If a security manager has been installed and it denies 88 * {@link RuntimePermission}{@code ("selectorProvider")} 89 */ 90 protected SelectorProvider() { 91 this(checkPermission()); 92 } 93 94 private static class Holder { 95 static final SelectorProvider INSTANCE = provider(); 96 97 static SelectorProvider provider() { 98 PrivilegedAction<SelectorProvider> pa = () -> { 99 SelectorProvider sp; 100 if ((sp = loadProviderFromProperty()) != null) 101 return sp; 102 if ((sp = loadProviderAsService()) != null) 103 return sp; 104 return sun.nio.ch.DefaultSelectorProvider.get(); 105 }; 106 return AccessController.doPrivileged(pa); 107 } 108 109 private static SelectorProvider loadProviderFromProperty() { 110 String cn = System.getProperty("java.nio.channels.spi.SelectorProvider"); 111 if (cn == null) 112 return null; 113 try { 114 Class<?> clazz = Class.forName(cn, true, ClassLoader.getSystemClassLoader()); 115 return (SelectorProvider) clazz.getConstructor().newInstance(); 116 } catch (ClassNotFoundException | 117 NoSuchMethodException | 118 IllegalAccessException | 119 InvocationTargetException | 120 InstantiationException | 121 SecurityException x) { 122 throw new ServiceConfigurationError(null, x); 123 } 124 } 125 126 private static SelectorProvider loadProviderAsService() { 127 ServiceLoader<SelectorProvider> sl = 128 ServiceLoader.load(SelectorProvider.class, 129 ClassLoader.getSystemClassLoader()); 130 Iterator<SelectorProvider> i = sl.iterator(); 131 for (;;) { 132 try { 133 return i.hasNext() ? i.next() : null; 134 } catch (ServiceConfigurationError sce) { 135 if (sce.getCause() instanceof SecurityException) { 136 // Ignore the security exception, try the next provider 137 continue; 138 } 139 throw sce; 140 } 141 } 142 } 143 } 144 145 /** 146 * Returns the system-wide default selector provider for this invocation of 147 * the Java virtual machine. 148 * 149 * <p> The first invocation of this method locates the default provider 150 * object as follows: </p> 151 * 152 * <ol> 153 * 154 * <li><p> If the system property 155 * {@systemProperty java.nio.channels.spi.SelectorProvider} is defined 156 * then it is taken to be the fully-qualified name of a concrete provider 157 * class. The class is loaded and instantiated; if this process fails then 158 * an unspecified error is thrown. </p></li> 159 * 160 * <li><p> If a provider class has been installed in a jar file that is 161 * visible to the system class loader, and that jar file contains a 162 * provider-configuration file named 163 * {@code java.nio.channels.spi.SelectorProvider} in the resource 164 * directory {@code META-INF/services}, then the first class name 165 * specified in that file is taken. The class is loaded and 166 * instantiated; if this process fails then an unspecified error is 167 * thrown. </p></li> 168 * 169 * <li><p> Finally, if no provider has been specified by any of the above 170 * means then the system-default provider class is instantiated and the 171 * result is returned. </p></li> 172 * 173 * </ol> 174 * 175 * <p> Subsequent invocations of this method return the provider that was 176 * returned by the first invocation. </p> 177 * 178 * @return The system-wide default selector provider 179 */ 180 public static SelectorProvider provider() { 181 return Holder.INSTANCE; 182 } 183 184 /** 185 * Opens a datagram channel. 186 * 187 * @return The new channel 188 * 189 * @throws IOException 190 * If an I/O error occurs 191 */ 192 public abstract DatagramChannel openDatagramChannel() 193 throws IOException; 194 195 /** 196 * Opens a datagram channel. 197 * 198 * @param family 199 * The protocol family 200 * 201 * @return A new datagram channel 202 * 203 * @throws UnsupportedOperationException 204 * If the specified protocol family is not supported 205 * @throws IOException 206 * If an I/O error occurs 207 * 208 * @since 1.7 209 */ 210 public abstract DatagramChannel openDatagramChannel(ProtocolFamily family) 211 throws IOException; 212 213 /** 214 * Opens a pipe. 215 * 216 * @return The new pipe 217 * 218 * @throws IOException 219 * If an I/O error occurs 220 */ 221 public abstract Pipe openPipe() 222 throws IOException; 223 224 /** 225 * Opens a selector. 226 * 227 * @return The new selector 228 * 229 * @throws IOException 230 * If an I/O error occurs 231 */ 232 public abstract AbstractSelector openSelector() 233 throws IOException; 234 235 /** 236 * Opens a server-socket channel. 237 * 238 * @return The new channel 239 * 240 * @throws IOException 241 * If an I/O error occurs 242 */ 243 public abstract ServerSocketChannel openServerSocketChannel() 244 throws IOException; 245 246 /** 247 * Opens a socket channel. 248 * 249 * @return The new channel 250 * 251 * @throws IOException 252 * If an I/O error occurs 253 */ 254 public abstract SocketChannel openSocketChannel() 255 throws IOException; 256 257 /** 258 * Returns the channel inherited from the entity that created this 259 * Java virtual machine. 260 * 261 * <p> On many operating systems a process, such as a Java virtual 262 * machine, can be started in a manner that allows the process to 263 * inherit a channel from the entity that created the process. The 264 * manner in which this is done is system dependent, as are the 265 * possible entities to which the channel may be connected. For example, 266 * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to 267 * start programs to service requests when a request arrives on an 268 * associated network port. In this example, the process that is started, 269 * inherits a channel representing a network socket. 270 * 271 * <p> In cases where the inherited channel is for an <i>Internet protocol</i> 272 * socket then the {@link Channel Channel} type returned 273 * by this method is determined as follows: 274 * 275 * <ul> 276 * 277 * <li><p> If the inherited channel is for a stream-oriented connected 278 * socket then a {@link SocketChannel SocketChannel} is returned. The 279 * socket channel is, at least initially, in blocking mode, bound 280 * to a socket address, and connected to a peer. 281 * </p></li> 282 * 283 * <li><p> If the inherited channel is for a stream-oriented listening 284 * socket then a {@link ServerSocketChannel ServerSocketChannel} is returned. 285 * The server-socket channel is, at least initially, in blocking mode, 286 * and bound to a socket address. 287 * </p></li> 288 * 289 * <li><p> If the inherited channel is a datagram-oriented socket then a 290 * {@link DatagramChannel DatagramChannel} is returned. The datagram channel 291 * is, at least initially, in blocking mode, and bound to a socket address. 292 * </p></li> 293 * 294 * </ul> 295 * 296 * <p> In cases where the inherited channel is for a <i>Unix domain</i> 297 * socket then the {@link Channel} type returned is the same as for 298 * <i>Internet protocol</i> sockets as described above, except that 299 * datagram-oriented sockets are not supported. 300 * 301 * <p> In addition to the two types of socket just described, this method 302 * may return other types in the future. 303 * 304 * <p> The first invocation of this method creates the channel that is 305 * returned. Subsequent invocations of this method return the same 306 * channel. </p> 307 * 308 * @return The inherited channel, if any, otherwise {@code null}. 309 * 310 * @throws IOException 311 * If an I/O error occurs 312 * 313 * @throws SecurityException 314 * If a security manager has been installed and it denies 315 * {@link RuntimePermission}{@code ("inheritedChannel")} 316 * 317 * @since 1.5 318 */ 319 public Channel inheritedChannel() throws IOException { 320 return null; 321 } 322 323 /** 324 * Opens a socket channel. 325 * 326 * @implSpec The default implementation of this method first checks that 327 * the given protocol {@code family} is not {@code null}, 328 * then throws {@link UnsupportedOperationException}. 329 * 330 * @param family 331 * The protocol family 332 * 333 * @return The new channel 334 * 335 * @throws UnsupportedOperationException 336 * If the specified protocol family is not supported 337 * @throws IOException 338 * If an I/O error occurs 339 * 340 * @since 15 341 */ 342 public SocketChannel openSocketChannel(ProtocolFamily family) throws IOException { 343 Objects.requireNonNull(family); 344 throw new UnsupportedOperationException("Protocol family not supported"); 345 } 346 347 /** 348 * Opens a server-socket channel. 349 * 350 * @implSpec The default implementation of this method first checks that 351 * the given protocol {@code family} is not {@code null}, 352 * then throws {@link UnsupportedOperationException}. 353 * 354 * @param family 355 * The protocol family 356 * 357 * @return The new channel 358 * 359 * @throws UnsupportedOperationException 360 * If the specified protocol family is not supported 361 * @throws IOException 362 * If an I/O error occurs 363 * 364 * @since 15 365 */ 366 public ServerSocketChannel openServerSocketChannel(ProtocolFamily family) throws IOException { 367 Objects.requireNonNull(family); 368 throw new UnsupportedOperationException("Protocol family not supported"); 369 } 370 }