1/*
2 * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 6638501
27 * @summary REGRESSION:  Java Compiler cannot find jar files referenced by other
28 * @modules jdk.compiler
29 * @run main JarFromManifestFailure
30 */
31
32import java.io.*;
33import java.nio.*;
34import java.util.*;
35import java.util.jar.*;
36import javax.tools.*;
37import javax.tools.StandardJavaFileManager.*;
38
39public class JarFromManifestFailure {
40    static File testSrc = new File(System.getProperty("test.src", "."));
41    static File testClasses = new File(System.getProperty("test.classes", "."));
42
43    public static void main(String... args) throws Exception {
44        compile(testClasses, null, new File(testSrc, "HelloLib/test/HelloImpl.java"), new File(testSrc, "WsCompileExample.java"));
45        File libFile = new File(testClasses, "lib");
46        libFile.mkdir();
47        jar(new File(libFile, "HelloLib.jar"), new ArrayList(), testClasses, new File("test"));
48
49        ArrayList arList = new ArrayList();
50        arList.add(new File("HelloLib.jar"));
51        jar(new File(libFile, "JarPointer.jar"), arList, testClasses);
52
53        String[] args1 = {
54            "-d", ".",
55            "-cp", new File(libFile, "JarPointer.jar").getPath().replace('\\', '/'),
56            new File(testSrc, "test/SayHello.java").getPath().replace('\\', '/')
57        };
58        System.err.println("First compile!!!");
59        if (com.sun.tools.javac.Main.compile(args1) != 0) {
60            throw new AssertionError("Failure in first compile!");
61        }
62
63        System.err.println("Second compile!!!");
64
65        args1 = new String[] {
66            "-d", ".",
67            "-cp", new File(libFile, "JarPointer.jar").getPath().replace('\\', '/'),
68            new File(testSrc, "test1/SayHelloToo.java").getPath().replace('\\', '/')
69        };
70        if (com.sun.tools.javac.Main.compile(args1) != 0) {
71            throw new AssertionError("Failure in second compile!");
72        }
73    }
74
75    static void compile(File classOutDir, Iterable<File> classPath, File... files) throws IOException {
76        System.err.println("compile...");
77        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
78        try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
79            Iterable<? extends JavaFileObject> fileObjects =
80                        fm.getJavaFileObjectsFromFiles(Arrays.asList(files));
81
82            List<String> options = new ArrayList<String>();
83            if (classOutDir != null) {
84                options.add("-d");
85                options.add(classOutDir.getPath());
86            }
87            if (classPath != null) {
88                options.add("-classpath");
89                options.add(join(classPath, File.pathSeparator));
90            }
91            options.add("-verbose");
92
93            JavaCompiler.CompilationTask task =
94                compiler.getTask(null, fm, null, options, null, fileObjects);
95            if (!task.call())
96                throw new AssertionError("compilation failed");
97        }
98    }
99
100    static void jar(File jar, Iterable<File> classPath, File base, File... files)
101            throws IOException {
102        System.err.println("jar...");
103        Manifest m = new Manifest();
104        if (classPath != null) {
105            Attributes mainAttrs = m.getMainAttributes();
106            mainAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
107            mainAttrs.put(Attributes.Name.CLASS_PATH, join(classPath, " "));
108        }
109        OutputStream out = new BufferedOutputStream(new FileOutputStream(jar));
110        JarOutputStream j = new JarOutputStream(out, m);
111        add(j, base, files);
112        j.close();
113    }
114
115    static void add(JarOutputStream j, File base, File... files) throws IOException {
116        if (files == null)
117            return;
118
119        for (File f: files)
120            add(j, base, f);
121    }
122
123    static void add(JarOutputStream j, File base, File file) throws IOException {
124        File f = new File(base, file.getPath());
125        if (f.isDirectory()) {
126            JarEntry e = new JarEntry(new String(file.getPath() + File.separator).replace('\\', '/'));
127            e.setSize(file.length());
128            j.putNextEntry(e);
129            String[] children = f.list();
130            if (children != null) {
131                for (String c: children) {
132                    add(j, base, new File(file, c));
133                }
134            }
135        } else {
136            JarEntry e = new JarEntry(file.getPath().replace('\\', '/'));
137            e.setSize(f.length());
138            j.putNextEntry(e);
139            j.write(read(f));
140            j.closeEntry();
141        }
142
143    }
144
145    static byte[] read(File f) throws IOException {
146        byte[] buf = new byte[(int) f.length()];
147        BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
148        int offset = 0;
149        while (offset < buf.length) {
150            int n = in.read(buf, offset, buf.length - offset);
151            if (n < 0)
152                throw new EOFException();
153            offset += n;
154        }
155        return buf;
156    }
157
158    static <T> Iterable<T> iterable(T single) {
159        return Collections.singleton(single);
160    }
161
162    static <T> String join(Iterable<T> iter, String sep) {
163        StringBuilder p = new StringBuilder();
164        for (T t: iter) {
165            if (p.length() > 0)
166                p.append(' ');
167            p.append(t);
168        }
169        return p.toString();
170    }
171}
172