Fri, 11 Dec 2009 14:26:27 -0800
6906175: bridge JSR199 and JSR 203 APIs
Reviewed-by: darcy, alanb
1.1 --- a/make/build.properties Thu Dec 10 20:35:31 2009 -0800 1.2 +++ b/make/build.properties Fri Dec 11 14:26:27 2009 -0800 1.3 @@ -149,11 +149,26 @@ 1.4 # 1.5 1.6 # The following files require the import JDK to be available 1.7 -require.import.jdk.files = 1.8 +require.import.jdk.files = \ 1.9 + com/sun/tools/javac/nio/*.java 1.10 1.11 # The following files in the import jdk source directory are required 1.12 # in order to compile the files defined in ${require.import.jdk.files} 1.13 -import.jdk.stub.files = 1.14 +# 1.15 +# For NIO, the list of stub files is defined by the contents of the primary 1.16 +# API packages, together with such types that may be required in order to 1.17 +# compile the stubs. Some of these dependencies would go away if the stub 1.18 +# generator were to be improved -- e.g. by removing unnecessary imports. 1.19 +# 1.20 +import.jdk.stub.files = \ 1.21 + java/io/File.java \ 1.22 + java/nio/file/**.java \ 1.23 + java/nio/file/attribute/**.java \ 1.24 + java/nio/file/spi/**.java \ 1.25 + java/nio/channels/AsynchronousChannel.java \ 1.26 + java/nio/channels/AsynchronousFileChannel.java \ 1.27 + java/nio/channels/CompletionHandler.java \ 1.28 + java/nio/channels/SeekableByteChannel.java 1.29 1.30 # The following value is used by the main jtreg target. 1.31 # An empty value means all tests
2.1 --- a/make/build.xml Thu Dec 10 20:35:31 2009 -0800 2.2 +++ b/make/build.xml Fri Dec 11 14:26:27 2009 -0800 2.3 @@ -98,7 +98,7 @@ 2.4 import.jdk should be unset, or set to jdk home (to use rt.jar) 2.5 or to jdk repo (to use src/share/classes). 2.6 Based on the value, if any, set up default values for javac's sourcepath, 2.7 - classpath and bootclasspath. Note: the default values are overridden 2.8 + classpath and bootclasspath. Note: the default values are overridden 2.9 in the build-bootstrap-classes macro. --> 2.10 2.11 <available property="import.jdk.src.dir" value="${import.jdk}/src/share/classes" 2.12 @@ -552,8 +552,8 @@ 2.13 <compilerarg line="${javac.version.opt}"/> 2.14 <compilerarg line="${javac.lint.opts}"/> 2.15 </javac> 2.16 - <copy todir="@{classes.dir}"> 2.17 - <fileset dir="${src.classes.dir}" includes="@{includes}"> 2.18 + <copy todir="@{classes.dir}" includeemptydirs="false"> 2.19 + <fileset dir="${src.classes.dir}" includes="@{includes}" excludes="@{excludes}"> 2.20 <exclude name="**/*.java"/> 2.21 <exclude name="**/*.properties"/> 2.22 <exclude name="**/*-template"/>
3.1 --- a/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java Thu Dec 10 20:35:31 2009 -0800 3.2 +++ b/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java Fri Dec 11 14:26:27 2009 -0800 3.3 @@ -39,6 +39,8 @@ 3.4 3.5 import static javax.tools.JavaFileObject.Kind.*; 3.6 3.7 +import com.sun.tools.javac.util.BaseFileManager; 3.8 + 3.9 /** 3.10 * <p><b>This is NOT part of any API supported by Sun Microsystems. 3.11 * If you write code that depends on this, you do so at your own risk. 3.12 @@ -74,14 +76,7 @@ 3.13 protected abstract String inferBinaryName(Iterable<? extends File> path); 3.14 3.15 protected static JavaFileObject.Kind getKind(String filename) { 3.16 - if (filename.endsWith(CLASS.extension)) 3.17 - return CLASS; 3.18 - else if (filename.endsWith(SOURCE.extension)) 3.19 - return SOURCE; 3.20 - else if (filename.endsWith(HTML.extension)) 3.21 - return HTML; 3.22 - else 3.23 - return OTHER; 3.24 + return BaseFileManager.getKind(filename); 3.25 } 3.26 3.27 protected static String removeExtension(String fileName) {
4.1 --- a/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java Thu Dec 10 20:35:31 2009 -0800 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,107 +0,0 @@ 4.4 -/* 4.5 - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. 4.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 - * 4.8 - * This code is free software; you can redistribute it and/or modify it 4.9 - * under the terms of the GNU General Public License version 2 only, as 4.10 - * published by the Free Software Foundation. Sun designates this 4.11 - * particular file as subject to the "Classpath" exception as provided 4.12 - * by Sun in the LICENSE file that accompanied this code. 4.13 - * 4.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 4.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.17 - * version 2 for more details (a copy is included in the LICENSE file that 4.18 - * accompanied this code). 4.19 - * 4.20 - * You should have received a copy of the GNU General Public License version 4.21 - * 2 along with this work; if not, write to the Free Software Foundation, 4.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.23 - * 4.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 4.25 - * CA 95054 USA or visit www.sun.com if you need additional information or 4.26 - * have any questions. 4.27 - */ 4.28 - 4.29 -package com.sun.tools.javac.file; 4.30 - 4.31 -import java.io.Closeable; 4.32 -import java.io.IOException; 4.33 -import java.lang.reflect.Field; 4.34 -import java.net.URL; 4.35 -import java.net.URLClassLoader; 4.36 -import java.util.ArrayList; 4.37 -import java.util.jar.JarFile; 4.38 - 4.39 -/** 4.40 - * A URLClassLoader that also implements Closeable. 4.41 - * Reflection is used to access internal data structures in the URLClassLoader, 4.42 - * since no public API exists for this purpose. Therefore this code is somewhat 4.43 - * fragile. Caveat emptor. 4.44 - * @throws Error if the internal data structures are not as expected. 4.45 - * 4.46 - * <p><b>This is NOT part of any API supported by Sun Microsystems. If 4.47 - * you write code that depends on this, you do so at your own risk. 4.48 - * This code and its internal interfaces are subject to change or 4.49 - * deletion without notice.</b> 4.50 - */ 4.51 -class CloseableURLClassLoader 4.52 - extends URLClassLoader implements Closeable { 4.53 - CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error { 4.54 - super(urls, parent); 4.55 - try { 4.56 - getLoaders(); //proactive check that URLClassLoader is as expected 4.57 - } catch (Throwable t) { 4.58 - throw new Error("cannot create CloseableURLClassLoader", t); 4.59 - } 4.60 - } 4.61 - 4.62 - /** 4.63 - * Close any jar files that may have been opened by the class loader. 4.64 - * Reflection is used to access the jar files in the URLClassLoader's 4.65 - * internal data structures. 4.66 - * @throws java.io.IOException if the jar files cannot be found for any 4.67 - * reson, or if closing the jar file itself causes an IOException. 4.68 - */ 4.69 - public void close() throws IOException { 4.70 - try { 4.71 - for (Object l: getLoaders()) { 4.72 - if (l.getClass().getName().equals("sun.misc.URLClassPath$JarLoader")) { 4.73 - Field jarField = l.getClass().getDeclaredField("jar"); 4.74 - JarFile jar = (JarFile) getField(l, jarField); 4.75 - if (jar != null) { 4.76 - //System.err.println("CloseableURLClassLoader: closing " + jar); 4.77 - jar.close(); 4.78 - } 4.79 - } 4.80 - } 4.81 - } catch (Throwable t) { 4.82 - IOException e = new IOException("cannot close class loader"); 4.83 - e.initCause(t); 4.84 - throw e; 4.85 - } 4.86 - } 4.87 - 4.88 - private ArrayList<?> getLoaders() 4.89 - throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException 4.90 - { 4.91 - Field ucpField = URLClassLoader.class.getDeclaredField("ucp"); 4.92 - Object urlClassPath = getField(this, ucpField); 4.93 - if (urlClassPath == null) 4.94 - throw new AssertionError("urlClassPath not set in URLClassLoader"); 4.95 - Field loadersField = urlClassPath.getClass().getDeclaredField("loaders"); 4.96 - return (ArrayList<?>) getField(urlClassPath, loadersField); 4.97 - } 4.98 - 4.99 - private Object getField(Object o, Field f) 4.100 - throws IllegalArgumentException, IllegalAccessException { 4.101 - boolean prev = f.isAccessible(); 4.102 - try { 4.103 - f.setAccessible(true); 4.104 - return f.get(o); 4.105 - } finally { 4.106 - f.setAccessible(prev); 4.107 - } 4.108 - } 4.109 - 4.110 -}
5.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Dec 10 20:35:31 2009 -0800 5.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Fri Dec 11 14:26:27 2009 -0800 5.3 @@ -26,29 +26,16 @@ 5.4 package com.sun.tools.javac.file; 5.5 5.6 import java.io.ByteArrayOutputStream; 5.7 -import java.io.Closeable; 5.8 import java.io.File; 5.9 -import java.io.FileInputStream; 5.10 import java.io.FileNotFoundException; 5.11 import java.io.IOException; 5.12 -import java.io.InputStream; 5.13 import java.io.OutputStreamWriter; 5.14 -import java.lang.ref.SoftReference; 5.15 -import java.lang.reflect.Constructor; 5.16 import java.net.MalformedURLException; 5.17 import java.net.URI; 5.18 import java.net.URISyntaxException; 5.19 import java.net.URL; 5.20 -import java.net.URLClassLoader; 5.21 -import java.nio.ByteBuffer; 5.22 import java.nio.CharBuffer; 5.23 -import java.nio.channels.FileChannel; 5.24 import java.nio.charset.Charset; 5.25 -import java.nio.charset.CharsetDecoder; 5.26 -import java.nio.charset.CoderResult; 5.27 -import java.nio.charset.CodingErrorAction; 5.28 -import java.nio.charset.IllegalCharsetNameException; 5.29 -import java.nio.charset.UnsupportedCharsetException; 5.30 import java.util.ArrayList; 5.31 import java.util.Arrays; 5.32 import java.util.Collection; 5.33 @@ -66,18 +53,13 @@ 5.34 import javax.tools.JavaFileObject; 5.35 import javax.tools.StandardJavaFileManager; 5.36 5.37 -import com.sun.tools.javac.code.Source; 5.38 import com.sun.tools.javac.file.RelativePath.RelativeFile; 5.39 import com.sun.tools.javac.file.RelativePath.RelativeDirectory; 5.40 -import com.sun.tools.javac.main.JavacOption; 5.41 import com.sun.tools.javac.main.OptionName; 5.42 -import com.sun.tools.javac.main.RecognizedOptions; 5.43 +import com.sun.tools.javac.util.BaseFileManager; 5.44 import com.sun.tools.javac.util.Context; 5.45 -import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 5.46 import com.sun.tools.javac.util.List; 5.47 import com.sun.tools.javac.util.ListBuffer; 5.48 -import com.sun.tools.javac.util.Log; 5.49 -import com.sun.tools.javac.util.Options; 5.50 5.51 import static javax.tools.StandardLocation.*; 5.52 import static com.sun.tools.javac.main.OptionName.*; 5.53 @@ -91,7 +73,7 @@ 5.54 * This code and its internal interfaces are subject to change or 5.55 * deletion without notice.</b> 5.56 */ 5.57 -public class JavacFileManager implements StandardJavaFileManager { 5.58 +public class JavacFileManager extends BaseFileManager implements StandardJavaFileManager { 5.59 5.60 boolean useZipFileIndex; 5.61 5.62 @@ -102,17 +84,10 @@ 5.63 return buffer.toString().toCharArray(); 5.64 } 5.65 5.66 - /** 5.67 - * The log to be used for error reporting. 5.68 - */ 5.69 - protected Log log; 5.70 - 5.71 /** Encapsulates knowledge of paths 5.72 */ 5.73 private Paths paths; 5.74 5.75 - private Options options; 5.76 - 5.77 private FSInfo fsInfo; 5.78 5.79 private final File uninited = new File("U N I N I T E D"); 5.80 @@ -134,12 +109,6 @@ 5.81 5.82 protected boolean mmappedIO; 5.83 protected boolean ignoreSymbolFile; 5.84 - protected String classLoaderClass; 5.85 - 5.86 - /** 5.87 - * User provided charset (through javax.tools). 5.88 - */ 5.89 - protected Charset charset; 5.90 5.91 /** 5.92 * Register a Context.Factory to create a JavacFileManager. 5.93 @@ -157,18 +126,18 @@ 5.94 * it as the JavaFileManager for that context. 5.95 */ 5.96 public JavacFileManager(Context context, boolean register, Charset charset) { 5.97 + super(charset); 5.98 if (register) 5.99 context.put(JavaFileManager.class, this); 5.100 - byteBufferCache = new ByteBufferCache(); 5.101 - this.charset = charset; 5.102 setContext(context); 5.103 } 5.104 5.105 /** 5.106 * Set the context for JavacFileManager. 5.107 */ 5.108 + @Override 5.109 public void setContext(Context context) { 5.110 - log = Log.instance(context); 5.111 + super.setContext(context); 5.112 if (paths == null) { 5.113 paths = Paths.instance(context); 5.114 } else { 5.115 @@ -177,14 +146,12 @@ 5.116 paths.setContext(context); 5.117 } 5.118 5.119 - options = Options.instance(context); 5.120 fsInfo = FSInfo.instance(context); 5.121 5.122 useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; 5.123 5.124 mmappedIO = options.get("mmappedIO") != null; 5.125 ignoreSymbolFile = options.get("ignore.symbol.file") != null; 5.126 - classLoaderClass = options.get("procloader"); 5.127 } 5.128 5.129 public JavaFileObject getFileForInput(String name) { 5.130 @@ -214,17 +181,6 @@ 5.131 return getJavaFileObjectsFromStrings(Arrays.asList(nullCheck(names))); 5.132 } 5.133 5.134 - protected JavaFileObject.Kind getKind(String extension) { 5.135 - if (extension.equals(JavaFileObject.Kind.CLASS.extension)) 5.136 - return JavaFileObject.Kind.CLASS; 5.137 - else if (extension.equals(JavaFileObject.Kind.SOURCE.extension)) 5.138 - return JavaFileObject.Kind.SOURCE; 5.139 - else if (extension.equals(JavaFileObject.Kind.HTML.extension)) 5.140 - return JavaFileObject.Kind.HTML; 5.141 - else 5.142 - return JavaFileObject.Kind.OTHER; 5.143 - } 5.144 - 5.145 private static boolean isValidName(String name) { 5.146 // Arguably, isValidName should reject keywords (such as in SourceVersion.isName() ), 5.147 // but the set of keywords depends on the source level, and we don't want 5.148 @@ -359,9 +315,7 @@ 5.149 } 5.150 5.151 private boolean isValidFile(String s, Set<JavaFileObject.Kind> fileKinds) { 5.152 - int lastDot = s.lastIndexOf("."); 5.153 - String extn = (lastDot == -1 ? s : s.substring(lastDot)); 5.154 - JavaFileObject.Kind kind = getKind(extn); 5.155 + JavaFileObject.Kind kind = getKind(s); 5.156 return fileKinds.contains(kind); 5.157 } 5.158 5.159 @@ -564,18 +518,6 @@ 5.160 } 5.161 } 5.162 5.163 - CharBuffer getCachedContent(JavaFileObject file) { 5.164 - SoftReference<CharBuffer> r = contentCache.get(file); 5.165 - return (r == null ? null : r.get()); 5.166 - } 5.167 - 5.168 - void cache(JavaFileObject file, CharBuffer cb) { 5.169 - contentCache.put(file, new SoftReference<CharBuffer>(cb)); 5.170 - } 5.171 - 5.172 - private final Map<JavaFileObject, SoftReference<CharBuffer>> contentCache 5.173 - = new HashMap<JavaFileObject, SoftReference<CharBuffer>>(); 5.174 - 5.175 private String defaultEncodingName; 5.176 private String getDefaultEncodingName() { 5.177 if (defaultEncodingName == null) { 5.178 @@ -585,161 +527,6 @@ 5.179 return defaultEncodingName; 5.180 } 5.181 5.182 - protected String getEncodingName() { 5.183 - String encName = options.get(OptionName.ENCODING); 5.184 - if (encName == null) 5.185 - return getDefaultEncodingName(); 5.186 - else 5.187 - return encName; 5.188 - } 5.189 - 5.190 - protected Source getSource() { 5.191 - String sourceName = options.get(OptionName.SOURCE); 5.192 - Source source = null; 5.193 - if (sourceName != null) 5.194 - source = Source.lookup(sourceName); 5.195 - return (source != null ? source : Source.DEFAULT); 5.196 - } 5.197 - 5.198 - /** 5.199 - * Make a byte buffer from an input stream. 5.200 - */ 5.201 - ByteBuffer makeByteBuffer(InputStream in) 5.202 - throws IOException { 5.203 - int limit = in.available(); 5.204 - if (mmappedIO && in instanceof FileInputStream) { 5.205 - // Experimental memory mapped I/O 5.206 - FileInputStream fin = (FileInputStream)in; 5.207 - return fin.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, limit); 5.208 - } 5.209 - if (limit < 1024) limit = 1024; 5.210 - ByteBuffer result = byteBufferCache.get(limit); 5.211 - int position = 0; 5.212 - while (in.available() != 0) { 5.213 - if (position >= limit) 5.214 - // expand buffer 5.215 - result = ByteBuffer. 5.216 - allocate(limit <<= 1). 5.217 - put((ByteBuffer)result.flip()); 5.218 - int count = in.read(result.array(), 5.219 - position, 5.220 - limit - position); 5.221 - if (count < 0) break; 5.222 - result.position(position += count); 5.223 - } 5.224 - return (ByteBuffer)result.flip(); 5.225 - } 5.226 - 5.227 - void recycleByteBuffer(ByteBuffer bb) { 5.228 - byteBufferCache.put(bb); 5.229 - } 5.230 - 5.231 - /** 5.232 - * A single-element cache of direct byte buffers. 5.233 - */ 5.234 - private static class ByteBufferCache { 5.235 - private ByteBuffer cached; 5.236 - ByteBuffer get(int capacity) { 5.237 - if (capacity < 20480) capacity = 20480; 5.238 - ByteBuffer result = 5.239 - (cached != null && cached.capacity() >= capacity) 5.240 - ? (ByteBuffer)cached.clear() 5.241 - : ByteBuffer.allocate(capacity + capacity>>1); 5.242 - cached = null; 5.243 - return result; 5.244 - } 5.245 - void put(ByteBuffer x) { 5.246 - cached = x; 5.247 - } 5.248 - } 5.249 - 5.250 - private final ByteBufferCache byteBufferCache; 5.251 - 5.252 - CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { 5.253 - Charset cs = (this.charset == null) 5.254 - ? Charset.forName(encodingName) 5.255 - : this.charset; 5.256 - CharsetDecoder decoder = cs.newDecoder(); 5.257 - 5.258 - CodingErrorAction action; 5.259 - if (ignoreEncodingErrors) 5.260 - action = CodingErrorAction.REPLACE; 5.261 - else 5.262 - action = CodingErrorAction.REPORT; 5.263 - 5.264 - return decoder 5.265 - .onMalformedInput(action) 5.266 - .onUnmappableCharacter(action); 5.267 - } 5.268 - 5.269 - /** 5.270 - * Decode a ByteBuffer into a CharBuffer. 5.271 - */ 5.272 - CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { 5.273 - String encodingName = getEncodingName(); 5.274 - CharsetDecoder decoder; 5.275 - try { 5.276 - decoder = getDecoder(encodingName, ignoreEncodingErrors); 5.277 - } catch (IllegalCharsetNameException e) { 5.278 - log.error("unsupported.encoding", encodingName); 5.279 - return (CharBuffer)CharBuffer.allocate(1).flip(); 5.280 - } catch (UnsupportedCharsetException e) { 5.281 - log.error("unsupported.encoding", encodingName); 5.282 - return (CharBuffer)CharBuffer.allocate(1).flip(); 5.283 - } 5.284 - 5.285 - // slightly overestimate the buffer size to avoid reallocation. 5.286 - float factor = 5.287 - decoder.averageCharsPerByte() * 0.8f + 5.288 - decoder.maxCharsPerByte() * 0.2f; 5.289 - CharBuffer dest = CharBuffer. 5.290 - allocate(10 + (int)(inbuf.remaining()*factor)); 5.291 - 5.292 - while (true) { 5.293 - CoderResult result = decoder.decode(inbuf, dest, true); 5.294 - dest.flip(); 5.295 - 5.296 - if (result.isUnderflow()) { // done reading 5.297 - // make sure there is at least one extra character 5.298 - if (dest.limit() == dest.capacity()) { 5.299 - dest = CharBuffer.allocate(dest.capacity()+1).put(dest); 5.300 - dest.flip(); 5.301 - } 5.302 - return dest; 5.303 - } else if (result.isOverflow()) { // buffer too small; expand 5.304 - int newCapacity = 5.305 - 10 + dest.capacity() + 5.306 - (int)(inbuf.remaining()*decoder.maxCharsPerByte()); 5.307 - dest = CharBuffer.allocate(newCapacity).put(dest); 5.308 - } else if (result.isMalformed() || result.isUnmappable()) { 5.309 - // bad character in input 5.310 - 5.311 - // report coding error (warn only pre 1.5) 5.312 - if (!getSource().allowEncodingErrors()) { 5.313 - log.error(new SimpleDiagnosticPosition(dest.limit()), 5.314 - "illegal.char.for.encoding", 5.315 - charset == null ? encodingName : charset.name()); 5.316 - } else { 5.317 - log.warning(new SimpleDiagnosticPosition(dest.limit()), 5.318 - "illegal.char.for.encoding", 5.319 - charset == null ? encodingName : charset.name()); 5.320 - } 5.321 - 5.322 - // skip past the coding error 5.323 - inbuf.position(inbuf.position() + result.length()); 5.324 - 5.325 - // undo the flip() to prepare the output buffer 5.326 - // for more translation 5.327 - dest.position(dest.limit()); 5.328 - dest.limit(dest.capacity()); 5.329 - dest.put((char)0xfffd); // backward compatible 5.330 - } else { 5.331 - throw new AssertionError(result); 5.332 - } 5.333 - } 5.334 - // unreached 5.335 - } 5.336 - 5.337 public ClassLoader getClassLoader(Location location) { 5.338 nullCheck(location); 5.339 Iterable<? extends File> path = getLocation(location); 5.340 @@ -754,39 +541,7 @@ 5.341 } 5.342 } 5.343 5.344 - URL[] urls = lb.toArray(new URL[lb.size()]); 5.345 - ClassLoader thisClassLoader = getClass().getClassLoader(); 5.346 - 5.347 - // Bug: 6558476 5.348 - // Ideally, ClassLoader should be Closeable, but before JDK7 it is not. 5.349 - // On older versions, try the following, to get a closeable classloader. 5.350 - 5.351 - // 1: Allow client to specify the class to use via hidden option 5.352 - if (classLoaderClass != null) { 5.353 - try { 5.354 - Class<? extends ClassLoader> loader = 5.355 - Class.forName(classLoaderClass).asSubclass(ClassLoader.class); 5.356 - Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class }; 5.357 - Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes); 5.358 - return constr.newInstance(new Object[] { urls, thisClassLoader }); 5.359 - } catch (Throwable t) { 5.360 - // ignore errors loading user-provided class loader, fall through 5.361 - } 5.362 - } 5.363 - 5.364 - // 2: If URLClassLoader implements Closeable, use that. 5.365 - if (Closeable.class.isAssignableFrom(URLClassLoader.class)) 5.366 - return new URLClassLoader(urls, thisClassLoader); 5.367 - 5.368 - // 3: Try using private reflection-based CloseableURLClassLoader 5.369 - try { 5.370 - return new CloseableURLClassLoader(urls, thisClassLoader); 5.371 - } catch (Throwable t) { 5.372 - // ignore errors loading workaround class loader, fall through 5.373 - } 5.374 - 5.375 - // 4: If all else fails, use plain old standard URLClassLoader 5.376 - return new URLClassLoader(urls, thisClassLoader); 5.377 + return getClassLoader(lb.toArray(new URL[lb.size()])); 5.378 } 5.379 5.380 public Iterable<JavaFileObject> list(Location location, 5.381 @@ -836,38 +591,6 @@ 5.382 return a.equals(b); 5.383 } 5.384 5.385 - public boolean handleOption(String current, Iterator<String> remaining) { 5.386 - for (JavacOption o: javacFileManagerOptions) { 5.387 - if (o.matches(current)) { 5.388 - if (o.hasArg()) { 5.389 - if (remaining.hasNext()) { 5.390 - if (!o.process(options, current, remaining.next())) 5.391 - return true; 5.392 - } 5.393 - } else { 5.394 - if (!o.process(options, current)) 5.395 - return true; 5.396 - } 5.397 - // operand missing, or process returned false 5.398 - throw new IllegalArgumentException(current); 5.399 - } 5.400 - } 5.401 - 5.402 - return false; 5.403 - } 5.404 - // where 5.405 - private static JavacOption[] javacFileManagerOptions = 5.406 - RecognizedOptions.getJavacFileManagerOptions( 5.407 - new RecognizedOptions.GrumpyHelper()); 5.408 - 5.409 - public int isSupportedOption(String option) { 5.410 - for (JavacOption o : javacFileManagerOptions) { 5.411 - if (o.matches(option)) 5.412 - return o.hasArg() ? 1 : 0; 5.413 - } 5.414 - return -1; 5.415 - } 5.416 - 5.417 public boolean hasLocation(Location location) { 5.418 return getLocation(location) != null; 5.419 } 5.420 @@ -1115,15 +838,4 @@ 5.421 } 5.422 throw new IllegalArgumentException("Invalid relative path: " + file); 5.423 } 5.424 - 5.425 - private static <T> T nullCheck(T o) { 5.426 - o.getClass(); // null check 5.427 - return o; 5.428 - } 5.429 - 5.430 - private static <T> Iterable<T> nullCheck(Iterable<T> it) { 5.431 - for (T t : it) 5.432 - t.getClass(); // null check 5.433 - return it; 5.434 - } 5.435 }
6.1 --- a/src/share/classes/com/sun/tools/javac/file/Paths.java Thu Dec 10 20:35:31 2009 -0800 6.2 +++ b/src/share/classes/com/sun/tools/javac/file/Paths.java Fri Dec 11 14:26:27 2009 -0800 6.3 @@ -66,7 +66,7 @@ 6.4 * @param context the context 6.5 * @return the Paths instance for this context 6.6 */ 6.7 - static Paths instance(Context context) { 6.8 + public static Paths instance(Context context) { 6.9 Paths instance = context.get(pathsKey); 6.10 if (instance == null) 6.11 instance = new Paths(context);
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Fri Dec 11 14:26:27 2009 -0800 7.3 @@ -0,0 +1,543 @@ 7.4 +/* 7.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. Sun designates this 7.11 + * particular file as subject to the "Classpath" exception as provided 7.12 + * by Sun in the LICENSE file that accompanied this code. 7.13 + * 7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.17 + * version 2 for more details (a copy is included in the LICENSE file that 7.18 + * accompanied this code). 7.19 + * 7.20 + * You should have received a copy of the GNU General Public License version 7.21 + * 2 along with this work; if not, write to the Free Software Foundation, 7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.23 + * 7.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 7.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 7.26 + * have any questions. 7.27 + */ 7.28 + 7.29 +package com.sun.tools.javac.nio; 7.30 + 7.31 + 7.32 +import java.io.File; 7.33 +import java.io.FileNotFoundException; 7.34 +import java.io.IOException; 7.35 +import java.net.MalformedURLException; 7.36 +import java.net.URL; 7.37 +import java.nio.charset.Charset; 7.38 +import java.nio.file.Files; 7.39 +import java.nio.file.FileSystem; 7.40 +import java.nio.file.FileSystems; 7.41 +import java.nio.file.FileVisitOption; 7.42 +import java.nio.file.FileVisitResult; 7.43 +import java.nio.file.Path; 7.44 +import java.nio.file.SimpleFileVisitor; 7.45 +import java.nio.file.attribute.Attributes; 7.46 +import java.nio.file.attribute.BasicFileAttributes; 7.47 +import java.util.ArrayList; 7.48 +import java.util.Arrays; 7.49 +import java.util.Collection; 7.50 +import java.util.Collections; 7.51 +import java.util.EnumSet; 7.52 +import java.util.HashMap; 7.53 +import java.util.Iterator; 7.54 +import java.util.LinkedHashSet; 7.55 +import java.util.Map; 7.56 +import java.util.Set; 7.57 +import javax.lang.model.SourceVersion; 7.58 +import javax.tools.FileObject; 7.59 +import javax.tools.JavaFileManager; 7.60 +import javax.tools.JavaFileObject; 7.61 +import javax.tools.JavaFileObject.Kind; 7.62 +import javax.tools.StandardLocation; 7.63 + 7.64 +import static java.nio.file.FileVisitOption.*; 7.65 +import static javax.tools.StandardLocation.*; 7.66 + 7.67 +import com.sun.tools.javac.file.Paths; 7.68 +import com.sun.tools.javac.util.BaseFileManager; 7.69 +import com.sun.tools.javac.util.Context; 7.70 +import com.sun.tools.javac.util.List; 7.71 +import com.sun.tools.javac.util.ListBuffer; 7.72 + 7.73 +import static com.sun.tools.javac.main.OptionName.*; 7.74 + 7.75 + 7.76 +// NOTE the imports carefully for this compilation unit. 7.77 +// 7.78 +// Path: java.nio.file.Path -- the new NIO type for which this file manager exists 7.79 +// 7.80 +// Paths: com.sun.tools.javac.file.Paths -- legacy javac type for handling path options 7.81 +// The other Paths (java.nio.file.Paths) is not used 7.82 + 7.83 +// NOTE this and related classes depend on new API in JDK 7. 7.84 +// This requires special handling while bootstrapping the JDK build, 7.85 +// when these classes might not yet have been compiled. To workaround 7.86 +// this, the build arranges to make stubs of these classes available 7.87 +// when compiling this and related classes. The set of stub files 7.88 +// is specified in make/build.properties. 7.89 + 7.90 +/** 7.91 + * Implementation of PathFileManager: a JavaFileManager based on the use 7.92 + * of java.nio.file.Path. 7.93 + * 7.94 + * <p>Just as a Path is somewhat analagous to a File, so too is this 7.95 + * JavacPathFileManager analogous to JavacFileManager, as it relates to the 7.96 + * support of FileObjects based on File objects (i.e. just RegularFileObject, 7.97 + * not ZipFileObject and its variants.) 7.98 + * 7.99 + * <p>The default values for the standard locations supported by this file 7.100 + * manager are the same as the default values provided by JavacFileManager -- 7.101 + * i.e. as determined by the javac.file.Paths class. To override these values, 7.102 + * call {@link #setLocation}. 7.103 + * 7.104 + * <p>To reduce confusion with Path objects, the locations such as "class path", 7.105 + * "source path", etc, are generically referred to here as "search paths". 7.106 + * 7.107 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 7.108 + * you write code that depends on this, you do so at your own risk. 7.109 + * This code and its internal interfaces are subject to change or 7.110 + * deletion without notice.</b> 7.111 + */ 7.112 +public class JavacPathFileManager extends BaseFileManager implements PathFileManager { 7.113 + protected FileSystem defaultFileSystem; 7.114 + 7.115 + /** 7.116 + * Create a JavacPathFileManager using a given context, optionally registering 7.117 + * it as the JavaFileManager for that context. 7.118 + */ 7.119 + public JavacPathFileManager(Context context, boolean register, Charset charset) { 7.120 + super(charset); 7.121 + if (register) 7.122 + context.put(JavaFileManager.class, this); 7.123 + pathsForLocation = new HashMap<Location, PathsForLocation>(); 7.124 + fileSystems = new HashMap<Path,FileSystem>(); 7.125 + setContext(context); 7.126 + } 7.127 + 7.128 + /** 7.129 + * Set the context for JavacPathFileManager. 7.130 + */ 7.131 + @Override 7.132 + protected void setContext(Context context) { 7.133 + super.setContext(context); 7.134 + searchPaths = Paths.instance(context); 7.135 + } 7.136 + 7.137 + @Override 7.138 + public FileSystem getDefaultFileSystem() { 7.139 + if (defaultFileSystem == null) 7.140 + defaultFileSystem = FileSystems.getDefault(); 7.141 + return defaultFileSystem; 7.142 + } 7.143 + 7.144 + @Override 7.145 + public void setDefaultFileSystem(FileSystem fs) { 7.146 + defaultFileSystem = fs; 7.147 + } 7.148 + 7.149 + @Override 7.150 + public void flush() throws IOException { 7.151 + contentCache.clear(); 7.152 + } 7.153 + 7.154 + @Override 7.155 + public void close() throws IOException { 7.156 + for (FileSystem fs: fileSystems.values()) 7.157 + fs.close(); 7.158 + } 7.159 + 7.160 + @Override 7.161 + public ClassLoader getClassLoader(Location location) { 7.162 + nullCheck(location); 7.163 + Iterable<? extends Path> path = getLocation(location); 7.164 + if (path == null) 7.165 + return null; 7.166 + ListBuffer<URL> lb = new ListBuffer<URL>(); 7.167 + for (Path p: path) { 7.168 + try { 7.169 + lb.append(p.toUri().toURL()); 7.170 + } catch (MalformedURLException e) { 7.171 + throw new AssertionError(e); 7.172 + } 7.173 + } 7.174 + 7.175 + return getClassLoader(lb.toArray(new URL[lb.size()])); 7.176 + } 7.177 + 7.178 + // <editor-fold defaultstate="collapsed" desc="Location handling"> 7.179 + 7.180 + public boolean hasLocation(Location location) { 7.181 + return (getLocation(location) != null); 7.182 + } 7.183 + 7.184 + public Iterable<? extends Path> getLocation(Location location) { 7.185 + nullCheck(location); 7.186 + lazyInitSearchPaths(); 7.187 + PathsForLocation path = pathsForLocation.get(location); 7.188 + if (path == null && !pathsForLocation.containsKey(location)) { 7.189 + setDefaultForLocation(location); 7.190 + path = pathsForLocation.get(location); 7.191 + } 7.192 + return path; 7.193 + } 7.194 + 7.195 + private Path getOutputLocation(Location location) { 7.196 + Iterable<? extends Path> paths = getLocation(location); 7.197 + return (paths == null ? null : paths.iterator().next()); 7.198 + } 7.199 + 7.200 + public void setLocation(Location location, Iterable<? extends Path> searchPath) 7.201 + throws IOException 7.202 + { 7.203 + nullCheck(location); 7.204 + lazyInitSearchPaths(); 7.205 + if (searchPath == null) { 7.206 + setDefaultForLocation(location); 7.207 + } else { 7.208 + if (location.isOutputLocation()) 7.209 + checkOutputPath(searchPath); 7.210 + PathsForLocation pl = new PathsForLocation(); 7.211 + for (Path p: searchPath) 7.212 + pl.add(p); // TODO -Xlint:path warn if path not found 7.213 + pathsForLocation.put(location, pl); 7.214 + } 7.215 + } 7.216 + 7.217 + private void checkOutputPath(Iterable<? extends Path> searchPath) throws IOException { 7.218 + Iterator<? extends Path> pathIter = searchPath.iterator(); 7.219 + if (!pathIter.hasNext()) 7.220 + throw new IllegalArgumentException("empty path for directory"); 7.221 + Path path = pathIter.next(); 7.222 + if (pathIter.hasNext()) 7.223 + throw new IllegalArgumentException("path too long for directory"); 7.224 + if (!path.exists()) 7.225 + throw new FileNotFoundException(path + ": does not exist"); 7.226 + else if (!isDirectory(path)) 7.227 + throw new IOException(path + ": not a directory"); 7.228 + } 7.229 + 7.230 + private void setDefaultForLocation(Location locn) { 7.231 + Collection<File> files = null; 7.232 + if (locn instanceof StandardLocation) { 7.233 + switch ((StandardLocation) locn) { 7.234 + case CLASS_PATH: 7.235 + files = searchPaths.userClassPath(); 7.236 + break; 7.237 + case PLATFORM_CLASS_PATH: 7.238 + files = searchPaths.bootClassPath(); 7.239 + break; 7.240 + case SOURCE_PATH: 7.241 + files = searchPaths.sourcePath(); 7.242 + break; 7.243 + case CLASS_OUTPUT: { 7.244 + String arg = options.get(D); 7.245 + files = (arg == null ? null : Collections.singleton(new File(arg))); 7.246 + break; 7.247 + } 7.248 + case SOURCE_OUTPUT: { 7.249 + String arg = options.get(S); 7.250 + files = (arg == null ? null : Collections.singleton(new File(arg))); 7.251 + break; 7.252 + } 7.253 + } 7.254 + } 7.255 + 7.256 + PathsForLocation pl = new PathsForLocation(); 7.257 + if (files != null) { 7.258 + for (File f: files) 7.259 + pl.add(f.toPath()); 7.260 + } 7.261 + pathsForLocation.put(locn, pl); 7.262 + } 7.263 + 7.264 + private void lazyInitSearchPaths() { 7.265 + if (!inited) { 7.266 + setDefaultForLocation(PLATFORM_CLASS_PATH); 7.267 + setDefaultForLocation(CLASS_PATH); 7.268 + setDefaultForLocation(SOURCE_PATH); 7.269 + inited = true; 7.270 + } 7.271 + } 7.272 + // where 7.273 + private boolean inited = false; 7.274 + 7.275 + private Map<Location, PathsForLocation> pathsForLocation; 7.276 + private Paths searchPaths; 7.277 + 7.278 + private static class PathsForLocation extends LinkedHashSet<Path> { 7.279 + private static final long serialVersionUID = 6788510222394486733L; 7.280 + } 7.281 + 7.282 + // </editor-fold> 7.283 + 7.284 + // <editor-fold defaultstate="collapsed" desc="FileObject handling"> 7.285 + 7.286 + @Override 7.287 + public Path getPath(FileObject fo) { 7.288 + nullCheck(fo); 7.289 + if (!(fo instanceof PathFileObject)) 7.290 + throw new IllegalArgumentException(); 7.291 + return ((PathFileObject) fo).getPath(); 7.292 + } 7.293 + 7.294 + @Override 7.295 + public boolean isSameFile(FileObject a, FileObject b) { 7.296 + nullCheck(a); 7.297 + nullCheck(b); 7.298 + if (!(a instanceof PathFileObject)) 7.299 + throw new IllegalArgumentException("Not supported: " + a); 7.300 + if (!(b instanceof PathFileObject)) 7.301 + throw new IllegalArgumentException("Not supported: " + b); 7.302 + return ((PathFileObject) a).isSameFile((PathFileObject) b); 7.303 + } 7.304 + 7.305 + @Override 7.306 + public Iterable<JavaFileObject> list(Location location, 7.307 + String packageName, Set<Kind> kinds, boolean recurse) 7.308 + throws IOException { 7.309 + // validatePackageName(packageName); 7.310 + nullCheck(packageName); 7.311 + nullCheck(kinds); 7.312 + 7.313 + Iterable<? extends Path> paths = getLocation(location); 7.314 + if (paths == null) 7.315 + return List.nil(); 7.316 + ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>(); 7.317 + 7.318 + for (Path path : paths) 7.319 + list(path, packageName, kinds, recurse, results); 7.320 + 7.321 + return results.toList(); 7.322 + } 7.323 + 7.324 + private void list(Path path, String packageName, final Set<Kind> kinds, 7.325 + boolean recurse, final ListBuffer<JavaFileObject> results) 7.326 + throws IOException { 7.327 + if (!path.exists()) 7.328 + return; 7.329 + 7.330 + final Path pathDir; 7.331 + if (isDirectory(path)) 7.332 + pathDir = path; 7.333 + else { 7.334 + FileSystem fs = getFileSystem(path); 7.335 + if (fs == null) 7.336 + return; 7.337 + pathDir = fs.getRootDirectories().iterator().next(); 7.338 + } 7.339 + String sep = path.getFileSystem().getSeparator(); 7.340 + Path packageDir = packageName.isEmpty() ? pathDir 7.341 + : pathDir.resolve(packageName.replace(".", sep)); 7.342 + if (!packageDir.exists()) 7.343 + return; 7.344 + 7.345 +/* Alternate impl of list, superceded by use of Files.walkFileTree */ 7.346 +// Deque<Path> queue = new LinkedList<Path>(); 7.347 +// queue.add(packageDir); 7.348 +// 7.349 +// Path dir; 7.350 +// while ((dir = queue.poll()) != null) { 7.351 +// DirectoryStream<Path> ds = dir.newDirectoryStream(); 7.352 +// try { 7.353 +// for (Path p: ds) { 7.354 +// String name = p.getName().toString(); 7.355 +// if (isDirectory(p)) { 7.356 +// if (recurse && SourceVersion.isIdentifier(name)) { 7.357 +// queue.add(p); 7.358 +// } 7.359 +// } else { 7.360 +// if (kinds.contains(getKind(name))) { 7.361 +// JavaFileObject fe = 7.362 +// PathFileObject.createDirectoryPathFileObject(this, p, pathDir); 7.363 +// results.append(fe); 7.364 +// } 7.365 +// } 7.366 +// } 7.367 +// } finally { 7.368 +// ds.close(); 7.369 +// } 7.370 +// } 7.371 + int maxDepth = (recurse ? Integer.MAX_VALUE : 1); 7.372 + Set<FileVisitOption> opts = EnumSet.of(DETECT_CYCLES, FOLLOW_LINKS); 7.373 + Files.walkFileTree(packageDir, opts, maxDepth, 7.374 + new SimpleFileVisitor<Path>() { 7.375 + @Override 7.376 + public FileVisitResult preVisitDirectory(Path dir) { 7.377 + if (SourceVersion.isIdentifier(dir.getName().toString())) // JSR 292? 7.378 + return FileVisitResult.CONTINUE; 7.379 + else 7.380 + return FileVisitResult.SKIP_SUBTREE; 7.381 + } 7.382 + 7.383 + @Override 7.384 + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { 7.385 + if (attrs.isRegularFile() && kinds.contains(getKind(file.getName().toString()))) { 7.386 + JavaFileObject fe = 7.387 + PathFileObject.createDirectoryPathFileObject( 7.388 + JavacPathFileManager.this, file, pathDir); 7.389 + results.append(fe); 7.390 + } 7.391 + return FileVisitResult.CONTINUE; 7.392 + } 7.393 + }); 7.394 + } 7.395 + 7.396 + @Override 7.397 + public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths( 7.398 + Iterable<? extends Path> paths) { 7.399 + ArrayList<PathFileObject> result; 7.400 + if (paths instanceof Collection<?>) 7.401 + result = new ArrayList<PathFileObject>(((Collection<?>)paths).size()); 7.402 + else 7.403 + result = new ArrayList<PathFileObject>(); 7.404 + for (Path p: paths) 7.405 + result.add(PathFileObject.createSimplePathFileObject(this, nullCheck(p))); 7.406 + return result; 7.407 + } 7.408 + 7.409 + @Override 7.410 + public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) { 7.411 + return getJavaFileObjectsFromPaths(Arrays.asList(nullCheck(paths))); 7.412 + } 7.413 + 7.414 + @Override 7.415 + public JavaFileObject getJavaFileForInput(Location location, 7.416 + String className, Kind kind) throws IOException { 7.417 + return getFileForInput(location, getRelativePath(className, kind)); 7.418 + } 7.419 + 7.420 + @Override 7.421 + public FileObject getFileForInput(Location location, 7.422 + String packageName, String relativeName) throws IOException { 7.423 + return getFileForInput(location, getRelativePath(packageName, relativeName)); 7.424 + } 7.425 + 7.426 + private JavaFileObject getFileForInput(Location location, String relativePath) 7.427 + throws IOException { 7.428 + for (Path p: getLocation(location)) { 7.429 + if (isDirectory(p)) { 7.430 + Path f = resolve(p, relativePath); 7.431 + if (f.exists()) 7.432 + return PathFileObject.createDirectoryPathFileObject(this, f, p); 7.433 + } else { 7.434 + FileSystem fs = getFileSystem(p); 7.435 + if (fs != null) { 7.436 + Path file = getPath(fs, relativePath); 7.437 + if (file.exists()) 7.438 + return PathFileObject.createJarPathFileObject(this, file); 7.439 + } 7.440 + } 7.441 + } 7.442 + return null; 7.443 + } 7.444 + 7.445 + @Override 7.446 + public JavaFileObject getJavaFileForOutput(Location location, 7.447 + String className, Kind kind, FileObject sibling) throws IOException { 7.448 + return getFileForOutput(location, getRelativePath(className, kind), sibling); 7.449 + } 7.450 + 7.451 + @Override 7.452 + public FileObject getFileForOutput(Location location, String packageName, 7.453 + String relativeName, FileObject sibling) 7.454 + throws IOException { 7.455 + return getFileForOutput(location, getRelativePath(packageName, relativeName), sibling); 7.456 + } 7.457 + 7.458 + private JavaFileObject getFileForOutput(Location location, 7.459 + String relativePath, FileObject sibling) { 7.460 + Path dir = getOutputLocation(location); 7.461 + if (dir == null) { 7.462 + if (location == CLASS_OUTPUT) { 7.463 + Path siblingDir = null; 7.464 + if (sibling != null && sibling instanceof PathFileObject) { 7.465 + siblingDir = ((PathFileObject) sibling).getPath().getParent(); 7.466 + } 7.467 + return PathFileObject.createSiblingPathFileObject(this, 7.468 + siblingDir.resolve(getBaseName(relativePath)), 7.469 + relativePath); 7.470 + } else if (location == SOURCE_OUTPUT) { 7.471 + dir = getOutputLocation(CLASS_OUTPUT); 7.472 + } 7.473 + } 7.474 + 7.475 + Path file; 7.476 + if (dir != null) { 7.477 + file = resolve(dir, relativePath); 7.478 + return PathFileObject.createDirectoryPathFileObject(this, file, dir); 7.479 + } else { 7.480 + file = getPath(getDefaultFileSystem(), relativePath); 7.481 + return PathFileObject.createSimplePathFileObject(this, file); 7.482 + } 7.483 + 7.484 + } 7.485 + 7.486 + @Override 7.487 + public String inferBinaryName(Location location, JavaFileObject fo) { 7.488 + nullCheck(fo); 7.489 + // Need to match the path semantics of list(location, ...) 7.490 + Iterable<? extends Path> paths = getLocation(location); 7.491 + if (paths == null) { 7.492 + return null; 7.493 + } 7.494 + 7.495 + if (!(fo instanceof PathFileObject)) 7.496 + throw new IllegalArgumentException(fo.getClass().getName()); 7.497 + 7.498 + return ((PathFileObject) fo).inferBinaryName(paths); 7.499 + } 7.500 + 7.501 + private FileSystem getFileSystem(Path p) throws IOException { 7.502 + FileSystem fs = fileSystems.get(p); 7.503 + if (fs == null) { 7.504 + fs = FileSystems.newFileSystem(p, Collections.<String,Void>emptyMap(), null); 7.505 + fileSystems.put(p, fs); 7.506 + } 7.507 + return fs; 7.508 + } 7.509 + 7.510 + private Map<Path,FileSystem> fileSystems; 7.511 + 7.512 + // </editor-fold> 7.513 + 7.514 + // <editor-fold defaultstate="collapsed" desc="Utility methods"> 7.515 + 7.516 + private static String getRelativePath(String className, Kind kind) { 7.517 + return className.replace(".", "/") + kind.extension; 7.518 + } 7.519 + 7.520 + private static String getRelativePath(String packageName, String relativeName) { 7.521 + return packageName.replace(".", "/") + relativeName; 7.522 + } 7.523 + 7.524 + private static String getBaseName(String relativePath) { 7.525 + int lastSep = relativePath.lastIndexOf("/"); 7.526 + return relativePath.substring(lastSep + 1); // safe if "/" not found 7.527 + } 7.528 + 7.529 + private static boolean isDirectory(Path path) throws IOException { 7.530 + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path); 7.531 + return attrs.isDirectory(); 7.532 + } 7.533 + 7.534 + private static Path getPath(FileSystem fs, String relativePath) { 7.535 + return fs.getPath(relativePath.replace("/", fs.getSeparator())); 7.536 + } 7.537 + 7.538 + private static Path resolve(Path base, String relativePath) { 7.539 + FileSystem fs = base.getFileSystem(); 7.540 + Path rp = fs.getPath(relativePath.replace("/", fs.getSeparator())); 7.541 + return base.resolve(rp); 7.542 + } 7.543 + 7.544 + // </editor-fold> 7.545 + 7.546 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/share/classes/com/sun/tools/javac/nio/PathFileManager.java Fri Dec 11 14:26:27 2009 -0800 8.3 @@ -0,0 +1,125 @@ 8.4 +/* 8.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. Sun designates this 8.11 + * particular file as subject to the "Classpath" exception as provided 8.12 + * by Sun in the LICENSE file that accompanied this code. 8.13 + * 8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.17 + * version 2 for more details (a copy is included in the LICENSE file that 8.18 + * accompanied this code). 8.19 + * 8.20 + * You should have received a copy of the GNU General Public License version 8.21 + * 2 along with this work; if not, write to the Free Software Foundation, 8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.23 + * 8.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 8.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 8.26 + * have any questions. 8.27 + */ 8.28 + 8.29 +package com.sun.tools.javac.nio; 8.30 + 8.31 +import java.io.IOException; 8.32 +import java.nio.file.FileSystem; 8.33 +import java.nio.file.Path; 8.34 +import javax.tools.FileObject; 8.35 +import javax.tools.JavaFileManager; 8.36 +import javax.tools.JavaFileObject; 8.37 + 8.38 +/** 8.39 + * File manager based on {@linkplain File java.nio.file.Path}. 8.40 + * 8.41 + * Eventually, this should be moved to javax.tools. 8.42 + * Also, JavaCompiler might reasonably provide a method getPathFileManager, 8.43 + * similar to {@link javax.tools.JavaCompiler#getStandardFileManager 8.44 + * getStandardFileManager}. However, would need to be handled carefully 8.45 + * as another forward reference from langtools to jdk. 8.46 + * 8.47 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 8.48 + * you write code that depends on this, you do so at your own risk. 8.49 + * This code and its internal interfaces are subject to change or 8.50 + * deletion without notice.</b> 8.51 + */ 8.52 +public interface PathFileManager extends JavaFileManager { 8.53 + /** 8.54 + * Get the default file system used to create paths. If no value has been 8.55 + * set, the default file system is {@link FileSystems#getDefault}. 8.56 + */ 8.57 + FileSystem getDefaultFileSystem(); 8.58 + 8.59 + /** 8.60 + * Set the default file system used to create paths. 8.61 + * @param fs the default file system used to create any new paths. 8.62 + */ 8.63 + void setDefaultFileSystem(FileSystem fs); 8.64 + 8.65 + /** 8.66 + * Get file objects representing the given files. 8.67 + * 8.68 + * @param paths a list of paths 8.69 + * @return a list of file objects 8.70 + * @throws IllegalArgumentException if the list of paths includes 8.71 + * a directory 8.72 + */ 8.73 + Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths( 8.74 + Iterable<? extends Path> paths); 8.75 + 8.76 + /** 8.77 + * Get file objects representing the given paths. 8.78 + * Convenience method equivalent to: 8.79 + * 8.80 + * <pre> 8.81 + * getJavaFileObjectsFromPaths({@linkplain java.util.Arrays#asList Arrays.asList}(paths)) 8.82 + * </pre> 8.83 + * 8.84 + * @param paths an array of paths 8.85 + * @return a list of file objects 8.86 + * @throws IllegalArgumentException if the array of files includes 8.87 + * a directory 8.88 + * @throws NullPointerException if the given array contains null 8.89 + * elements 8.90 + */ 8.91 + Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths); 8.92 + 8.93 + /** 8.94 + * Return the Path for a file object that has been obtained from this 8.95 + * file manager. 8.96 + * 8.97 + * @param fo A file object that has been obtained from this file manager. 8.98 + * @return The underlying Path object. 8.99 + * @throws IllegalArgumentException is the file object was not obtained from 8.100 + * from this file manager. 8.101 + */ 8.102 + Path getPath(FileObject fo); 8.103 + 8.104 + /** 8.105 + * Get the search path associated with the given location. 8.106 + * 8.107 + * @param location a location 8.108 + * @return a list of paths or {@code null} if this location has no 8.109 + * associated search path 8.110 + * @see #setLocation 8.111 + */ 8.112 + Iterable<? extends Path> getLocation(Location location); 8.113 + 8.114 + /** 8.115 + * Associate the given search path with the given location. Any 8.116 + * previous value will be discarded. 8.117 + * 8.118 + * @param location a location 8.119 + * @param searchPath a list of files, if {@code null} use the default 8.120 + * search path for this location 8.121 + * @see #getLocation 8.122 + * @throws IllegalArgumentException if location is an output 8.123 + * location and searchpath does not contain exactly one element 8.124 + * @throws IOException if location is an output location and searchpath 8.125 + * does not represent an existing directory 8.126 + */ 8.127 + void setLocation(Location location, Iterable<? extends Path> searchPath) throws IOException; 8.128 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/share/classes/com/sun/tools/javac/nio/PathFileObject.java Fri Dec 11 14:26:27 2009 -0800 9.3 @@ -0,0 +1,319 @@ 9.4 +/* 9.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.7 + * 9.8 + * This code is free software; you can redistribute it and/or modify it 9.9 + * under the terms of the GNU General Public License version 2 only, as 9.10 + * published by the Free Software Foundation. Sun designates this 9.11 + * particular file as subject to the "Classpath" exception as provided 9.12 + * by Sun in the LICENSE file that accompanied this code. 9.13 + * 9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.17 + * version 2 for more details (a copy is included in the LICENSE file that 9.18 + * accompanied this code). 9.19 + * 9.20 + * You should have received a copy of the GNU General Public License version 9.21 + * 2 along with this work; if not, write to the Free Software Foundation, 9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.23 + * 9.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 9.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 9.26 + * have any questions. 9.27 + */ 9.28 + 9.29 +package com.sun.tools.javac.nio; 9.30 + 9.31 +import java.io.IOException; 9.32 +import java.io.InputStream; 9.33 +import java.io.InputStreamReader; 9.34 +import java.io.OutputStream; 9.35 +import java.io.OutputStreamWriter; 9.36 +import java.io.Reader; 9.37 +import java.io.Writer; 9.38 +import java.net.URI; 9.39 +import java.nio.ByteBuffer; 9.40 +import java.nio.CharBuffer; 9.41 +import java.nio.charset.CharsetDecoder; 9.42 +import java.nio.file.Files; 9.43 +import java.nio.file.Path; 9.44 +import java.nio.file.attribute.Attributes; 9.45 +import java.nio.file.attribute.BasicFileAttributes; 9.46 +import javax.lang.model.element.Modifier; 9.47 +import javax.lang.model.element.NestingKind; 9.48 +import javax.tools.JavaFileObject; 9.49 + 9.50 +import com.sun.tools.javac.util.BaseFileManager; 9.51 + 9.52 + 9.53 +/** 9.54 + * Implementation of JavaFileObject using java.nio.file API. 9.55 + * 9.56 + * <p>PathFileObjects are, for the most part, straightforward wrappers around 9.57 + * Path objects. The primary complexity is the support for "inferBinaryName". 9.58 + * This is left as an abstract method, implemented by each of a number of 9.59 + * different factory methods, which compute the binary name based on 9.60 + * information available at the time the file object is created. 9.61 + * 9.62 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 9.63 + * you write code that depends on this, you do so at your own risk. 9.64 + * This code and its internal interfaces are subject to change or 9.65 + * deletion without notice.</b> 9.66 + */ 9.67 +abstract class PathFileObject implements JavaFileObject { 9.68 + private JavacPathFileManager fileManager; 9.69 + private Path path; 9.70 + 9.71 + /** 9.72 + * Create a PathFileObject within a directory, such that the binary name 9.73 + * can be inferred from the relationship to the parent directory. 9.74 + */ 9.75 + static PathFileObject createDirectoryPathFileObject(JavacPathFileManager fileManager, 9.76 + final Path path, final Path dir) { 9.77 + return new PathFileObject(fileManager, path) { 9.78 + @Override 9.79 + String inferBinaryName(Iterable<? extends Path> paths) { 9.80 + return toBinaryName(dir.relativize(path)); 9.81 + } 9.82 + }; 9.83 + } 9.84 + 9.85 + /** 9.86 + * Create a PathFileObject in a file system such as a jar file, such that 9.87 + * the binary name can be inferred from its position within the filesystem. 9.88 + */ 9.89 + static PathFileObject createJarPathFileObject(JavacPathFileManager fileManager, 9.90 + final Path path) { 9.91 + return new PathFileObject(fileManager, path) { 9.92 + @Override 9.93 + String inferBinaryName(Iterable<? extends Path> paths) { 9.94 + return toBinaryName(path); 9.95 + } 9.96 + }; 9.97 + } 9.98 + 9.99 + /** 9.100 + * Create a PathFileObject whose binary name can be inferred from the 9.101 + * relative path to a sibling. 9.102 + */ 9.103 + static PathFileObject createSiblingPathFileObject(JavacPathFileManager fileManager, 9.104 + final Path path, final String relativePath) { 9.105 + return new PathFileObject(fileManager, path) { 9.106 + @Override 9.107 + String inferBinaryName(Iterable<? extends Path> paths) { 9.108 + return toBinaryName(relativePath, "/"); 9.109 + } 9.110 + }; 9.111 + } 9.112 + 9.113 + /** 9.114 + * Create a PathFileObject whose binary name might be inferred from its 9.115 + * position on a search path. 9.116 + */ 9.117 + static PathFileObject createSimplePathFileObject(JavacPathFileManager fileManager, 9.118 + final Path path) { 9.119 + return new PathFileObject(fileManager, path) { 9.120 + @Override 9.121 + String inferBinaryName(Iterable<? extends Path> paths) { 9.122 + Path absPath = path.toAbsolutePath(); 9.123 + for (Path p: paths) { 9.124 + Path ap = p.toAbsolutePath(); 9.125 + if (absPath.startsWith(ap)) { 9.126 + try { 9.127 + Path rp = ap.relativize(absPath); 9.128 + if (rp != null) // maybe null if absPath same as ap 9.129 + return toBinaryName(rp); 9.130 + } catch (IllegalArgumentException e) { 9.131 + // ignore this p if cannot relativize path to p 9.132 + } 9.133 + } 9.134 + } 9.135 + return null; 9.136 + } 9.137 + }; 9.138 + } 9.139 + 9.140 + protected PathFileObject(JavacPathFileManager fileManager, Path path) { 9.141 + fileManager.getClass(); // null check 9.142 + path.getClass(); // null check 9.143 + this.fileManager = fileManager; 9.144 + this.path = path; 9.145 + } 9.146 + 9.147 + abstract String inferBinaryName(Iterable<? extends Path> paths); 9.148 + 9.149 + /** 9.150 + * Return the Path for this object. 9.151 + * @return the Path for this object. 9.152 + */ 9.153 + Path getPath() { 9.154 + return path; 9.155 + } 9.156 + 9.157 + @Override 9.158 + public Kind getKind() { 9.159 + return BaseFileManager.getKind(path.getName().toString()); 9.160 + } 9.161 + 9.162 + @Override 9.163 + public boolean isNameCompatible(String simpleName, Kind kind) { 9.164 + simpleName.getClass(); 9.165 + // null check 9.166 + if (kind == Kind.OTHER && getKind() != kind) { 9.167 + return false; 9.168 + } 9.169 + String sn = simpleName + kind.extension; 9.170 + String pn = path.getName().toString(); 9.171 + if (pn.equals(sn)) { 9.172 + return true; 9.173 + } 9.174 + if (pn.equalsIgnoreCase(sn)) { 9.175 + try { 9.176 + // allow for Windows 9.177 + return path.toRealPath(false).getName().toString().equals(sn); 9.178 + } catch (IOException e) { 9.179 + } 9.180 + } 9.181 + return false; 9.182 + } 9.183 + 9.184 + @Override 9.185 + public NestingKind getNestingKind() { 9.186 + return null; 9.187 + } 9.188 + 9.189 + @Override 9.190 + public Modifier getAccessLevel() { 9.191 + return null; 9.192 + } 9.193 + 9.194 + @Override 9.195 + public URI toUri() { 9.196 + return path.toUri(); 9.197 + } 9.198 + 9.199 + @Override 9.200 + public String getName() { 9.201 + return path.toString(); 9.202 + } 9.203 + 9.204 + @Override 9.205 + public InputStream openInputStream() throws IOException { 9.206 + return path.newInputStream(); 9.207 + } 9.208 + 9.209 + @Override 9.210 + public OutputStream openOutputStream() throws IOException { 9.211 + ensureParentDirectoriesExist(); 9.212 + return path.newOutputStream(); 9.213 + } 9.214 + 9.215 + @Override 9.216 + public Reader openReader(boolean ignoreEncodingErrors) throws IOException { 9.217 + CharsetDecoder decoder = fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors); 9.218 + return new InputStreamReader(openInputStream(), decoder); 9.219 + } 9.220 + 9.221 + @Override 9.222 + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { 9.223 + CharBuffer cb = fileManager.getCachedContent(this); 9.224 + if (cb == null) { 9.225 + InputStream in = openInputStream(); 9.226 + try { 9.227 + ByteBuffer bb = fileManager.makeByteBuffer(in); 9.228 + JavaFileObject prev = fileManager.log.useSource(this); 9.229 + try { 9.230 + cb = fileManager.decode(bb, ignoreEncodingErrors); 9.231 + } finally { 9.232 + fileManager.log.useSource(prev); 9.233 + } 9.234 + fileManager.recycleByteBuffer(bb); 9.235 + if (!ignoreEncodingErrors) { 9.236 + fileManager.cache(this, cb); 9.237 + } 9.238 + } finally { 9.239 + in.close(); 9.240 + } 9.241 + } 9.242 + return cb; 9.243 + } 9.244 + 9.245 + @Override 9.246 + public Writer openWriter() throws IOException { 9.247 + ensureParentDirectoriesExist(); 9.248 + return new OutputStreamWriter(path.newOutputStream(), fileManager.getEncodingName()); 9.249 + } 9.250 + 9.251 + @Override 9.252 + public long getLastModified() { 9.253 + try { 9.254 + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path); 9.255 + return attrs.lastModifiedTime().toMillis(); 9.256 + } catch (IOException e) { 9.257 + return -1; 9.258 + } 9.259 + } 9.260 + 9.261 + @Override 9.262 + public boolean delete() { 9.263 + try { 9.264 + path.delete(); 9.265 + return true; 9.266 + } catch (IOException e) { 9.267 + return false; 9.268 + } 9.269 + } 9.270 + 9.271 + public boolean isSameFile(PathFileObject other) { 9.272 + try { 9.273 + return path.isSameFile(other.path); 9.274 + } catch (IOException e) { 9.275 + return false; 9.276 + } 9.277 + } 9.278 + 9.279 + @Override 9.280 + public boolean equals(Object other) { 9.281 + return (other instanceof PathFileObject && path.equals(((PathFileObject) other).path)); 9.282 + } 9.283 + 9.284 + @Override 9.285 + public int hashCode() { 9.286 + return path.hashCode(); 9.287 + } 9.288 + 9.289 + @Override 9.290 + public String toString() { 9.291 + return getClass().getSimpleName() + "[" + path + "]"; 9.292 + } 9.293 + 9.294 + private void ensureParentDirectoriesExist() throws IOException { 9.295 + Path parent = path.getParent(); 9.296 + if (parent != null) 9.297 + Files.createDirectories(parent); 9.298 + } 9.299 + 9.300 + private long size() { 9.301 + try { 9.302 + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path); 9.303 + return attrs.size(); 9.304 + } catch (IOException e) { 9.305 + return -1; 9.306 + } 9.307 + } 9.308 + 9.309 + protected static String toBinaryName(Path relativePath) { 9.310 + return toBinaryName(relativePath.toString(), 9.311 + relativePath.getFileSystem().getSeparator()); 9.312 + } 9.313 + 9.314 + protected static String toBinaryName(String relativePath, String sep) { 9.315 + return removeExtension(relativePath).replaceAll(sep, "."); 9.316 + } 9.317 + 9.318 + protected static String removeExtension(String fileName) { 9.319 + int lastDot = fileName.lastIndexOf("."); 9.320 + return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); 9.321 + } 9.322 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java Fri Dec 11 14:26:27 2009 -0800 10.3 @@ -0,0 +1,355 @@ 10.4 +/* 10.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.7 + * 10.8 + * This code is free software; you can redistribute it and/or modify it 10.9 + * under the terms of the GNU General Public License version 2 only, as 10.10 + * published by the Free Software Foundation. Sun designates this 10.11 + * particular file as subject to the "Classpath" exception as provided 10.12 + * by Sun in the LICENSE file that accompanied this code. 10.13 + * 10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.17 + * version 2 for more details (a copy is included in the LICENSE file that 10.18 + * accompanied this code). 10.19 + * 10.20 + * You should have received a copy of the GNU General Public License version 10.21 + * 2 along with this work; if not, write to the Free Software Foundation, 10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 10.23 + * 10.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 10.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 10.26 + * have any questions. 10.27 + */ 10.28 + 10.29 +package com.sun.tools.javac.util; 10.30 + 10.31 +import com.sun.tools.javac.code.Source; 10.32 +import com.sun.tools.javac.main.JavacOption; 10.33 +import com.sun.tools.javac.main.OptionName; 10.34 +import com.sun.tools.javac.main.RecognizedOptions; 10.35 +import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 10.36 +import java.io.ByteArrayOutputStream; 10.37 +import java.io.Closeable; 10.38 +import java.io.IOException; 10.39 +import java.io.InputStream; 10.40 +import java.io.OutputStreamWriter; 10.41 +import java.lang.ref.SoftReference; 10.42 +import java.lang.reflect.Constructor; 10.43 +import java.net.URL; 10.44 +import java.net.URLClassLoader; 10.45 +import java.nio.ByteBuffer; 10.46 +import java.nio.CharBuffer; 10.47 +import java.nio.charset.Charset; 10.48 +import java.nio.charset.CharsetDecoder; 10.49 +import java.nio.charset.CoderResult; 10.50 +import java.nio.charset.CodingErrorAction; 10.51 +import java.nio.charset.IllegalCharsetNameException; 10.52 +import java.nio.charset.UnsupportedCharsetException; 10.53 +import java.util.Collection; 10.54 +import java.util.HashMap; 10.55 +import java.util.Iterator; 10.56 +import java.util.Map; 10.57 +import javax.tools.JavaFileObject; 10.58 +import javax.tools.JavaFileObject.Kind; 10.59 + 10.60 +/** 10.61 + * Utility methods for building a filemanager. 10.62 + * There are no references here to file-system specific objects such as 10.63 + * java.io.File or java.nio.file.Path. 10.64 + */ 10.65 +public class BaseFileManager { 10.66 + protected BaseFileManager(Charset charset) { 10.67 + this.charset = charset; 10.68 + byteBufferCache = new ByteBufferCache(); 10.69 + } 10.70 + 10.71 + /** 10.72 + * Set the context for JavacPathFileManager. 10.73 + */ 10.74 + protected void setContext(Context context) { 10.75 + log = Log.instance(context); 10.76 + options = Options.instance(context); 10.77 + classLoaderClass = options.get("procloader"); 10.78 + } 10.79 + 10.80 + /** 10.81 + * The log to be used for error reporting. 10.82 + */ 10.83 + public Log log; 10.84 + 10.85 + /** 10.86 + * User provided charset (through javax.tools). 10.87 + */ 10.88 + protected Charset charset; 10.89 + 10.90 + protected Options options; 10.91 + 10.92 + protected String classLoaderClass; 10.93 + 10.94 + protected Source getSource() { 10.95 + String sourceName = options.get(OptionName.SOURCE); 10.96 + Source source = null; 10.97 + if (sourceName != null) 10.98 + source = Source.lookup(sourceName); 10.99 + return (source != null ? source : Source.DEFAULT); 10.100 + } 10.101 + 10.102 + protected ClassLoader getClassLoader(URL[] urls) { 10.103 + ClassLoader thisClassLoader = getClass().getClassLoader(); 10.104 + 10.105 + // Bug: 6558476 10.106 + // Ideally, ClassLoader should be Closeable, but before JDK7 it is not. 10.107 + // On older versions, try the following, to get a closeable classloader. 10.108 + 10.109 + // 1: Allow client to specify the class to use via hidden option 10.110 + if (classLoaderClass != null) { 10.111 + try { 10.112 + Class<? extends ClassLoader> loader = 10.113 + Class.forName(classLoaderClass).asSubclass(ClassLoader.class); 10.114 + Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class }; 10.115 + Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes); 10.116 + return constr.newInstance(new Object[] { urls, thisClassLoader }); 10.117 + } catch (Throwable t) { 10.118 + // ignore errors loading user-provided class loader, fall through 10.119 + } 10.120 + } 10.121 + 10.122 + // 2: If URLClassLoader implements Closeable, use that. 10.123 + if (Closeable.class.isAssignableFrom(URLClassLoader.class)) 10.124 + return new URLClassLoader(urls, thisClassLoader); 10.125 + 10.126 + // 3: Try using private reflection-based CloseableURLClassLoader 10.127 + try { 10.128 + return new CloseableURLClassLoader(urls, thisClassLoader); 10.129 + } catch (Throwable t) { 10.130 + // ignore errors loading workaround class loader, fall through 10.131 + } 10.132 + 10.133 + // 4: If all else fails, use plain old standard URLClassLoader 10.134 + return new URLClassLoader(urls, thisClassLoader); 10.135 + } 10.136 + 10.137 + // <editor-fold defaultstate="collapsed" desc="Option handling"> 10.138 + public boolean handleOption(String current, Iterator<String> remaining) { 10.139 + for (JavacOption o: javacFileManagerOptions) { 10.140 + if (o.matches(current)) { 10.141 + if (o.hasArg()) { 10.142 + if (remaining.hasNext()) { 10.143 + if (!o.process(options, current, remaining.next())) 10.144 + return true; 10.145 + } 10.146 + } else { 10.147 + if (!o.process(options, current)) 10.148 + return true; 10.149 + } 10.150 + // operand missing, or process returned false 10.151 + throw new IllegalArgumentException(current); 10.152 + } 10.153 + } 10.154 + 10.155 + return false; 10.156 + } 10.157 + // where 10.158 + private static JavacOption[] javacFileManagerOptions = 10.159 + RecognizedOptions.getJavacFileManagerOptions( 10.160 + new RecognizedOptions.GrumpyHelper()); 10.161 + 10.162 + public int isSupportedOption(String option) { 10.163 + for (JavacOption o : javacFileManagerOptions) { 10.164 + if (o.matches(option)) 10.165 + return o.hasArg() ? 1 : 0; 10.166 + } 10.167 + return -1; 10.168 + } 10.169 + // </editor-fold> 10.170 + 10.171 + // <editor-fold defaultstate="collapsed" desc="Encoding"> 10.172 + private String defaultEncodingName; 10.173 + private String getDefaultEncodingName() { 10.174 + if (defaultEncodingName == null) { 10.175 + defaultEncodingName = 10.176 + new OutputStreamWriter(new ByteArrayOutputStream()).getEncoding(); 10.177 + } 10.178 + return defaultEncodingName; 10.179 + } 10.180 + 10.181 + public String getEncodingName() { 10.182 + String encName = options.get(OptionName.ENCODING); 10.183 + if (encName == null) 10.184 + return getDefaultEncodingName(); 10.185 + else 10.186 + return encName; 10.187 + } 10.188 + 10.189 + public CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { 10.190 + String encodingName = getEncodingName(); 10.191 + CharsetDecoder decoder; 10.192 + try { 10.193 + decoder = getDecoder(encodingName, ignoreEncodingErrors); 10.194 + } catch (IllegalCharsetNameException e) { 10.195 + log.error("unsupported.encoding", encodingName); 10.196 + return (CharBuffer)CharBuffer.allocate(1).flip(); 10.197 + } catch (UnsupportedCharsetException e) { 10.198 + log.error("unsupported.encoding", encodingName); 10.199 + return (CharBuffer)CharBuffer.allocate(1).flip(); 10.200 + } 10.201 + 10.202 + // slightly overestimate the buffer size to avoid reallocation. 10.203 + float factor = 10.204 + decoder.averageCharsPerByte() * 0.8f + 10.205 + decoder.maxCharsPerByte() * 0.2f; 10.206 + CharBuffer dest = CharBuffer. 10.207 + allocate(10 + (int)(inbuf.remaining()*factor)); 10.208 + 10.209 + while (true) { 10.210 + CoderResult result = decoder.decode(inbuf, dest, true); 10.211 + dest.flip(); 10.212 + 10.213 + if (result.isUnderflow()) { // done reading 10.214 + // make sure there is at least one extra character 10.215 + if (dest.limit() == dest.capacity()) { 10.216 + dest = CharBuffer.allocate(dest.capacity()+1).put(dest); 10.217 + dest.flip(); 10.218 + } 10.219 + return dest; 10.220 + } else if (result.isOverflow()) { // buffer too small; expand 10.221 + int newCapacity = 10.222 + 10 + dest.capacity() + 10.223 + (int)(inbuf.remaining()*decoder.maxCharsPerByte()); 10.224 + dest = CharBuffer.allocate(newCapacity).put(dest); 10.225 + } else if (result.isMalformed() || result.isUnmappable()) { 10.226 + // bad character in input 10.227 + 10.228 + // report coding error (warn only pre 1.5) 10.229 + if (!getSource().allowEncodingErrors()) { 10.230 + log.error(new SimpleDiagnosticPosition(dest.limit()), 10.231 + "illegal.char.for.encoding", 10.232 + charset == null ? encodingName : charset.name()); 10.233 + } else { 10.234 + log.warning(new SimpleDiagnosticPosition(dest.limit()), 10.235 + "illegal.char.for.encoding", 10.236 + charset == null ? encodingName : charset.name()); 10.237 + } 10.238 + 10.239 + // skip past the coding error 10.240 + inbuf.position(inbuf.position() + result.length()); 10.241 + 10.242 + // undo the flip() to prepare the output buffer 10.243 + // for more translation 10.244 + dest.position(dest.limit()); 10.245 + dest.limit(dest.capacity()); 10.246 + dest.put((char)0xfffd); // backward compatible 10.247 + } else { 10.248 + throw new AssertionError(result); 10.249 + } 10.250 + } 10.251 + // unreached 10.252 + } 10.253 + 10.254 + public CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { 10.255 + Charset cs = (this.charset == null) 10.256 + ? Charset.forName(encodingName) 10.257 + : this.charset; 10.258 + CharsetDecoder decoder = cs.newDecoder(); 10.259 + 10.260 + CodingErrorAction action; 10.261 + if (ignoreEncodingErrors) 10.262 + action = CodingErrorAction.REPLACE; 10.263 + else 10.264 + action = CodingErrorAction.REPORT; 10.265 + 10.266 + return decoder 10.267 + .onMalformedInput(action) 10.268 + .onUnmappableCharacter(action); 10.269 + } 10.270 + // </editor-fold> 10.271 + 10.272 + // <editor-fold defaultstate="collapsed" desc="ByteBuffers"> 10.273 + /** 10.274 + * Make a byte buffer from an input stream. 10.275 + */ 10.276 + public ByteBuffer makeByteBuffer(InputStream in) 10.277 + throws IOException { 10.278 + int limit = in.available(); 10.279 + if (limit < 1024) limit = 1024; 10.280 + ByteBuffer result = byteBufferCache.get(limit); 10.281 + int position = 0; 10.282 + while (in.available() != 0) { 10.283 + if (position >= limit) 10.284 + // expand buffer 10.285 + result = ByteBuffer. 10.286 + allocate(limit <<= 1). 10.287 + put((ByteBuffer)result.flip()); 10.288 + int count = in.read(result.array(), 10.289 + position, 10.290 + limit - position); 10.291 + if (count < 0) break; 10.292 + result.position(position += count); 10.293 + } 10.294 + return (ByteBuffer)result.flip(); 10.295 + } 10.296 + 10.297 + public void recycleByteBuffer(ByteBuffer bb) { 10.298 + byteBufferCache.put(bb); 10.299 + } 10.300 + 10.301 + /** 10.302 + * A single-element cache of direct byte buffers. 10.303 + */ 10.304 + private static class ByteBufferCache { 10.305 + private ByteBuffer cached; 10.306 + ByteBuffer get(int capacity) { 10.307 + if (capacity < 20480) capacity = 20480; 10.308 + ByteBuffer result = 10.309 + (cached != null && cached.capacity() >= capacity) 10.310 + ? (ByteBuffer)cached.clear() 10.311 + : ByteBuffer.allocate(capacity + capacity>>1); 10.312 + cached = null; 10.313 + return result; 10.314 + } 10.315 + void put(ByteBuffer x) { 10.316 + cached = x; 10.317 + } 10.318 + } 10.319 + 10.320 + private final ByteBufferCache byteBufferCache; 10.321 + // </editor-fold> 10.322 + 10.323 + // <editor-fold defaultstate="collapsed" desc="Content cache"> 10.324 + public CharBuffer getCachedContent(JavaFileObject file) { 10.325 + SoftReference<CharBuffer> r = contentCache.get(file); 10.326 + return (r == null ? null : r.get()); 10.327 + } 10.328 + 10.329 + public void cache(JavaFileObject file, CharBuffer cb) { 10.330 + contentCache.put(file, new SoftReference<CharBuffer>(cb)); 10.331 + } 10.332 + 10.333 + protected final Map<JavaFileObject, SoftReference<CharBuffer>> contentCache 10.334 + = new HashMap<JavaFileObject, SoftReference<CharBuffer>>(); 10.335 + // </editor-fold> 10.336 + 10.337 + public static Kind getKind(String name) { 10.338 + if (name.endsWith(Kind.CLASS.extension)) 10.339 + return Kind.CLASS; 10.340 + else if (name.endsWith(Kind.SOURCE.extension)) 10.341 + return Kind.SOURCE; 10.342 + else if (name.endsWith(Kind.HTML.extension)) 10.343 + return Kind.HTML; 10.344 + else 10.345 + return Kind.OTHER; 10.346 + } 10.347 + 10.348 + protected static <T> T nullCheck(T o) { 10.349 + o.getClass(); // null check 10.350 + return o; 10.351 + } 10.352 + 10.353 + protected static <T> Collection<T> nullCheck(Collection<T> it) { 10.354 + for (T t : it) 10.355 + t.getClass(); // null check 10.356 + return it; 10.357 + } 10.358 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/share/classes/com/sun/tools/javac/util/CloseableURLClassLoader.java Fri Dec 11 14:26:27 2009 -0800 11.3 @@ -0,0 +1,108 @@ 11.4 +/* 11.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. Sun designates this 11.11 + * particular file as subject to the "Classpath" exception as provided 11.12 + * by Sun in the LICENSE file that accompanied this code. 11.13 + * 11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.17 + * version 2 for more details (a copy is included in the LICENSE file that 11.18 + * accompanied this code). 11.19 + * 11.20 + * You should have received a copy of the GNU General Public License version 11.21 + * 2 along with this work; if not, write to the Free Software Foundation, 11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.23 + * 11.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 11.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 11.26 + * have any questions. 11.27 + */ 11.28 + 11.29 +package com.sun.tools.javac.util; 11.30 + 11.31 +import java.io.Closeable; 11.32 +import java.io.IOException; 11.33 +import java.lang.reflect.Field; 11.34 +import java.net.URL; 11.35 +import java.net.URLClassLoader; 11.36 +import java.util.ArrayList; 11.37 +import java.util.jar.JarFile; 11.38 + 11.39 +/** 11.40 + * A URLClassLoader that also implements Closeable. 11.41 + * Reflection is used to access internal data structures in the URLClassLoader, 11.42 + * since no public API exists for this purpose. Therefore this code is somewhat 11.43 + * fragile. Caveat emptor. 11.44 + * @throws Error if the internal data structures are not as expected. 11.45 + * 11.46 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 11.47 + * you write code that depends on this, you do so at your own risk. 11.48 + * This code and its internal interfaces are subject to change or 11.49 + * deletion without notice.</b> 11.50 + */ 11.51 +public class CloseableURLClassLoader 11.52 + extends URLClassLoader implements Closeable { 11.53 + public CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error { 11.54 + super(urls, parent); 11.55 + try { 11.56 + getLoaders(); //proactive check that URLClassLoader is as expected 11.57 + } catch (Throwable t) { 11.58 + throw new Error("cannot create CloseableURLClassLoader", t); 11.59 + } 11.60 + } 11.61 + 11.62 + /** 11.63 + * Close any jar files that may have been opened by the class loader. 11.64 + * Reflection is used to access the jar files in the URLClassLoader's 11.65 + * internal data structures. 11.66 + * @throws java.io.IOException if the jar files cannot be found for any 11.67 + * reson, or if closing the jar file itself causes an IOException. 11.68 + */ 11.69 + @Override 11.70 + public void close() throws IOException { 11.71 + try { 11.72 + for (Object l: getLoaders()) { 11.73 + if (l.getClass().getName().equals("sun.misc.URLClassPath$JarLoader")) { 11.74 + Field jarField = l.getClass().getDeclaredField("jar"); 11.75 + JarFile jar = (JarFile) getField(l, jarField); 11.76 + if (jar != null) { 11.77 + //System.err.println("CloseableURLClassLoader: closing " + jar); 11.78 + jar.close(); 11.79 + } 11.80 + } 11.81 + } 11.82 + } catch (Throwable t) { 11.83 + IOException e = new IOException("cannot close class loader"); 11.84 + e.initCause(t); 11.85 + throw e; 11.86 + } 11.87 + } 11.88 + 11.89 + private ArrayList<?> getLoaders() 11.90 + throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException 11.91 + { 11.92 + Field ucpField = URLClassLoader.class.getDeclaredField("ucp"); 11.93 + Object urlClassPath = getField(this, ucpField); 11.94 + if (urlClassPath == null) 11.95 + throw new AssertionError("urlClassPath not set in URLClassLoader"); 11.96 + Field loadersField = urlClassPath.getClass().getDeclaredField("loaders"); 11.97 + return (ArrayList<?>) getField(urlClassPath, loadersField); 11.98 + } 11.99 + 11.100 + private Object getField(Object o, Field f) 11.101 + throws IllegalArgumentException, IllegalAccessException { 11.102 + boolean prev = f.isAccessible(); 11.103 + try { 11.104 + f.setAccessible(true); 11.105 + return f.get(o); 11.106 + } finally { 11.107 + f.setAccessible(prev); 11.108 + } 11.109 + } 11.110 + 11.111 +}
12.1 --- a/src/share/classes/javax/tools/StandardJavaFileManager.java Thu Dec 10 20:35:31 2009 -0800 12.2 +++ b/src/share/classes/javax/tools/StandardJavaFileManager.java Fri Dec 11 14:26:27 2009 -0800 12.3 @@ -28,7 +28,6 @@ 12.4 import java.io.File; 12.5 import java.io.IOException; 12.6 import java.util.*; 12.7 -import java.util.concurrent.*; 12.8 12.9 /** 12.10 * File manager based on {@linkplain File java.io.File}. A common way
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/test/tools/javac/nio/compileTest/CompileTest.java Fri Dec 11 14:26:27 2009 -0800 13.3 @@ -0,0 +1,165 @@ 13.4 +/* 13.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.7 + * 13.8 + * This code is free software; you can redistribute it and/or modify it 13.9 + * under the terms of the GNU General Public License version 2 only, as 13.10 + * published by the Free Software Foundation. 13.11 + * 13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13.15 + * version 2 for more details (a copy is included in the LICENSE file that 13.16 + * accompanied this code). 13.17 + * 13.18 + * You should have received a copy of the GNU General Public License version 13.19 + * 2 along with this work; if not, write to the Free Software Foundation, 13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 13.21 + * 13.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 13.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 13.24 + * have any questions. 13.25 + */ 13.26 + 13.27 +/** 13.28 + * @test 13.29 + * @compile HelloPathWorld.java 13.30 + * @run main CompileTest 13.31 + */ 13.32 + 13.33 +import java.io.*; 13.34 +import java.nio.file.*; 13.35 +import java.util.*; 13.36 +import java.util.jar.*; 13.37 +import javax.tools.*; 13.38 + 13.39 +import com.sun.tools.javac.nio.*; 13.40 +import com.sun.tools.javac.util.Context; 13.41 +import java.nio.file.spi.FileSystemProvider; 13.42 + 13.43 + 13.44 +public class CompileTest { 13.45 + public static void main(String[] args) throws Exception { 13.46 + new CompileTest().run(); 13.47 + } 13.48 + 13.49 + public void run() throws Exception { 13.50 + File rtDir = new File("rt.dir"); 13.51 + File javaHome = new File(System.getProperty("java.home")); 13.52 + if (javaHome.getName().equals("jre")) 13.53 + javaHome = javaHome.getParentFile(); 13.54 + File rtJar = new File(new File(new File(javaHome, "jre"), "lib"), "rt.jar"); 13.55 + expand(rtJar, rtDir); 13.56 + 13.57 + String[] rtDir_opts = { 13.58 + "-bootclasspath", rtDir.toString(), 13.59 + "-classpath", "", 13.60 + "-sourcepath", "", 13.61 + "-extdirs", "" 13.62 + }; 13.63 + test(rtDir_opts, "HelloPathWorld"); 13.64 + 13.65 + if (isJarFileSystemAvailable()) { 13.66 + String[] rtJar_opts = { 13.67 + "-bootclasspath", rtJar.toString(), 13.68 + "-classpath", "", 13.69 + "-sourcepath", "", 13.70 + "-extdirs", "" 13.71 + }; 13.72 + test(rtJar_opts, "HelloPathWorld"); 13.73 + 13.74 + String[] default_opts = { }; 13.75 + test(default_opts, "HelloPathWorld"); 13.76 + 13.77 + // finally, a non-trivial program 13.78 + test(default_opts, "CompileTest"); 13.79 + } else 13.80 + System.err.println("jar file system not available: test skipped"); 13.81 + } 13.82 + 13.83 + void test(String[] opts, String className) throws Exception { 13.84 + count++; 13.85 + System.err.println("Test " + count + " " + Arrays.asList(opts) + " " + className); 13.86 + Path testSrcDir = Paths.get(System.getProperty("test.src")); 13.87 + Path testClassesDir = Paths.get(System.getProperty("test.classes")); 13.88 + Path classes = Paths.get("classes." + count); 13.89 + classes.createDirectory(); 13.90 + 13.91 + Context ctx = new Context(); 13.92 + PathFileManager fm = new JavacPathFileManager(ctx, true, null); 13.93 + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 13.94 + List<String> options = new ArrayList<String>(); 13.95 + options.addAll(Arrays.asList(opts)); 13.96 + options.addAll(Arrays.asList( 13.97 + "-verbose", "-XDverboseCompilePolicy", 13.98 + "-d", classes.toString() 13.99 + )); 13.100 + Iterable<? extends JavaFileObject> compilationUnits = 13.101 + fm.getJavaFileObjects(testSrcDir.resolve(className + ".java")); 13.102 + StringWriter sw = new StringWriter(); 13.103 + PrintWriter out = new PrintWriter(sw); 13.104 + JavaCompiler.CompilationTask t = 13.105 + compiler.getTask(out, fm, null, options, null, compilationUnits); 13.106 + boolean ok = t.call(); 13.107 + System.err.println(sw.toString()); 13.108 + if (!ok) { 13.109 + throw new Exception("compilation failed"); 13.110 + } 13.111 + 13.112 + File expect = new File("classes." + count + "/" + className + ".class"); 13.113 + if (!expect.exists()) 13.114 + throw new Exception("expected file not found: " + expect); 13.115 + long expectedSize = new File(testClassesDir.toString(), className + ".class").length(); 13.116 + long actualSize = expect.length(); 13.117 + if (expectedSize != actualSize) 13.118 + throw new Exception("wrong size found: " + actualSize + "; expected: " + expectedSize); 13.119 + } 13.120 + 13.121 + boolean isJarFileSystemAvailable() { 13.122 + boolean result = false; 13.123 + for (FileSystemProvider fsp: FileSystemProvider.installedProviders()) { 13.124 + String scheme = fsp.getScheme(); 13.125 + System.err.println("Provider: " + scheme + " " + fsp); 13.126 + if (scheme.equalsIgnoreCase("jar") || scheme.equalsIgnoreCase("zip")) 13.127 + result = true; 13.128 + } 13.129 + return result; 13.130 + } 13.131 + 13.132 + void expand(File jar, File dir) throws IOException { 13.133 + JarFile jarFile = new JarFile(jar); 13.134 + try { 13.135 + Enumeration<JarEntry> entries = jarFile.entries(); 13.136 + while (entries.hasMoreElements()) { 13.137 + JarEntry je = entries.nextElement(); 13.138 + if (!je.isDirectory()) { 13.139 + copy(jarFile.getInputStream(je), new File(dir, je.getName())); 13.140 + } 13.141 + } 13.142 + } finally { 13.143 + jarFile.close(); 13.144 + } 13.145 + } 13.146 + 13.147 + void copy(InputStream in, File dest) throws IOException { 13.148 + dest.getParentFile().mkdirs(); 13.149 + OutputStream out = new BufferedOutputStream(new FileOutputStream(dest)); 13.150 + try { 13.151 + byte[] data = new byte[8192]; 13.152 + int n; 13.153 + while ((n = in.read(data, 0, data.length)) > 0) 13.154 + out.write(data, 0, n); 13.155 + } finally { 13.156 + out.close(); 13.157 + in.close(); 13.158 + } 13.159 + } 13.160 + 13.161 + void error(String message) { 13.162 + System.err.println("Error: " + message); 13.163 + errors++; 13.164 + } 13.165 + 13.166 + int errors; 13.167 + int count; 13.168 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/test/tools/javac/nio/compileTest/HelloPathWorld.java Fri Dec 11 14:26:27 2009 -0800 14.3 @@ -0,0 +1,28 @@ 14.4 +/* 14.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.7 + * 14.8 + * This code is free software; you can redistribute it and/or modify it 14.9 + * under the terms of the GNU General Public License version 2 only, as 14.10 + * published by the Free Software Foundation. 14.11 + * 14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14.15 + * version 2 for more details (a copy is included in the LICENSE file that 14.16 + * accompanied this code). 14.17 + * 14.18 + * You should have received a copy of the GNU General Public License version 14.19 + * 2 along with this work; if not, write to the Free Software Foundation, 14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 14.21 + * 14.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 14.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 14.24 + * have any questions. 14.25 + */ 14.26 + 14.27 +class HelloPathWorld { 14.28 + public static void main(String... args) { 14.29 + System.out.println("Hello World!"); 14.30 + } 14.31 +}