1 /* 2 * Copyright (c) 2000, 2013, 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 checkPermission()74 private static Void checkPermission() { 75 SecurityManager sm = System.getSecurityManager(); 76 if (sm != null) 77 sm.checkPermission(new RuntimePermission("selectorProvider")); 78 return null; 79 } SelectorProvider(Void ignore)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 */ SelectorProvider()89 protected SelectorProvider() { 90 this(checkPermission()); 91 } 92 loadProviderFromProperty()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 loadProviderAsService()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 * {@code java.nio.channels.spi.SelectorProvider} is defined then it is 147 * taken to be the fully-qualified name of a concrete provider class. 148 * The class is loaded and instantiated; if this process fails then an 149 * 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 */ provider()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 } 325