bchristi@3368: /* bchristi@3368: * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. bchristi@3368: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. bchristi@3368: * bchristi@3368: * This code is free software; you can redistribute it and/or modify it bchristi@3368: * under the terms of the GNU General Public License version 2 only, as bchristi@3368: * published by the Free Software Foundation. bchristi@3368: * bchristi@3368: * This code is distributed in the hope that it will be useful, but WITHOUT bchristi@3368: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or bchristi@3368: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License bchristi@3368: * version 2 for more details (a copy is included in the LICENSE file that bchristi@3368: * accompanied this code). bchristi@3368: * bchristi@3368: * You should have received a copy of the GNU General Public License version bchristi@3368: * 2 along with this work; if not, write to the Free Software Foundation, bchristi@3368: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. bchristi@3368: * bchristi@3368: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA bchristi@3368: * or visit www.oracle.com if you need additional information or have any bchristi@3368: * questions. bchristi@3368: */ bchristi@3368: bchristi@3368: /* bchristi@3368: * @test bchristi@3368: * @bug 8176329 bchristi@3368: * @summary Test for jdeps warning when it encounters a multi-release jar bchristi@3368: * @run testng MRJarWarning bchristi@3368: */ bchristi@3368: bchristi@3368: import java.io.IOException; bchristi@3368: import java.io.OutputStream; bchristi@3368: import java.io.PrintWriter; bchristi@3368: import java.io.StringWriter; bchristi@3368: import java.nio.file.Files; bchristi@3368: import java.nio.file.Path; bchristi@3368: import java.nio.file.Paths; bchristi@3368: import java.util.Arrays; bchristi@3368: import java.util.Collections; bchristi@3368: import java.util.List; bchristi@3368: import java.util.Locale; bchristi@3368: import java.util.jar.Attributes; bchristi@3368: import java.util.jar.JarEntry; bchristi@3368: import java.util.jar.JarOutputStream; bchristi@3368: import java.util.jar.Manifest; bchristi@3368: import org.testng.Assert; bchristi@3368: import org.testng.annotations.BeforeSuite; bchristi@3368: import org.testng.annotations.DataProvider; bchristi@3368: import org.testng.annotations.Test; bchristi@3368: bchristi@3368: public class MRJarWarning { bchristi@3368: private static final String WARNING = " is a multi-release jar file"; bchristi@3368: private static final String MRJAR_ATTR = "Multi-Release"; bchristi@3368: bchristi@3368: Path mrjar1; bchristi@3368: Path mrjar2; bchristi@3368: Path nonMRjar; bchristi@3368: Path mrjarAllCaps; bchristi@3368: bchristi@3368: private Attributes defaultAttributes; bchristi@3368: bchristi@3368: @BeforeSuite bchristi@3368: public void setup() throws IOException { bchristi@3368: defaultAttributes = new Attributes(); bchristi@3368: defaultAttributes.putValue("Manifest-Version", "1.0"); bchristi@3368: defaultAttributes.putValue("Created-By", "1.8.0-internal"); bchristi@3368: bchristi@3368: mrjar1 = Paths.get("mrjar1.jar"); bchristi@3368: mrjar2 = Paths.get("mrjar2.jar"); bchristi@3368: nonMRjar = Paths.get("nonMRjar.jar"); bchristi@3368: mrjarAllCaps = Paths.get("mrjarAllCaps.jar"); bchristi@3368: bchristi@3368: Attributes mrJarAttrs = new Attributes(defaultAttributes); bchristi@3368: mrJarAttrs.putValue(MRJAR_ATTR, "true"); bchristi@3368: bchristi@3368: build(mrjar1, mrJarAttrs); bchristi@3368: build(mrjar2, mrJarAttrs); bchristi@3368: build(nonMRjar, defaultAttributes); bchristi@3368: bchristi@3368: // JEP 238 - "Multi-Release JAR Files" states that the attribute name bchristi@3368: // and value are case insensitive. Try with all caps to ensure that bchristi@3368: // jdeps still recognizes a multi-release jar. bchristi@3368: Attributes allCapsAttrs = new Attributes(defaultAttributes); bchristi@3368: allCapsAttrs.putValue(MRJAR_ATTR.toUpperCase(), "TRUE"); bchristi@3368: build(mrjarAllCaps, allCapsAttrs); bchristi@3368: } bchristi@3368: bchristi@3368: @DataProvider(name="provider") bchristi@3368: private Object[][] args() { bchristi@3368: // jdeps warning messages may be localized. bchristi@3368: // This test only checks for the English version. Return an empty bchristi@3368: // array (skip testing) if the default language is not English. bchristi@3368: String language = Locale.getDefault().getLanguage(); bchristi@3368: System.out.println("Language: " + language); bchristi@3368: bchristi@3368: if ("en".equals(language)) { bchristi@3368: return new Object[][] { bchristi@3368: // one mrjar arg bchristi@3368: { Arrays.asList(mrjar1.toString()), bchristi@3368: Arrays.asList(mrjar1)}, bchristi@3368: // two mrjar args bchristi@3368: { Arrays.asList(mrjar1.toString(), mrjar2.toString()), bchristi@3368: Arrays.asList(mrjar1, mrjar2)}, bchristi@3368: // one mrjar arg, with mrjar on classpath bchristi@3368: { Arrays.asList("-cp", mrjar2.toString(), mrjar1.toString()), bchristi@3368: Arrays.asList(mrjar1, mrjar2)}, bchristi@3368: // non-mrjar arg, with mrjar on classpath bchristi@3368: { Arrays.asList("-cp", mrjar1.toString(), nonMRjar.toString()), bchristi@3368: Arrays.asList(mrjar1)}, bchristi@3368: // mrjar arg with jar attribute name/value in ALL CAPS bchristi@3368: { Arrays.asList(mrjarAllCaps.toString()), bchristi@3368: Arrays.asList(mrjarAllCaps)}, bchristi@3368: // non-mrjar arg bchristi@3368: { Arrays.asList(nonMRjar.toString()), bchristi@3368: Collections.emptyList()} bchristi@3368: }; bchristi@3368: } else { bchristi@3368: System.out.println("Non-English language \""+ language + bchristi@3368: "\"; test passes superficially"); bchristi@3368: return new Object[][]{}; bchristi@3368: } bchristi@3368: } bchristi@3368: bchristi@3368: /* Run jdeps with the arguments given in 'args', and confirm that a warning bchristi@3368: * is issued for each Multi-Release jar in 'expectedMRpaths'. bchristi@3368: */ bchristi@3368: @Test(dataProvider="provider") bchristi@3368: public void checkWarning(List args, List expectedMRpaths) { bchristi@3368: StringWriter sw = new StringWriter(); bchristi@3368: PrintWriter pw = new PrintWriter(sw); bchristi@3368: bchristi@3368: int rc = com.sun.tools.jdeps.Main.run(args.toArray(new String[args.size()]), pw); bchristi@3368: pw.close(); bchristi@3368: bchristi@3368: expectedMRJars(sw.toString(), expectedMRpaths); bchristi@3368: Assert.assertEquals(rc, 0, "non-zero exit code from jdeps"); bchristi@3368: } bchristi@3368: bchristi@3368: /* Confirm that warnings for the specified paths are in the output (or that bchristi@3368: * warnings are absent if 'paths' is empty). bchristi@3368: * Doesn't check for extra, unexpected warnings. bchristi@3368: */ bchristi@3368: private static void expectedMRJars(String output, List paths) { bchristi@3368: if (paths.isEmpty()) { bchristi@3368: Assert.assertFalse(output.contains(WARNING), bchristi@3368: "Expected no mrjars, but found:\n" + output); bchristi@3368: } else { bchristi@3368: for (Path path : paths) { bchristi@3368: String expect = "Warning: " + path.toString() + WARNING; bchristi@3368: Assert.assertTrue(output.contains(expect), bchristi@3368: "Did not find:\n" + expect + "\nin:\n" + output + "\n"); bchristi@3368: } bchristi@3368: } bchristi@3368: } bchristi@3368: bchristi@3368: /* Build a jar at the expected path, containing the given attributes */ bchristi@3368: private static void build(Path path, Attributes attributes) throws IOException { bchristi@3368: try (OutputStream os = Files.newOutputStream(path); bchristi@3368: JarOutputStream jos = new JarOutputStream(os)) { bchristi@3368: bchristi@3368: JarEntry me = new JarEntry("META-INF/MANIFEST.MF"); bchristi@3368: jos.putNextEntry(me); bchristi@3368: Manifest manifest = new Manifest(); bchristi@3368: manifest.getMainAttributes().putAll(attributes); bchristi@3368: manifest.write(jos); bchristi@3368: jos.closeEntry(); bchristi@3368: } bchristi@3368: } bchristi@3368: }