1/* 2 * Copyright (c) 2006, 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 6400872 27 * @summary REGRESSION: Java Compiler cannot find jar files referenced by other 28 * @modules java.compiler 29 * jdk.compiler 30 * @run main T6400872 31 */ 32 33// ${TESTJAVA}/bin/javac -d ${TESTCLASSES} ${TESTSRC}/A.java ${TESTSRC}/B.java 34// ${TESTJAVA}/bin/jar -cfm A.jar ${TESTSRC}/A/META-INF/MANIFEST.MF -C ${TESTCLASSES} A.class 35// ${TESTJAVA}/bin/jar -cfm B.jar ${TESTSRC}/B/META-INF/MANIFEST.MF -C ${TESTCLASSES} B.class 36// ${TESTJAVA}/bin/javac -cp A.jar ${TESTSRC}/C.java 37 38import java.io.*; 39import java.nio.*; 40import java.util.*; 41import java.util.jar.*; 42import javax.tools.*; 43import javax.tools.StandardJavaFileManager.*; 44 45public class T6400872 { 46 static File testSrc = new File(System.getProperty("test.src", ".")); 47 static File testClasses = new File(System.getProperty("test.classes", ".")); 48 49 public static void main(String... args) throws Exception { 50 // compile A.java and B.java 51 compile(testClasses, null, new File(testSrc, "A.java"), new File(testSrc, "B.java")); 52 // put them in mutually referential class files 53 jar(new File("A.jar"), iterable(new File(".", "B.jar")), testClasses, new File("A.class")); 54 jar(new File("B.jar"), iterable(new File(".", "A.jar")), testClasses, new File("B.class")); 55 // verify we can successfully use the class path entries in the jar files 56 compile(new File("."), iterable(new File("A.jar")), new File(testSrc, "C.java")); 57 } 58 59 static void compile(File classOutDir, Iterable<File> classPath, File... files) 60 throws IOException { 61 System.err.println("compile..."); 62 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 63 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 64 Iterable<? extends JavaFileObject> fileObjects = 65 fm.getJavaFileObjectsFromFiles(Arrays.asList(files)); 66 67 List<String> options = new ArrayList<String>(); 68 if (classOutDir != null) { 69 options.add("-d"); 70 options.add(classOutDir.getPath()); 71 } 72 if (classPath != null) { 73 options.add("-classpath"); 74 options.add(join(classPath, File.pathSeparator)); 75 } 76 options.add("-verbose"); 77 78 JavaCompiler.CompilationTask task = 79 compiler.getTask(null, fm, null, options, null, fileObjects); 80 if (!task.call()) 81 throw new AssertionError("compilation failed"); 82 } 83 } 84 85 static void jar(File jar, Iterable<File> classPath, File base, File... files) 86 throws IOException { 87 System.err.println("jar..."); 88 Manifest m = new Manifest(); 89 if (classPath != null) { 90 Attributes mainAttrs = m.getMainAttributes(); 91 mainAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); 92 mainAttrs.put(Attributes.Name.CLASS_PATH, join(classPath, " ")); 93 } 94 OutputStream out = new BufferedOutputStream(new FileOutputStream(jar)); 95 JarOutputStream j = new JarOutputStream(out, m); 96 add(j, base, files); 97 j.close(); 98 } 99 100 static void add(JarOutputStream j, File base, File... files) throws IOException { 101 if (files == null) 102 return; 103 104 for (File f: files) 105 add(j, base, f); 106 } 107 108 static void add(JarOutputStream j, File base, File file) throws IOException { 109 File f = new File(base, file.getPath()); 110 if (f.isDirectory()) { 111 String[] children = f.list(); 112 if (children != null) 113 for (String c: children) 114 add(j, base, new File(file, c)); 115 } else { 116 JarEntry e = new JarEntry(file.getPath()); 117 e.setSize(f.length()); 118 j.putNextEntry(e); 119 j.write(read(f)); 120 j.closeEntry(); 121 } 122 123 } 124 125 static byte[] read(File f) throws IOException { 126 byte[] buf = new byte[(int) f.length()]; 127 BufferedInputStream in = new BufferedInputStream(new FileInputStream(f)); 128 int offset = 0; 129 while (offset < buf.length) { 130 int n = in.read(buf, offset, buf.length - offset); 131 if (n < 0) 132 throw new EOFException(); 133 offset += n; 134 } 135 return buf; 136 } 137 138 static <T> Iterable<T> iterable(T single) { 139 return Collections.singleton(single); 140 } 141 142 static <T> String join(Iterable<T> iter, String sep) { 143 StringBuilder p = new StringBuilder(); 144 for (T t: iter) { 145 if (p.length() > 0) 146 p.append(' '); 147 p.append(t); 148 } 149 return p.toString(); 150 } 151} 152