Path: blob/master/test/jdk/lib/testlibrary/java/util/jar/CreateMultiReleaseTestJars.java
41159 views
/*1* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.File;24import java.io.FileOutputStream;25import java.io.IOException;26import java.nio.file.Files;27import java.nio.file.Path;28import java.nio.file.Paths;29import java.security.KeyStore;30import java.security.PrivateKey;31import java.security.cert.CertPath;32import java.security.cert.CertificateFactory;33import java.util.Arrays;34import java.util.HashMap;35import java.util.Map;36import java.util.zip.ZipFile;37import java.io.File;3839import jdk.security.jarsigner.JarSigner;40import jdk.test.lib.compiler.Compiler;41import jdk.test.lib.util.JarBuilder;4243public class CreateMultiReleaseTestJars {44final private String main =45"package version;\n\n"46+ "public class Main {\n"47+ " public static void main(String[] args) {\n"48+ " Version v = new Version();\n"49+ " System.out.println(\"I am running on version \" + v.getVersion());\n"50+ " }\n"51+ "}\n";52final private String java8 =53"package version;\n\n"54+ "public class Version {\n"55+ " public int getVersion() {\n"56+ " return 8;\n"57+ " }\n"58+ "}\n";59final private String java9 =60"package version;\n\n"61+ "public class Version {\n"62+ " public int getVersion() {\n"63+ " int version = (new PackagePrivate()).getVersion();\n"64+ " if (version == 9) return 9;\n" // strange I know, but easy to test65+ " return version;\n"66+ " }\n"67+ "}\n";68final private String ppjava9 =69"package version;\n\n"70+ "class PackagePrivate {\n"71+ " int getVersion() {\n"72+ " return 9;\n"73+ " }\n"74+ "}\n";75final int currentVersion = Runtime.version().feature();76final String currentVersionStr = Integer.toString(currentVersion);77final private String javaCurrent = java8.replace("8", currentVersionStr);78final String readme8 = "This is the root readme file";79final String readme9 = "This is the version nine readme file";80final String readmeCurrent = "This is the current version readme file";81private Map<String,byte[]> rootClasses;82private Map<String,byte[]> version9Classes;83private Map<String,byte[]> versionCurrentClasses;8485public void buildUnversionedJar() throws IOException {86JarBuilder jb = new JarBuilder("unversioned.jar");87jb.addEntry("README", readme8.getBytes());88jb.addEntry("version/Main.java", main.getBytes());89jb.addEntry("version/Main.class", rootClasses.get("version.Main"));90jb.addEntry("version/Version.java", java8.getBytes());91jb.addEntry("version/Version.class", rootClasses.get("version.Version"));92jb.build();93}9495public void buildMultiReleaseJar() throws IOException {96JarBuilder jb = customMultiReleaseJar("multi-release.jar", "true");97addEntries(jb);98jb.addEntry("META-INF/versions/9/version/Version.class", version9Classes.get("version.Version"));99jb.build();100}101102public void buildShortMultiReleaseJar() throws IOException {103JarBuilder jb = customMultiReleaseJar("short-multi-release.jar", "true");104addEntries(jb);105jb.build();106}107108private JarBuilder customMultiReleaseJar(String filename, String multiReleaseValue)109throws IOException {110JarBuilder jb = new JarBuilder(filename);111jb.addAttribute("Multi-Release", multiReleaseValue);112return jb;113}114115public void buildCustomMultiReleaseJar(String filename, String multiReleaseValue,116Map<String, String> extraAttributes) throws IOException {117buildCustomMultiReleaseJar(filename, multiReleaseValue, extraAttributes, false);118}119120public void buildCustomMultiReleaseJar(String filename, String multiReleaseValue,121Map<String, String> extraAttributes, boolean addEntries) throws IOException {122JarBuilder jb = new JarBuilder(filename);123extraAttributes.entrySet()124.forEach(entry -> jb.addAttribute(entry.getKey(), entry.getValue()));125if (addEntries) {126addEntries(jb);127}128jb.addAttribute("Multi-Release", multiReleaseValue);129jb.build();130}131132private void addEntries(JarBuilder jb) {133jb.addEntry("README", readme8.getBytes());134jb.addEntry("version/Main.java", main.getBytes());135jb.addEntry("version/Main.class", rootClasses.get("version.Main"));136jb.addEntry("version/Version.java", java8.getBytes());137jb.addEntry("version/Version.class", rootClasses.get("version.Version"));138jb.addEntry("META-INF/versions/9/README", readme9.getBytes());139jb.addEntry("META-INF/versions/9/version/Version.java", java9.getBytes());140jb.addEntry("META-INF/versions/9/version/PackagePrivate.java", ppjava9.getBytes());141jb.addEntry("META-INF/versions/9/version/PackagePrivate.class", version9Classes.get("version.PackagePrivate"));142jb.addEntry("META-INF/versions/" + currentVersionStr + "/README", readmeCurrent.getBytes());143jb.addEntry("META-INF/versions/" + currentVersionStr + "/version/Version.java", javaCurrent.getBytes());144jb.addEntry("META-INF/versions/" + currentVersionStr + "/version/Version.class", versionCurrentClasses.get("version.Version"));145}146147public void buildSignedMultiReleaseJar() throws Exception {148buildSignedMultiReleaseJar("multi-release.jar", "signed-multi-release.jar");149}150151public void buildSignedMultiReleaseJar(String multiReleaseJar,152String signedMultiReleaseJar) throws Exception153{154String testsrc = System.getProperty("test.src",".");155String testdir = findTestDir(testsrc);156String keystore = testdir + "/sun/security/tools/jarsigner/JarSigning.keystore";157158// jarsigner -keystore keystore -storepass "bbbbbb"159// -signedJar signed-multi-release.jar multi-release.jar b160161char[] password = "bbbbbb".toCharArray();162KeyStore ks = KeyStore.getInstance(new File(keystore), password);163PrivateKey pkb = (PrivateKey)ks.getKey("b", password);164CertPath cp = CertificateFactory.getInstance("X.509")165.generateCertPath(Arrays.asList(ks.getCertificateChain("b")));166JarSigner js = new JarSigner.Builder(pkb, cp).build();167try (ZipFile in = new ZipFile(multiReleaseJar);168FileOutputStream os = new FileOutputStream(signedMultiReleaseJar))169{170js.sign(in, os);171}172}173174String findTestDir(String dir) throws IOException {175Path path = Paths.get(dir).toAbsolutePath();176Path child = null;177while (path != null && !path.endsWith("test")) {178child = path;179path = path.getParent();180}181if (child == null) {182throw new IllegalArgumentException(dir + " is not in a test directory");183}184if (!Files.isDirectory(child)) {185throw new IOException(child.toString() + " is not a directory");186}187return child.toString();188}189190void compileEntries() {191Map<String,String> input = new HashMap<>();192input.put("version.Main", main);193input.put("version.Version", java8);194rootClasses = (new Compiler(input)).setRelease(8).compile();195input.clear();196input.put("version.Version", java9);197input.put("version.PackagePrivate", ppjava9);198version9Classes = (new Compiler(input)).setRelease(9).compile();199input.clear();200input.put("version.Version", javaCurrent);201versionCurrentClasses = (new Compiler(input)).compile(); // Use default release202}203}204205206