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(tcwd, "manifest.tmp"); 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 File outFile = new File(tcwd, "test-repacked" + Utils.JAR_FILE_EXT); 104 List<String> cmdsList = new ArrayList<>(); 105 106 cmdsList.add(Utils.getPack200Cmd()); 107 cmdsList.add("-J-ea"); 108 cmdsList.add("-J-esa"); 109 cmdsList.add("-v"); 110 cmdsList.add("--repack"); 111 cmdsList.add(outFile.getAbsolutePath()); 112 cmdsList.add(testFile.getAbsolutePath()); 113 List<String> output = Utils.runExec(cmdsList); 114 Utils.doCompareVerify(testFile.getAbsoluteFile(), outFile.getAbsoluteFile()); 115 pass++; 116 } catch (Exception e) { 117 e.printStackTrace(System.err); 118 fail++; 119 } 120 } 121 } 122 123 static class TestCase1 extends TestCase { 124 private TestCase1(String directory) throws IOException { 125 super(directory); 126 } 127 128 public TestCase1() throws Exception { 129 this("case1"); 130 } 131 132 @Override 133 void emitClassFiles() throws Exception { 134 emitClassFile(""); 135 emitClassFile("7"); 136 emitClassFile("8"); 137 emitClassFile("9"); 138 } 139 140 /* 141 * Adds different variants of types 142 */ 143 void emitClassFile(String version) throws IOException { 144 final File outDir = mkdir(version.isEmpty() 145 ? tcwd 146 : new File(versionsDir, version)); 147 148 final File srcDir = mkdir(version.isEmpty() 149 ? new File(tcwd, "src") 150 : new File(new File(versionsDir, version), "src")); 151 152 final String fname = "Foo"; 153 final File srcFile = new File(srcDir, fname + Utils.JAVA_FILE_EXT); 154 List<String> scratch = new ArrayList<>(); 155 156 scratch.add("package pkg;"); 157 switch (version) { 158 case "7": 159 scratch.add("public class Foo {"); 160 scratch.add("public static final class Bar {}"); 161 break; 162 case "8": 163 scratch.add("public abstract class Foo {"); 164 scratch.add("public final class Bar {}"); 165 break; 166 case "9": 167 scratch.add("public interface Foo {"); 168 scratch.add("public final class Bar {}"); 169 break; 170 default: 171 scratch.add("public class Foo {"); 172 scratch.add("public final class Bar {}"); 173 break; 174 } 175 scratch.add("}"); 176 177 Utils.createFile(srcFile, scratch); 178 Utils.compiler("-d", 179 outDir.getAbsolutePath(), 180 srcFile.getAbsolutePath()); 181 } 182 } 183 184 static class TestCase2 extends TestCase { 185 private TestCase2(String directory) throws IOException { 186 super(directory); 187 } 188 189 TestCase2() throws Exception { 190 this("case2"); 191 } 192 193 @Override 194 void emitClassFiles() throws Exception { 195 emitClassFile(""); 196 emitClassFile("8"); 197 } 198 199 /* 200 * Adds different variants of types and tries to invoke an 201 * interface or concrete method defined by them. 202 */ 203 void emitClassFile(String version) throws IOException { 204 205 final File outDir = mkdir(version.isEmpty() 206 ? tcwd 207 : new File(versionsDir, version)); 208 209 final File srcDir = mkdir(version.isEmpty() 210 ? new File(tcwd, "src") 211 : new File(new File(versionsDir, version), "src")); 212 213 List<String> scratch = new ArrayList<>(); 214 final String fname1 = "Ab"; 215 final File srcFile1 = new File(srcDir, fname1 + Utils.JAVA_FILE_EXT); 216 217 final String fname2 = "AbNormal"; 218 final File srcFile2 = new File(srcDir, fname2 + Utils.JAVA_FILE_EXT); 219 switch (version) { 220 case "8": 221 scratch.clear(); 222 scratch.add("import java.io.IOException;"); 223 scratch.add("public interface " + fname1 + "{"); 224 scratch.add(" public abstract void close() throws IOException ;"); 225 scratch.add("}"); 226 Utils.createFile(srcFile1, scratch); 227 break; 228 default: 229 scratch.clear(); 230 scratch.add("import java.io.IOException;"); 231 scratch.add("public abstract class " + fname1 + "{"); 232 scratch.add(" public abstract void close() throws IOException ;"); 233 scratch.add("}"); 234 Utils.createFile(srcFile1, scratch); 235 } 236 237 scratch.clear(); 238 scratch.add("import java.io.IOException;"); 239 scratch.add("public class " + fname2 + "{"); 240 scratch.add(" public void doSomething(Ab ab) throws IOException {"); 241 scratch.add(" ab.close();"); 242 scratch.add(" }"); 243 scratch.add("}"); 244 245 Utils.createFile(srcFile2, scratch); 246 Utils.compiler("-d", 247 outDir.getAbsolutePath(), 248 srcFile1.getAbsolutePath(), 249 srcFile2.getAbsolutePath()); 250 } 251 } 252 }