1 /* 2 * Copyright (c) 2007, 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.nio.channels.*; 29 import java.io.IOException; 30 import java.util.Iterator; 31 import java.util.ServiceLoader; 32 import java.util.ServiceConfigurationError; 33 import java.util.concurrent.*; 34 import java.security.AccessController; 35 import java.security.PrivilegedAction; 36 37 /** 38 * Service-provider class for asynchronous channels. 39 * 40 * <p> An asynchronous channel provider is a concrete subclass of this class that 41 * has a zero-argument constructor and implements the abstract methods specified 42 * below. A given invocation of the Java virtual machine maintains a single 43 * system-wide default provider instance, which is returned by the {@link 44 * #provider() provider} method. The first invocation of that method will locate 45 * the default provider as specified below. 46 * 47 * <p> All of the methods in this class are safe for use by multiple concurrent 48 * threads. </p> 49 * 50 * @since 1.7 51 */ 52 53 public abstract class AsynchronousChannelProvider { checkPermission()54 private static Void checkPermission() { 55 SecurityManager sm = System.getSecurityManager(); 56 if (sm != null) 57 sm.checkPermission(new RuntimePermission("asynchronousChannelProvider")); 58 return null; 59 } AsynchronousChannelProvider(Void ignore)60 private AsynchronousChannelProvider(Void ignore) { } 61 62 /** 63 * Initializes a new instance of this class. 64 * 65 * @throws SecurityException 66 * If a security manager has been installed and it denies 67 * {@link RuntimePermission}{@code ("asynchronousChannelProvider")} 68 */ AsynchronousChannelProvider()69 protected AsynchronousChannelProvider() { 70 this(checkPermission()); 71 } 72 73 // lazy initialization of default provider 74 private static class ProviderHolder { 75 static final AsynchronousChannelProvider provider = load(); 76 load()77 private static AsynchronousChannelProvider load() { 78 return AccessController 79 .doPrivileged(new PrivilegedAction<>() { 80 public AsynchronousChannelProvider run() { 81 AsynchronousChannelProvider p; 82 p = loadProviderFromProperty(); 83 if (p != null) 84 return p; 85 p = loadProviderAsService(); 86 if (p != null) 87 return p; 88 return sun.nio.ch.DefaultAsynchronousChannelProvider.create(); 89 }}); 90 } 91 loadProviderFromProperty()92 private static AsynchronousChannelProvider loadProviderFromProperty() { 93 String cn = System.getProperty("java.nio.channels.spi.AsynchronousChannelProvider"); 94 if (cn == null) 95 return null; 96 try { 97 @SuppressWarnings("deprecation") 98 Object tmp = Class.forName(cn, true, 99 ClassLoader.getSystemClassLoader()).newInstance(); 100 return (AsynchronousChannelProvider)tmp; 101 } catch (ClassNotFoundException x) { 102 throw new ServiceConfigurationError(null, x); 103 } catch (IllegalAccessException x) { 104 throw new ServiceConfigurationError(null, x); 105 } catch (InstantiationException x) { 106 throw new ServiceConfigurationError(null, x); 107 } catch (SecurityException x) { 108 throw new ServiceConfigurationError(null, x); 109 } 110 } 111 loadProviderAsService()112 private static AsynchronousChannelProvider loadProviderAsService() { 113 ServiceLoader<AsynchronousChannelProvider> sl = 114 ServiceLoader.load(AsynchronousChannelProvider.class, 115 ClassLoader.getSystemClassLoader()); 116 Iterator<AsynchronousChannelProvider> i = sl.iterator(); 117 for (;;) { 118 try { 119 return (i.hasNext()) ? i.next() : null; 120 } catch (ServiceConfigurationError sce) { 121 if (sce.getCause() instanceof SecurityException) { 122 // Ignore the security exception, try the next provider 123 continue; 124 } 125 throw sce; 126 } 127 } 128 } 129 } 130 131 /** 132 * Returns the system-wide default asynchronous channel provider for this 133 * invocation of the Java virtual machine. 134 * 135 * <p> The first invocation of this method locates the default provider 136 * object as follows: </p> 137 * 138 * <ol> 139 * 140 * <li><p> If the system property 141 * {@code java.nio.channels.spi.AsynchronousChannelProvider} is defined 142 * then it is taken to be the fully-qualified name of a concrete provider class. 143 * The class is loaded and instantiated; if this process fails then an 144 * unspecified error is thrown. </p></li> 145 * 146 * <li><p> If a provider class has been installed in a jar file that is 147 * visible to the system class loader, and that jar file contains a 148 * provider-configuration file named 149 * {@code java.nio.channels.spi.AsynchronousChannelProvider} in the resource 150 * directory {@code META-INF/services}, then the first class name 151 * specified in that file is taken. The class is loaded and 152 * instantiated; if this process fails then an unspecified error is 153 * thrown. </p></li> 154 * 155 * <li><p> Finally, if no provider has been specified by any of the above 156 * means then the system-default provider class is instantiated and the 157 * result is returned. </p></li> 158 * 159 * </ol> 160 * 161 * <p> Subsequent invocations of this method return the provider that was 162 * returned by the first invocation. </p> 163 * 164 * @return The system-wide default AsynchronousChannel provider 165 */ 166 public static AsynchronousChannelProvider provider() { 167 return ProviderHolder.provider; 168 } 169 170 /** 171 * Constructs a new asynchronous channel group with a fixed thread pool. 172 * 173 * @param nThreads 174 * The number of threads in the pool 175 * @param threadFactory 176 * The factory to use when creating new threads 177 * 178 * @return A new asynchronous channel group 179 * 180 * @throws IllegalArgumentException 181 * If {@code nThreads <= 0} 182 * @throws IOException 183 * If an I/O error occurs 184 * 185 * @see AsynchronousChannelGroup#withFixedThreadPool 186 */ 187 public abstract AsynchronousChannelGroup 188 openAsynchronousChannelGroup(int nThreads, ThreadFactory threadFactory) throws IOException; 189 190 /** 191 * Constructs a new asynchronous channel group with the given thread pool. 192 * 193 * @param executor 194 * The thread pool 195 * @param initialSize 196 * A value {@code >=0} or a negative value for implementation 197 * specific default 198 * 199 * @return A new asynchronous channel group 200 * 201 * @throws IOException 202 * If an I/O error occurs 203 * 204 * @see AsynchronousChannelGroup#withCachedThreadPool 205 */ 206 public abstract AsynchronousChannelGroup 207 openAsynchronousChannelGroup(ExecutorService executor, int initialSize) throws IOException; 208 209 /** 210 * Opens an asynchronous server-socket channel. 211 * 212 * @param group 213 * The group to which the channel is bound, or {@code null} to 214 * bind to the default group 215 * 216 * @return The new channel 217 * 218 * @throws IllegalChannelGroupException 219 * If the provider that created the group differs from this provider 220 * @throws ShutdownChannelGroupException 221 * The group is shutdown 222 * @throws IOException 223 * If an I/O error occurs 224 */ 225 public abstract AsynchronousServerSocketChannel openAsynchronousServerSocketChannel 226 (AsynchronousChannelGroup group) throws IOException; 227 228 /** 229 * Opens an asynchronous socket channel. 230 * 231 * @param group 232 * The group to which the channel is bound, or {@code null} to 233 * bind to the default group 234 * 235 * @return The new channel 236 * 237 * @throws IllegalChannelGroupException 238 * If the provider that created the group differs from this provider 239 * @throws ShutdownChannelGroupException 240 * The group is shutdown 241 * @throws IOException 242 * If an I/O error occurs 243 */ 244 public abstract AsynchronousSocketChannel openAsynchronousSocketChannel 245 (AsynchronousChannelGroup group) throws IOException; 246 } 247