1 /* 2 * Copyright (c) 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 import java.io.File; 24 import java.io.IOException; 25 import java.util.ArrayList; 26 import java.util.List; 27 28 /* 29 * @test 30 * @bug 8066272 31 * @summary tests a simple multi-versioned jar file 32 * @compile -XDignore.symbol.file Utils.java MultiVersion.java 33 * @run main MultiVersion 34 * @author ksrini 35 */ 36 37 public class MultiVersion { 38 private static final File cwd = new File("."); 39 private static int pass = 0; 40 private static int fail = 0; 41 42 public static void main(String... args) throws Exception { 43 new MultiVersion().run(); 44 } 45 46 void run() throws Exception { 47 List<TestCase> testCases = new ArrayList<>(); 48 testCases.add(new TestCase1()); 49 testCases.add(new TestCase2()); 50 for (TestCase tc : testCases) { 51 tc.run(); 52 } 53 if (fail > 0) { 54 throw new Exception(fail + "/" + testCases.size() + " tests fails"); 55 } else { 56 System.out.println("All tests(" + pass + ") passes"); 57 } 58 } 59 60 /* 61 * An abstract class to eliminate test boiler plating. 62 */ 63 static abstract class TestCase { 64 final File tcwd; 65 final File metaInfDir; 66 final File versionsDir; 67 final File manifestFile; 68 69 TestCase(String directory) throws IOException { 70 System.out.println("initializing directories"); 71 tcwd = new File(cwd, directory); 72 metaInfDir = mkdir(new File(tcwd, "META-INF")); 73 versionsDir = mkdir(new File(metaInfDir, "versions")); 74 manifestFile = new File(metaInfDir, "manifest.mf"); 75 List<String> scratch = new ArrayList<>(); 76 scratch.add("Multi-Release: true"); 77 Utils.createFile(manifestFile, scratch); 78 } 79 80 File mkdir(File f) throws IOException { 81 if (f.exists() && f.isDirectory() && f.canRead() && f.canWrite()) { 82 return f; 83 } 84 if (!f.mkdirs()) { 85 throw new IOException("mkdirs failed: " + f.getAbsolutePath()); 86 } 87 return f; 88 } 89 90 abstract void emitClassFiles() throws Exception; 91 92 void run() { 93 try { 94 emitClassFiles(); 95 // jar the file up 96 File testFile = new File(tcwd, "test" + Utils.JAR_FILE_EXT); 97 Utils.jar("cvfm", 98 testFile.getAbsolutePath(), 99 manifestFile.getAbsolutePath(), 100 "-C", 101 tcwd.getAbsolutePath(), 102 "."); 103 104 File outFile = new File(tcwd, "test-repacked" + Utils.JAR_FILE_EXT); 105 List<String> cmdsList = new ArrayList<>(); 106 107 cmdsList.add(Utils.getPack200Cmd()); 108 cmdsList.add("-J-ea"); 109 cmdsList.add("-J-esa"); 110 cmdsList.add("-v"); 111 cmdsList.add("--repack"); 112 cmdsList.add(outFile.getAbsolutePath()); 113 cmdsList.add(testFile.getAbsolutePath()); 114 List<String> output = Utils.runExec(cmdsList); 115 Utils.doCompareVerify(testFile.getAbsoluteFile(), outFile.getAbsoluteFile()); 116 pass++; 117 } catch (Exception e) { 118 e.printStackTrace(System.err); 119 fail++; 120 } 121 } 122 } 123 124 static class TestCase1 extends TestCase { 125 private TestCase1(String directory) throws IOException { 126 super(directory); 127 } 128 129 public TestCase1() throws Exception { 130 this("case1"); 131 } 132 133 @Override 134 void emitClassFiles() throws Exception { 135 emitClassFile(""); 136 emitClassFile("6.0"); 137 emitClassFile("7.0"); 138 emitClassFile("8.0"); 139 } 140 141 /* 142 * Adds different variants of types 143 */ 144 void emitClassFile(String version) throws IOException { 145 final File outDir = mkdir(version.isEmpty() 146 ? tcwd 147 : new File(versionsDir, version)); 148 149 final File srcDir = mkdir(version.isEmpty() 150 ? new File(tcwd, "src") 151 : new File(new File(versionsDir, version), "src")); 152 153 final String fname = "Foo"; 154 final File srcFile = new File(srcDir, fname + Utils.JAVA_FILE_EXT); 155 List<String> scratch = new ArrayList<>(); 156 157 scratch.add("package pkg;"); 158 switch (version) { 159 case "6.0": 160 scratch.add("public class Foo {"); 161 scratch.add("public static final class Bar {}"); 162 break; 163 case "7.0": 164 scratch.add("public abstract class Foo {"); 165 scratch.add("public final class Bar {}"); 166 break; 167 case "8.0": 168 scratch.add("public interface Foo {"); 169 scratch.add("public final class Bar {}"); 170 break; 171 default: 172 scratch.add("public class Foo {"); 173 scratch.add("public final class Bar {}"); 174 break; 175 } 176 scratch.add("}"); 177 178 Utils.createFile(srcFile, scratch); 179 Utils.compiler("-d", 180 outDir.getAbsolutePath(), 181 srcFile.getAbsolutePath()); 182 } 183 } 184 185 static class TestCase2 extends TestCase { 186 private TestCase2(String directory) throws IOException { 187 super(directory); 188 } 189 190 TestCase2() throws Exception { 191 this("case2"); 192 } 193 194 @Override 195 void emitClassFiles() throws Exception { 196 emitClassFile(""); 197 emitClassFile("8.0"); 198 } 199 200 /* 201 * Adds different variants of types and tries to invoke an 202 * interface or concrete method defined by them. 203 */ 204 void emitClassFile(String version) throws IOException { 205 206 final File outDir = mkdir(version.isEmpty() 207 ? tcwd 208 : new File(versionsDir, version)); 209 210 final File srcDir = mkdir(version.isEmpty() 211 ? new File(tcwd, "src") 212 : new File(new File(versionsDir, version), "src")); 213 214 List<String> scratch = new ArrayList<>(); 215 final String fname1 = "Ab"; 216 final File srcFile1 = new File(srcDir, fname1 + Utils.JAVA_FILE_EXT); 217 218 final String fname2 = "AbNormal"; 219 final File srcFile2 = new File(srcDir, fname2 + Utils.JAVA_FILE_EXT); 220 switch (version) { 221 case "8.0": 222 scratch.clear(); 223 scratch.add("import java.io.IOException;"); 224 scratch.add("public interface " + fname1 + "{"); 225 scratch.add(" public abstract void close() throws IOException ;"); 226 scratch.add("}"); 227 Utils.createFile(srcFile1, scratch); 228 break; 229 default: 230 scratch.clear(); 231 scratch.add("import java.io.IOException;"); 232 scratch.add("public abstract class " + fname1 + "{"); 233 scratch.add(" public abstract void close() throws IOException ;"); 234 scratch.add("}"); 235 Utils.createFile(srcFile1, scratch); 236 } 237 238 scratch.clear(); 239 scratch.add("import java.io.IOException;"); 240 scratch.add("public class " + fname2 + "{"); 241 scratch.add(" public void doSomething(Ab ab) throws IOException {"); 242 scratch.add(" ab.close();"); 243 scratch.add(" }"); 244 scratch.add("}"); 245 246 Utils.createFile(srcFile2, scratch); 247 Utils.compiler("-d", 248 outDir.getAbsolutePath(), 249 srcFile1.getAbsolutePath(), 250 srcFile2.getAbsolutePath()); 251 } 252 } 253 }