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 represents a network socket 272 * then the {@link java.nio.channels.Channel Channel} type returned 273 * by this method is determined as follows: 274 * 275 * <ul> 276 * 277 * <li><p> If the inherited channel represents a stream-oriented connected 278 * socket then a {@link java.nio.channels.SocketChannel SocketChannel} is 279 * returned. The socket channel is, at least initially, in blocking 280 * mode, bound to a socket address, and connected to a peer. 281 * </p></li> 282 * 283 * <li><p> If the inherited channel represents a stream-oriented listening 284 * socket then a {@link java.nio.channels.ServerSocketChannel 285 * ServerSocketChannel} is returned. The server-socket channel is, at 286 * least initially, in blocking mode, and bound to a socket address. 287 * </p></li> 288 * 289 * <li><p> If the inherited channel is a datagram-oriented socket 290 * then a {@link java.nio.channels.DatagramChannel DatagramChannel} is 291 * returned. The datagram channel is, at least initially, in blocking 292 * mode, and bound to a socket address. 293 * </p></li> 294 * 295 * </ul> 296 * 297 * <p> In addition to the network-oriented channels described, this method 298 * may return other kinds of channels in the future. 299 * 300 * <p> The first invocation of this method creates the channel that is 301 * returned. Subsequent invocations of this method return the same 302 * channel. </p> 303 * 304 * @return The inherited channel, if any, otherwise {@code null}. 305 * 306 * @throws IOException 307 * If an I/O error occurs 308 * 309 * @throws SecurityException 310 * If a security manager has been installed and it denies 311 * {@link RuntimePermission}{@code ("inheritedChannel")} 312 * 313 * @since 1.5 314 */ 315 public Channel inheritedChannel() throws IOException { 316 return null; 317 } 318 319 /** 320 * Opens a socket channel. 321 * 322 * @implSpec The default implementation of this method first checks that 323 * the given protocol {@code family} is not {@code null}, 324 * then throws {@link UnsupportedOperationException}. 325 * 326 * @param family 327 * The protocol family 328 * 329 * @return The new channel 330 * 331 * @throws UnsupportedOperationException 332 * If the specified protocol family is not supported 333 * @throws IOException 334 * If an I/O error occurs 335 * 336 * @since 15 337 */ 338 public SocketChannel openSocketChannel(ProtocolFamily family) throws IOException { 339 Objects.requireNonNull(family); 340 throw new UnsupportedOperationException("Protocol family not supported"); 341 } 342 343 /** 344 * Opens a server-socket channel. 345 * 346 * @implSpec The default implementation of this method first checks that 347 * the given protocol {@code family} is not {@code null}, 348 * then throws {@link UnsupportedOperationException}. 349 * 350 * @param family 351 * The protocol family 352 * 353 * @return The new channel 354 * 355 * @throws UnsupportedOperationException 356 * If the specified protocol family is not supported 357 * @throws IOException 358 * If an I/O error occurs 359 * 360 * @since 15 361 */ 362 public ServerSocketChannel openServerSocketChannel(ProtocolFamily family) throws IOException { 363 Objects.requireNonNull(family); 364 throw new UnsupportedOperationException("Protocol family not supported"); 365 } 366 }