--- old/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java 2009-09-24 17:46:28.000000000 -0700 +++ new/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java 2009-09-24 17:46:28.000000000 -0700 @@ -45,9 +45,9 @@ * This code and its internal interfaces are subject to change or * deletion without notice. */ -class CloseableURLClassLoader +public class CloseableURLClassLoader extends URLClassLoader implements Closeable { - CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error { + public CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error { super(urls, parent); try { getLoaders(); //proactive check that URLClassLoader is as expected @@ -63,6 +63,7 @@ * @throws java.io.IOException if the jar files cannot be found for any * reson, or if closing the jar file itself causes an IOException. */ + @Override public void close() throws IOException { try { for (Object l: getLoaders()) { --- old/src/share/classes/com/sun/tools/javac/file/Paths.java 2009-09-24 17:46:28.000000000 -0700 +++ new/src/share/classes/com/sun/tools/javac/file/Paths.java 2009-09-24 17:46:28.000000000 -0700 @@ -66,7 +66,7 @@ * @param context the context * @return the Paths instance for this context */ - static Paths instance(Context context) { + public static Paths instance(Context context) { Paths instance = context.get(pathsKey); if (instance == null) instance = new Paths(context); --- old/src/share/classes/javax/tools/StandardJavaFileManager.java 2009-09-24 17:46:29.000000000 -0700 +++ new/src/share/classes/javax/tools/StandardJavaFileManager.java 2009-09-24 17:46:28.000000000 -0700 @@ -28,7 +28,6 @@ import java.io.File; import java.io.IOException; import java.util.*; -import java.util.concurrent.*; /** * File manager based on {@linkplain File java.io.File}. A common way --- /dev/null 2009-07-15 19:05:43.000000000 -0700 +++ new/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java 2009-09-24 17:46:29.000000000 -0700 @@ -0,0 +1,797 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.tools.javac.nio; + + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.lang.ref.SoftReference; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.attribute.Attributes; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import javax.lang.model.SourceVersion; +import javax.tools.FileObject; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardLocation; + +import static javax.tools.StandardLocation.*; + +import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.file.CloseableURLClassLoader; +import com.sun.tools.javac.file.Paths; +import com.sun.tools.javac.main.JavacOption; +import com.sun.tools.javac.main.OptionName; +import com.sun.tools.javac.main.RecognizedOptions; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Options; + +import static com.sun.tools.javac.main.OptionName.*; + +/** + *
This is NOT part of any API supported by Sun Microsystems. If
+ * you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.
+ */
+public class JavacPathFileManager implements PathFileManager {
+ protected FileSystem defaultFileSystem;
+
+ /**
+ * Create a JavacPathFileManager using a given context, optionally registering
+ * it as the JavaFileManager for that context.
+ */
+ public JavacPathFileManager(Context context, boolean register, Charset charset) {
+ if (register)
+ context.put(JavaFileManager.class, this);
+ this.charset = charset;
+ byteBufferCache = new ByteBufferCache();
+ pathsForLocation = new HashMap This is NOT part of any API supported by Sun Microsystems. If
+ * you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.
+ */
+public interface PathFileManager extends JavaFileManager {
+ /**
+ * Get the default file system used to create paths. If no value has been
+ * set, the default file system is {@link FileSystems#getDefault}.
+ */
+ FileSystem getDefaultFileSystem();
+
+ /**
+ * Set the default file system used to create paths.
+ * @param fs the default file system used to create any new paths.
+ */
+ void setDefaultFileSystem(FileSystem fs);
+
+ /**
+ * Get file objects representing the given files.
+ *
+ * @param paths a list of paths
+ * @return a list of file objects
+ * @throws IllegalArgumentException if the list of paths includes
+ * a directory
+ */
+ Iterable extends JavaFileObject> getJavaFileObjectsFromPaths(
+ Iterable extends Path> paths);
+
+ /**
+ * Get file objects representing the given paths.
+ * Convenience method equivalent to:
+ *
+ * This is NOT part of any API supported by Sun Microsystems. If
+ * you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.
+ */
+abstract class PathFileObject implements JavaFileObject {
+ private JavacPathFileManager fileManager;
+ private Path path;
+
+ static PathFileObject createDirectoryPathFileObject(JavacPathFileManager fileManager,
+ final Path path, final Path dir) {
+ return new PathFileObject(fileManager, path) {
+ @Override
+ String inferBinaryName(Iterable extends Path> paths) {
+ return toBinaryName(dir.relativize(path));
+ }
+ };
+ }
+
+ static PathFileObject createJarPathFileObject(JavacPathFileManager fileManager,
+ final Path path) {
+ return new PathFileObject(fileManager, path) {
+ @Override
+ String inferBinaryName(Iterable extends Path> paths) {
+ return toBinaryName(path.relativize(path));
+ }
+ };
+ }
+
+ static PathFileObject createSiblingPathFileObject(JavacPathFileManager fileManager,
+ final Path path, final String relativePath) {
+ return new PathFileObject(fileManager, path) {
+ @Override
+ String inferBinaryName(Iterable extends Path> paths) {
+ return toBinaryName(relativePath, "/");
+ }
+ };
+ }
+
+ static PathFileObject createSimplePathFileObject(JavacPathFileManager fileManager,
+ final Path path) {
+ return new PathFileObject(fileManager, path) {
+ @Override
+ String inferBinaryName(Iterable extends Path> paths) {
+ Path absPath = path.toAbsolutePath();
+ for (Path p: paths) {
+ Path ap = p.toAbsolutePath();
+ if (absPath.startsWith(ap)) {
+ try {
+ Path rp = ap.relativize(absPath);
+ if (rp != null) // maybe null if absPath same as ap
+ return toBinaryName(rp);
+ } catch (IllegalArgumentException e) {
+ // ignore this p if cannot relativize path to p
+ }
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+ protected PathFileObject(JavacPathFileManager fileManager, Path path) {
+ fileManager.getClass(); // null check
+ path.getClass(); // null check
+ this.fileManager = fileManager;
+ this.path = path;
+ }
+
+ abstract String inferBinaryName(Iterable extends Path> paths);
+
+ /**
+ * Return the Path for this object.
+ * @return the Path for this object.
+ */
+ Path getPath() {
+ return path;
+ }
+
+ @Override
+ public Kind getKind() {
+ String name = path.getName().toString();
+ if (name.endsWith(Kind.CLASS.extension))
+ return Kind.CLASS;
+ else if (name.endsWith(Kind.SOURCE.extension))
+ return Kind.SOURCE;
+ else if (name.endsWith(Kind.HTML.extension))
+ return Kind.HTML;
+ else
+ return Kind.OTHER;
+ }
+
+ @Override
+ public boolean isNameCompatible(String simpleName, Kind kind) {
+ simpleName.getClass();
+ // null check
+ if (kind == Kind.OTHER && getKind() != kind) {
+ return false;
+ }
+ String sn = simpleName + kind.extension;
+ String pn = path.getName().toString();
+ if (pn.equals(sn)) {
+ return true;
+ }
+ if (pn.equalsIgnoreCase(sn)) {
+ try {
+ // allow for Windows
+ return path.toRealPath(false).getName().toString().equals(sn);
+ } catch (IOException e) {
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public NestingKind getNestingKind() {
+ return null;
+ }
+
+ @Override
+ public Modifier getAccessLevel() {
+ return null;
+ }
+
+ @Override
+ public URI toUri() {
+ return path.toUri();
+ }
+
+ @Override
+ public String getName() {
+ return path.toString();
+ }
+
+ @Override
+ public InputStream openInputStream() throws IOException {
+ InputStream in = path.newInputStream();
+ //return path.newInputStream();
+ // Currently, the stream obtained from path.newInputStream returns 0
+ // for available(), which causes downstream problems for javac.
+ return new FilterInputStream(in) {
+ @Override
+ public int available() throws IOException {
+ return ((int) size());
+ }
+ };
+ }
+
+ @Override
+ public OutputStream openOutputStream() throws IOException {
+ ensureParentDirectoriesExist();
+ return path.newOutputStream();
+ }
+
+ @Override
+ public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
+ CharsetDecoder decoder = fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
+ return new InputStreamReader(openInputStream(), decoder);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ CharBuffer cb = fileManager.getCachedContent(this);
+ if (cb == null) {
+ InputStream in = openInputStream();
+ try {
+ ByteBuffer bb = fileManager.makeByteBuffer(in);
+ JavaFileObject prev = fileManager.log.useSource(this);
+ try {
+ cb = fileManager.decode(bb, ignoreEncodingErrors);
+ } finally {
+ fileManager.log.useSource(prev);
+ }
+ fileManager.recycleByteBuffer(bb);
+ if (!ignoreEncodingErrors) {
+ fileManager.cache(this, cb);
+ }
+ } finally {
+ in.close();
+ }
+ }
+ return cb;
+ }
+
+ @Override
+ public Writer openWriter() throws IOException {
+ ensureParentDirectoriesExist();
+ return new OutputStreamWriter(path.newOutputStream(), fileManager.getEncodingName());
+ }
+
+ @Override
+ public long getLastModified() {
+ try {
+ BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
+ return attrs.lastModifiedTime().toMillis();
+ } catch (IOException e) {
+ return -1;
+ }
+ }
+
+ @Override
+ public boolean delete() {
+ try {
+ path.delete();
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ public boolean isSameFile(PathFileObject other) {
+ try {
+ return path.isSameFile(other.path);
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return (other instanceof PathFileObject && path.equals(((PathFileObject) other).path));
+ }
+
+ @Override
+ public int hashCode() {
+ return path.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + path + "]";
+ }
+
+ private void ensureParentDirectoriesExist() throws IOException {
+ Path parent = path.getParent();
+ if (parent != null)
+ Files.createDirectories(parent);
+ }
+
+ private long size() {
+ try {
+ BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
+ return attrs.size();
+ } catch (IOException e) {
+ return -1;
+ }
+ }
+
+ protected static String toBinaryName(Path relativePath) {
+ return toBinaryName(relativePath.toString(),
+ relativePath.getFileSystem().getSeparator());
+ }
+
+ protected static String toBinaryName(String relativePath, String sep) {
+ return removeExtension(relativePath).replaceAll(sep, ".");
+ }
+
+ protected static String removeExtension(String fileName) {
+ int lastDot = fileName.lastIndexOf(".");
+ return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
+ }
+}
--- /dev/null 2009-07-15 19:05:43.000000000 -0700
+++ new/test/tools/javac/nio/compileTest/CompileTest.java 2009-09-24 17:46:30.000000000 -0700
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @compile HelloPathWorld.java
+ * @run main CompileTest
+ */
+
+import java.io.*;
+import java.nio.file.*;
+import java.util.*;
+import java.util.jar.*;
+import javax.tools.*;
+
+import com.sun.tools.javac.nio.*;
+import com.sun.tools.javac.util.Context;
+import java.nio.file.spi.FileSystemProvider;
+
+
+public class CompileTest {
+ public static void main(String[] args) throws Exception {
+ new CompileTest().run();
+ }
+
+ public void run() throws Exception {
+ File rtDir = new File("rt.dir");
+ File javaHome = new File(System.getProperty("java.home"));
+ if (javaHome.getName().equals("jre"))
+ javaHome = javaHome.getParentFile();
+ File rtJar = new File(new File(new File(javaHome, "jre"), "lib"), "rt.jar");
+ expand(rtJar, rtDir);
+
+ String[] rtDir_opts = {
+ "-bootclasspath", rtDir.toString(),
+ "-classpath", "",
+ "-sourcepath", "",
+ "-extdirs", ""
+ };
+ test(rtDir_opts, "HelloPathWorld");
+
+ if (isJarFileSystemAvailable()) {
+ String[] rtJar_opts = {
+ "-bootclasspath", rtJar.toString(),
+ "-classpath", "",
+ "-sourcepath", "",
+ "-extdirs", ""
+ };
+ test(rtJar_opts, "HelloPathWorld");
+
+ String[] default_opts = { };
+ test(default_opts, "HelloPathWorld");
+
+ // finally, a non-trivial program
+ test(default_opts, "CompileTest");
+ } else
+ System.err.println("jar file system not available: test skipped");
+ }
+
+ void test(String[] opts, String className) throws Exception {
+ count++;
+ System.err.println("Test " + count + " " + Arrays.asList(opts) + " " + className);
+ Path testSrcDir = Paths.get(System.getProperty("test.src"));
+ Path testClassesDir = Paths.get(System.getProperty("test.classes"));
+ Path classes = Paths.get("classes." + count);
+ classes.createDirectory();
+
+ Context ctx = new Context();
+ PathFileManager fm = new JavacPathFileManager(ctx, true, null);
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ List
+ * getJavaFileObjectsFromPaths({@linkplain java.util.Arrays#asList Arrays.asList}(paths))
+ *
+ *
+ * @param paths an array of paths
+ * @return a list of file objects
+ * @throws IllegalArgumentException if the array of files includes
+ * a directory
+ * @throws NullPointerException if the given array contains null
+ * elements
+ */
+ Iterable extends JavaFileObject> getJavaFileObjects(Path... paths);
+
+ /**
+ * Return the Path for a file object that has been obtained from this
+ * file manager.
+ *
+ * @param fo A file object that has been obtained from this file manager.
+ * @return The underlying Path object.
+ * @throws IllegalArgumentException is the file object was not obtained from
+ * from this file manager.
+ */
+ Path getPath(FileObject fo);
+
+ /**
+ * Get the search path associated with the given location.
+ *
+ * @param location a location
+ * @return a list of paths or {@code null} if this location has no
+ * associated search path
+ * @see #setLocation
+ */
+ Iterable extends Path> getLocation(Location location);
+
+ /**
+ * Associate the given search path with the given location. Any
+ * previous value will be discarded.
+ *
+ * @param location a location
+ * @param searchPath a list of files, if {@code null} use the default
+ * search path for this location
+ * @see #getLocation
+ * @throws IllegalArgumentException if location is an output
+ * location and searchpath does not contain exactly one element
+ * @throws IOException if location is an output location and searchpath
+ * does not represent an existing directory
+ */
+ void setLocation(Location location, Iterable extends Path> searchPath) throws IOException;
+}
--- /dev/null 2009-07-15 19:05:43.000000000 -0700
+++ new/src/share/classes/com/sun/tools/javac/nio/PathFileObject.java 2009-09-24 17:46:30.000000000 -0700
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.javac.nio;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharsetDecoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.Attributes;
+import java.nio.file.attribute.BasicFileAttributes;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.NestingKind;
+import javax.tools.JavaFileObject;
+
+
+/**
+ * Implementation of JavaFileObject using java.nio.file API.
+ *
+ *