ExplodedImage.java revision 3294:9adfb22ff08f
150477Speter/*
2139749Simp * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
380313Smjacob * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
499599Smjacob *
535388Smjacob * This code is free software; you can redistribute it and/or modify it
635388Smjacob * under the terms of the GNU General Public License version 2 only, as
735388Smjacob * published by the Free Software Foundation.
835388Smjacob *
935388Smjacob * This code is distributed in the hope that it will be useful, but WITHOUT
1035388Smjacob * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1135388Smjacob * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1266189Smjacob * version 2 for more details (a copy is included in the LICENSE file that
1366189Smjacob * accompanied this code).
1435388Smjacob *
1535388Smjacob * You should have received a copy of the GNU General Public License version
1635388Smjacob * 2 along with this work; if not, write to the Free Software Foundation,
1735388Smjacob * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1835388Smjacob *
1935388Smjacob * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2035388Smjacob * or visit www.oracle.com if you need additional information or have any
2135388Smjacob * questions.
2235388Smjacob */
2335388Smjacob
2435388Smjacobimport com.sun.source.util.JavacTask;
2535388Smjacobimport com.sun.tools.javac.code.Symbol.ClassSymbol;
2635388Smjacobimport java.io.File;
2735388Smjacobimport java.io.IOException;
2835388Smjacobimport java.io.InputStream;
2935388Smjacobimport java.net.URI;
3058100Smjacobimport java.nio.file.DirectoryStream;
3180313Smjacobimport java.nio.file.FileSystems;
3239235Sgibbsimport java.nio.file.Files;
3339445Smjacobimport java.nio.file.Path;
3448487Smjacobimport java.util.Arrays;
3595533Smikeimport java.util.EnumSet;
3648487Smjacobimport java.util.List;
3748487Smjacobimport javax.lang.model.element.TypeElement;
3874914Sjhbimport javax.tools.Diagnostic;
3959452Smjacobimport javax.tools.DiagnosticListener;
4067365Sjhbimport javax.tools.JavaCompiler;
4177365Smjacobimport javax.tools.JavaFileObject;
4262496Smjacobimport javax.tools.StandardJavaFileManager;
4373246Smjacobimport javax.tools.StandardLocation;
4439445Smjacobimport javax.tools.ToolProvider;
4548487Smjacob
4648487Smjacob/**
4762496Smjacob * @test
4839445Smjacob * @bug 8067138
4948487Smjacob * @summary Verify that compiling against the exploded JDK image works, and that Locations close
5048487Smjacob *          the directory streams properly when working with exploded JDK image.
5148487Smjacob * @library /tools/lib
5248487Smjacob * @modules jdk.compiler/com.sun.tools.javac.api
5348487Smjacob *          jdk.compiler/com.sun.tools.javac.code
5448487Smjacob *          jdk.compiler/com.sun.tools.javac.file
5548487Smjacob *          jdk.compiler/com.sun.tools.javac.main
5648487Smjacob *          jdk.jdeps/com.sun.tools.javap
5748487Smjacob * @build ToolBox ExplodedImage
5848487Smjacob * @run main/othervm ExplodedImage modules/* testDirectoryStreamClosed
5952348Smjacob * @run main/othervm ExplodedImage modules/* testCanCompileAgainstExplodedImage
6048487Smjacob */
61102272Smjacob
62135594Smjacobpublic class ExplodedImage {
63135594Smjacob    public static void main(String... args) throws IOException {
64135594Smjacob        new ExplodedImage().run(args);
65102272Smjacob    }
6687635Smjacob
6787635Smjacob    void run(String... args) throws IOException {
6887635Smjacob        switch (args[0]) {
69153072Sru            case "testDirectoryStreamClosed":
7087635Smjacob                testDirectoryStreamClosed(args[1]);
7187635Smjacob                break;
7287635Smjacob            case "testCanCompileAgainstExplodedImage":
7387635Smjacob                testCanCompileAgainstExplodedImage(args[1]);
7439235Sgibbs                break;
7577365Smjacob        }
76121317Smjacob    }
7777365Smjacob
78100680Smjacob    void testDirectoryStreamClosed(String loc) throws IOException {
79100680Smjacob        System.err.println("testDirectoryStreamClosed(" + loc + ")");
80100680Smjacob        Path javaHome = prepareJavaHome();
81100680Smjacob        Path targetPath = javaHome.resolve(loc.replace("*", "/java.base").replace("/", sep));
82100680Smjacob        Path testClass = targetPath.resolve(("java/lang/" + TEST_FILE).replace("/", sep));
83100680Smjacob        Files.createDirectories(testClass.getParent());
8492739Salfred        Files.createFile(testClass);
8555366Smjacob        System.setProperty("java.home", javaHome.toString());
8655366Smjacob
8787635Smjacob        for (int i = 0; i < REPEATS; i++) {
8884242Smjacob            try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) {
8984242Smjacob                Iterable<JavaFileObject> javaLangContent =
9084242Smjacob                        fm.list(StandardLocation.PLATFORM_CLASS_PATH,
9184242Smjacob                                "java.lang",
9284242Smjacob                                EnumSet.allOf(JavaFileObject.Kind.class),
9398288Smjacob                                false);
9498288Smjacob                boolean found = false;
9598288Smjacob
9684242Smjacob                for (JavaFileObject fo : javaLangContent) {
9798288Smjacob                    if (!fo.getName().endsWith(TEST_FILE)) {
9898288Smjacob                        throw new IllegalStateException("Wrong file: " + fo);
9998288Smjacob                    }
10098288Smjacob                    found = true;
10198288Smjacob                }
10298288Smjacob
10384242Smjacob                if (!found)
10455366Smjacob                    throw new IllegalStateException("Could not find the expected file!");
10555366Smjacob            }
10655366Smjacob        }
10755366Smjacob
10855366Smjacob        System.err.println("finished.");
10955366Smjacob    }
11075198Smjacob    //where:
11155366Smjacob        static final String TEST_FILE = "ExplodedImageTestFile.class";
11298288Smjacob        static final int REPEATS = 16 * 1024 + 1;
113125548Smjacob
11455366Smjacob    void testCanCompileAgainstExplodedImage(String loc) throws IOException {
11555366Smjacob        System.err.println("testCanCompileAgainstExplodedImage(" + loc + ")");
11675198Smjacob        Path javaHome = prepareJavaHome();
11775198Smjacob        Path targetPath = javaHome.resolve(loc.replace("*", "/java.base").replace("/", sep));
11875198Smjacob        try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) {
11975198Smjacob            for (String pack : REQUIRED_PACKAGES) {
12075198Smjacob                Iterable<JavaFileObject> content = fm.list(StandardLocation.PLATFORM_CLASS_PATH,
12155366Smjacob                                                           pack,
12255366Smjacob                                                           EnumSet.allOf(JavaFileObject.Kind.class),
12335388Smjacob                                                           false);
12455366Smjacob
12573246Smjacob                for (JavaFileObject jfo : content) {
12673246Smjacob                    String name = jfo.getName();
12799598Smjacob                    int lastSlash = name.lastIndexOf('/');
12873246Smjacob                    name = lastSlash >= 0 ? name.substring(lastSlash + 1) : name;
12948487Smjacob                    Path target = targetPath.resolve(pack.replace(".", sep) + sep + name);
13048487Smjacob                    Files.createDirectories(target.getParent());
13148487Smjacob                    try (InputStream in = jfo.openInputStream()) {
13248487Smjacob                        Files.copy(in, target);
13362496Smjacob                    }
13499598Smjacob                }
13599598Smjacob            }
13699598Smjacob        }
13799598Smjacob
13899598Smjacob        System.setProperty("java.home", javaHome.toString());
13999598Smjacob
14067258Smjacob        try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) {
14177365Smjacob            DiagnosticListener<JavaFileObject> noErrors = d -> {
14277365Smjacob                if (d.getKind() == Diagnostic.Kind.ERROR)
14393706Smjacob                    throw new IllegalStateException("Unexpected error: " + d);
14493706Smjacob            };
14593706Smjacob            ToolBox.JavaSource inputFile =
14693706Smjacob                    new ToolBox.JavaSource("import java.util.List; class Test { List l; }");
14755366Smjacob            List<JavaFileObject> inputFiles = Arrays.asList(inputFile);
14883025Smjacob            boolean result =
14983025Smjacob                    javaCompiler.getTask(null, fm, noErrors, null, null, inputFiles).call();
15083025Smjacob            if (!result) {
151125596Smjacob                throw new IllegalStateException("Could not compile correctly!");
152125596Smjacob            }
15375198Smjacob            JavacTask task =
15455366Smjacob                    (JavacTask) javaCompiler.getTask(null, fm, noErrors, null, null, inputFiles);
15584242Smjacob            task.parse();
15655366Smjacob            TypeElement juList = task.getElements().getTypeElement("java.util.List");
15735388Smjacob            if (juList == null)
15839235Sgibbs                throw new IllegalStateException("Cannot resolve java.util.List!");
15977365Smjacob            URI listSource = ((ClassSymbol) juList).classfile.toUri();
16077365Smjacob            if (!listSource.toString().startsWith(javaHome.toUri().toString()))
16164092Smjacob                throw new IllegalStateException(  "Did not load java.util.List from correct place, " +
16269525Smjacob                                                  "actual location: " + listSource.toString() +
16369525Smjacob                                                "; expected prefix: " + javaHome.toUri());
16469525Smjacob        }
165102884Smjacob
16677365Smjacob        System.err.println("finished.");
16777365Smjacob    }
16877365Smjacob    //where:
16977365Smjacob        static final String[] REQUIRED_PACKAGES = {"java.lang", "java.io", "java.util"};
17077365Smjacob
17177365Smjacob    Path prepareJavaHome() throws IOException {
172102884Smjacob        Path javaHome = new File("javahome").getAbsoluteFile().toPath();
173102884Smjacob        delete(javaHome);
174102884Smjacob        Files.createDirectory(javaHome);
175102884Smjacob        return javaHome;
176102884Smjacob    }
177102884Smjacob
17869525Smjacob    String sep = FileSystems.getDefault().getSeparator();
17969525Smjacob    JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
18064092Smjacob    String originalJavaHome = System.getProperty("java.home");
18164092Smjacob
18248487Smjacob    void delete(Path p) throws IOException {
18364092Smjacob        if (!Files.exists(p))
18448487Smjacob            return ;
18593837Smjacob        if (Files.isDirectory(p)) {
18645284Smjacob            try (DirectoryStream<Path> dir = Files.newDirectoryStream(p)) {
18764092Smjacob                for (Path child : dir) {
18864092Smjacob                    delete(child);
18964092Smjacob                }
19064092Smjacob            }
19169598Smjacob        }
19269598Smjacob        Files.delete(p);
19369598Smjacob    }
19469598Smjacob}
19569598Smjacob