--- old/test/java/security/modules/JigsawSecurityUtils.java 2015-11-23 02:53:33.430945576 -0800 +++ new/test/java/security/modules/JigsawSecurityUtils.java 2015-11-23 02:53:33.171948537 -0800 @@ -1,126 +1,129 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.Map; -import java.lang.module.ModuleDescriptor; -import static java.lang.module.ModuleDescriptor.Builder; - -/** - * Jigsaw utility methods are part of this class. It exposes methods to generate - * module descriptor object and create service descriptor inside META-INF folder - * etc. - */ -public class JigsawSecurityUtils { - - /** - * Enum represents all supported module types in JDK9. - */ - public enum MODULE_TYPE { - - EXPLICIT, AUTO, UNNAMED; - } - - public static final String SPACE = " "; - - /** - * Constructs a Java Command line string based on modular structure followed - * by modular client and service. - */ - public static String[] getJavaCommand(Path modulePath, - StringBuilder classPath, String clientModuleName, - String mainClass, Map vmArgs) throws IOException { - - final StringBuilder command = new StringBuilder(); - vmArgs.forEach((key, value) -> command.append(key + value + SPACE)); - if (modulePath != null) { - command.append("-mp" + SPACE + modulePath.toRealPath() + SPACE); - } - if (classPath != null && classPath.length() > 0) { - command.append("-cp" + SPACE + classPath + SPACE); - } - if (clientModuleName != null && clientModuleName.length() > 0) { - command.append("-m" + SPACE + clientModuleName + "/"); - } - command.append(mainClass); - return command.toString().trim().split("[\\s]+"); - } - - /** - * Generate ModuleDescriptor object for explicit/auto based client/service - * modules. - */ - public static ModuleDescriptor generateModuleDescriptor( - boolean service, MODULE_TYPE moduleType, String moduleName, - String pkg, String serviceInterface, - String serviceImpl, String serviceModuleName, - List requiredModules, boolean depends) { - final Builder builder; - if (moduleType == MODULE_TYPE.EXPLICIT) { - System.out.println("Generating ModuleDescriptor object"); - builder = new Builder(moduleName).exports(pkg); - if (service) { - builder.provides(serviceInterface, serviceImpl); - } else { - builder.uses(serviceInterface); - if (depends) { - builder.requires(serviceModuleName); - } - } - } else { - System.out.println("ModuleDescriptor object not required."); - return null; - } - requiredModules.stream().forEach(reqMod -> builder.requires(reqMod)); - - return builder.build(); - } - - /** - * Generates service descriptor inside META-INF folder. - */ - public static boolean createMetaInfServiceDescriptor( - Path serviceDescriptorFile, String serviceImpl) { - boolean created = true; - System.out.println(String.format("Creating META-INF service descriptor" - + " for '%s' at path '%s'", serviceImpl, - serviceDescriptorFile)); - try { - Path parent = serviceDescriptorFile.getParent(); - if (parent != null) { - Files.createDirectories(parent); - } - Files.write(serviceDescriptorFile, serviceImpl.getBytes("UTF-8")); - System.out.println(String.format( - "META-INF service descriptor generated successfully")); - } catch (IOException e) { - e.printStackTrace(System.out); - created = false; - } - return created; - } - -} +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Arrays; +import java.lang.module.ModuleDescriptor; +import static java.lang.module.ModuleDescriptor.Builder; + +/** + * Jigsaw utility methods are part of this class. It exposes methods to generate + * module descriptor object and create service descriptor inside META-INF folder + * etc. + */ +public class JigsawSecurityUtils { + + /** + * Enum represents all supported module types in JDK9. + */ + public enum MODULE_TYPE { + + EXPLICIT, AUTO, UNNAMED; + } + + public static final String SPACE = " "; + + /** + * Constructs a Java Command line string based on modular structure followed + * by modular client and service. + */ + public static String[] getJavaCommand(Path modulePath, + StringBuilder classPath, String clientModuleName, + String mainClass, Map vmArgs, + String... options) throws IOException { + + final StringBuilder command = new StringBuilder(); + vmArgs.forEach((key, value) -> command.append(key + value + SPACE)); + if (modulePath != null) { + command.append("-mp" + SPACE + modulePath.toRealPath() + SPACE); + } + if (classPath != null && classPath.length() > 0) { + command.append("-cp" + SPACE + classPath + SPACE); + } + if (clientModuleName != null && clientModuleName.length() > 0) { + command.append("-m" + SPACE + clientModuleName + "/"); + } + command.append(mainClass); + Arrays.asList(options).stream().forEach(o -> command.append(SPACE + o)); + return command.toString().trim().split("[\\s]+"); + } + + /** + * Generate ModuleDescriptor object for explicit/auto based client/service + * modules. + */ + public static ModuleDescriptor generateModuleDescriptor( + boolean service, MODULE_TYPE moduleType, String moduleName, + String pkg, String serviceInterface, + String serviceImpl, String serviceModuleName, + List requiredModules, boolean depends) { + final Builder builder; + if (moduleType == MODULE_TYPE.EXPLICIT) { + System.out.println("Generating ModuleDescriptor object"); + builder = new Builder(moduleName).exports(pkg); + if (service) { + builder.provides(serviceInterface, serviceImpl); + } else { + builder.uses(serviceInterface); + if (depends) { + builder.requires(serviceModuleName); + } + } + } else { + System.out.println("ModuleDescriptor object not required."); + return null; + } + requiredModules.stream().forEach(reqMod -> builder.requires(reqMod)); + + return builder.build(); + } + + /** + * Generates service descriptor inside META-INF folder. + */ + public static boolean createMetaInfServiceDescriptor( + Path serviceDescriptorFile, String serviceImpl) { + boolean created = true; + System.out.println(String.format( + "Creating META-INF service descriptor for '%s' " + + "at path '%s'", serviceImpl, serviceDescriptorFile)); + try { + Path parent = serviceDescriptorFile.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.write(serviceDescriptorFile, serviceImpl.getBytes("UTF-8")); + System.out.println(String.format( + "META-INF service descriptor generated successfully")); + } catch (IOException e) { + e.printStackTrace(System.out); + created = false; + } + return created; + } + +} --- /dev/null 2015-07-25 05:49:27.889711346 -0700 +++ new/test/java/security/Provider/modules/JCEProviderModularTest.java 2015-11-23 02:53:33.751941906 -0800 @@ -0,0 +1,562 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Arrays; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.File; +import java.io.OutputStream; +import java.lang.module.ModuleDescriptor; +import sun.security.tools.keytool.CertAndKeyGen; +import sun.security.x509.X500Name; +import jdk.internal.module.ModuleInfoWriter; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.OutputAnalyzer; + +/** + * @test + * @bug 8130360 + * @library /jdk/jigsaw/lib + * @library /lib/testlibrary + * @library /java/security/modules + * @summary Test custom JCE provider module with all possible modular condition. + * The test includes different combination of JCE client/provider + * modules interaction with or without service description. + * The different module types used here are, + * EXPLICIT - Modules have module descriptor(module-info.java) + * defining the module. + * AUTO - Are regular jar files but provided in MODULE_PATH + * instead of CLASS_PATH. + * UNNAMED - Are regular jar but provided through CLASS_PATH. + * This test uses a boolean argument indicating to use signed jar + * for the third party JCE provider. + * @run main/othervm -Duser.language=en -Duser.region=US JCEProviderModularTest + * false + * @run main/othervm -Duser.language=en -Duser.region=US JCEProviderModularTest + * true + */ +public class JCEProviderModularTest extends JigsawSecurityUtils { + + private static final String TEST_SRC = System.getProperty("test.src"); + private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); + private static final Path JAVA_PATH + = Paths.get(System.getProperty("java.home")).resolve("bin"); + private static final String DESCRIPTOR = "metaservice"; + private static final String MODULAR = "modular"; + private static final String AUTO = "autodepend"; + private static final String JAR_EXTN = ".jar"; + + private static final String SERVICE_MODULE_NAME = "jceprovidermodule"; + private static final Path SERVICE_SRC_DIR + = SRC_DIR.resolve(SERVICE_MODULE_NAME); + private static final String SERVICE_PKG = "provider"; + private static final String SERVICE_JAR_NAME = SERVICE_PKG + JAR_EXTN; + private static final String SERVICE_DESCRIPTOR_JAR_NAME + = SERVICE_PKG + DESCRIPTOR + JAR_EXTN; + private static final String MODULAR_SERVICE_JAR_NAME + = MODULAR + SERVICE_PKG + JAR_EXTN; + private static final String MODULE_SERVICE_DESCRIPTOR_JAR_NAME + = MODULAR + SERVICE_PKG + DESCRIPTOR + JAR_EXTN; + + private static final String CLIENT_MODULE_NAME = "jceclientmodule"; + private static final Path CLIENT_SRC_DIR + = SRC_DIR.resolve(CLIENT_MODULE_NAME); + private static final String CLIENT_PKG = "client"; + private static final String CLIENT_JAR_NAME = CLIENT_PKG + JAR_EXTN; + private static final String MODULAR_CLIENT_AUTO_DEPEND_JAR_NAME + = MODULAR + CLIENT_PKG + AUTO + JAR_EXTN; + private static final String MODULAR_CLIENT_JAR_NAME + = MODULAR + CLIENT_PKG + JAR_EXTN; + + private static final Path BUILD_DIR = Paths.get(".").resolve("build"); + private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin"); + private static final Path SERVICE_BUILD_DIR + = COMPILE_DIR.resolve(SERVICE_PKG); + private static final Path SERVICE_META_BUILD_DIR + = COMPILE_DIR.resolve(SERVICE_PKG + DESCRIPTOR); + private static final Path CLIENT_BUILD_DIR + = COMPILE_DIR.resolve(CLIENT_PKG); + + private static final String EXPLICIT_MODULE_NAME = "jarmodule"; + private static final Path EXPLICIT_MODULE_BASE_PATH + = BUILD_DIR.resolve(EXPLICIT_MODULE_NAME); + + private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts"); + private static final Path SERVICE_ARTIFACTS_DIR + = ARTIFACTS_DIR.resolve(SERVICE_PKG); + private static final Path REGULAR_SERVICE_JAR + = SERVICE_ARTIFACTS_DIR.resolve(SERVICE_JAR_NAME); + private static final Path REGULAR_SERVICE_WITH_DESCRIPTOR_JAR + = SERVICE_ARTIFACTS_DIR.resolve(SERVICE_DESCRIPTOR_JAR_NAME); + private static final Path MODULAR_SERVICE_JAR + = SERVICE_ARTIFACTS_DIR.resolve(MODULAR_SERVICE_JAR_NAME); + private static final Path MODULAR_SERVICE_WITH_DESCRIPTOR_JAR + = SERVICE_ARTIFACTS_DIR.resolve(MODULE_SERVICE_DESCRIPTOR_JAR_NAME); + + private static final Path CLIENT_ARTIFACTS_DIR + = ARTIFACTS_DIR.resolve(CLIENT_PKG); + private static final Path REGULAR_CLIENT_JAR + = CLIENT_ARTIFACTS_DIR.resolve(CLIENT_JAR_NAME); + private static final Path MODULAR_CLIENT_JAR + = CLIENT_ARTIFACTS_DIR.resolve(MODULAR_CLIENT_JAR_NAME); + private static final Path MODULAR_CLIENT_AUTO_DEPEND_JAR + = CLIENT_ARTIFACTS_DIR.resolve(MODULAR_CLIENT_AUTO_DEPEND_JAR_NAME); + + private static final Path KEYSTORE_DIR = BUILD_DIR.resolve("store"); + private static final Path KEYSTORE_PATH + = KEYSTORE_DIR.resolve("test.keystore"); + private static final String STORE_PASSWORD = "password"; + private static final String ALIAS = "test"; + + private static final String MAIN_CLASS = CLIENT_PKG + ".TestJCEClient"; + private static final String LOGIN_SERVICE_INTERFACE + = "java.security.Provider"; + private static final String SERVICE_IMPL = SERVICE_PKG + ".TestJCEProvider"; + private static final List REQUIRED_MODULES + = Arrays.asList("java.base"); + private static final Path META_DESCRIPTOR = Paths.get("META-INF") + .resolve("services").resolve(LOGIN_SERVICE_INTERFACE); + private static final Path META_SERVICE_DESCRIPTOR + = SERVICE_META_BUILD_DIR.resolve(META_DESCRIPTOR); + + private static final boolean WITH_SERVICE_DESCRIPTOR = true; + private static final boolean WITHOUT_SERVICE_DESCRIPTOR = false; + private static final boolean PASS = true; + private static final String PROVIDER_CLASS_NOT_FOUND_MSG + = "NoClassDefFoundError: provider/TestJCEProvider"; + private static final String PROVIDER_NOT_FOUND_BY_CLIENT_MSG + = "Unable to find Test JCE Provider"; + private static final String CAN_NOT_ACCESS_MSG = "cannot access class"; + private static final String NO_FAILURE = null; + private static final String USE_SERVICE_LOADER = "USE_SERVICE_LOADER"; + private static final String USE_CLASS_LOADER = "USE_CLASS_LOADER"; + private static final List MECHANISMS + = Arrays.asList(USE_SERVICE_LOADER, USE_CLASS_LOADER); + private static final Map VM_ARGS = new LinkedHashMap<>(); + + public static void main(String[] args) { + + boolean success = true; + boolean useSignedJar = (args != null && args.length > 0) + ? Boolean.valueOf(args[0]) : false; + + boolean ready = createArtifacts(useSignedJar); + if (!ready) { + throw new RuntimeException("Unable to prepare to run this test."); + } + + for (String mechanism : MECHANISMS) { + boolean useClassLoader = USE_CLASS_LOADER.equals(mechanism); + //PARAMETER ORDERS - + //client Module Type, Service Module Type, + //Service META Descriptor Required, Expected Result + success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, + WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, + WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, + WITH_SERVICE_DESCRIPTOR, PASS, + ((useClassLoader) ? CAN_NOT_ACCESS_MSG : NO_FAILURE), + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, + WITHOUT_SERVICE_DESCRIPTOR, PASS, + PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, + WITH_SERVICE_DESCRIPTOR, PASS, + ((useClassLoader) ? CAN_NOT_ACCESS_MSG : NO_FAILURE), + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, + WITHOUT_SERVICE_DESCRIPTOR, PASS, ((useClassLoader) + ? CAN_NOT_ACCESS_MSG + : PROVIDER_NOT_FOUND_BY_CLIENT_MSG), + useSignedJar, mechanism); + + success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, + WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, + WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, + WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, + WITHOUT_SERVICE_DESCRIPTOR, PASS, + PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, + WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, + WITHOUT_SERVICE_DESCRIPTOR, PASS, + ((useClassLoader) ? NO_FAILURE + : PROVIDER_NOT_FOUND_BY_CLIENT_MSG), + useSignedJar, mechanism); + + success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, + WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, + WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, + WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, + WITHOUT_SERVICE_DESCRIPTOR, PASS, + PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, + WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, + useSignedJar, mechanism); + success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, + WITHOUT_SERVICE_DESCRIPTOR, PASS, + ((useClassLoader) ? NO_FAILURE + : PROVIDER_NOT_FOUND_BY_CLIENT_MSG), + useSignedJar, mechanism); + + if (!success) { + throw new RuntimeException("At least one test failed."); + } + } + } + + public static boolean runTest(MODULE_TYPE clientModuleType, + MODULE_TYPE serviceModuletype, boolean addMetaInfDescriptor, + boolean expectedResult, String expectedFailure, + boolean useSignedJar, String mechanism) { + + boolean result = true; + try { + + String testName = (clientModuleType + "_") + + (serviceModuletype + "_") + + ((addMetaInfDescriptor) ? "DESCRIPTOR" : "NO_DESCRIPTOR"); + + System.out.println(String.format( + "Starting Test case: '%s'", testName)); + Path clientJarPath = findJarPath(false, clientModuleType, false, + (serviceModuletype == MODULE_TYPE.EXPLICIT)); + Path serviceJarPath = findJarPath( + true, serviceModuletype, addMetaInfDescriptor, false); + System.out.println(String.format( + "Client jar path : %s ", clientJarPath)); + System.out.println(String.format( + "Service jar path : %s ", serviceJarPath)); + //For automated/explicit module type copy the corresponding + //jars to module base folder, which will be considered as + //module base path during execution. + if (!(clientModuleType == MODULE_TYPE.UNNAMED + && serviceModuletype == MODULE_TYPE.UNNAMED)) { + copyJarsToModuleBase(clientModuleType, clientJarPath, + serviceModuletype, serviceJarPath); + } + + System.out.println("Started executing java client with required" + + " custom JCE provider in class/module path."); + String moduleName + = getClientModuleName(clientModuleType, clientJarPath); + Path moduleBasePath = (clientModuleType != MODULE_TYPE.UNNAMED + || serviceModuletype != MODULE_TYPE.UNNAMED) + ? EXPLICIT_MODULE_BASE_PATH : null; + StringBuilder classPath + = getClassPath(clientModuleType, clientJarPath, + serviceModuletype, serviceJarPath); + OutputAnalyzer output = ProcessTools.executeTestJava( + getJavaCommand(moduleBasePath, classPath, moduleName, + MAIN_CLASS, VM_ARGS, mechanism)) + .outputTo(System.out) + .errorTo(System.out); + + if (output.getExitValue() != 0) { + if (expectedFailure != null + && output.getOutput().contains(expectedFailure)) { + System.out.println("PASS: Test is expected to fail here."); + } else { + System.out.println(String.format( + "Unexpected failure occured during executing '%s'" + + " with exit code '%s'.", + MAIN_CLASS, output.getExitValue())); + result = false; + } + } + } catch (Exception e) { + e.printStackTrace(System.out); + result = false; + } finally { + //clean module path so that the modulepath can only hold + //the required jars for next run. + cleanModuleBasePath(); + } + + return (expectedResult == result); + } + + //Decide the pre-generated client/service jar path for a given module type. + private static Path findJarPath(boolean service, MODULE_TYPE moduleType, + boolean addMetaInfDescriptor, boolean dependsOnServiceModule) { + if (service) { + if (moduleType == MODULE_TYPE.EXPLICIT) { + if (addMetaInfDescriptor) { + return MODULAR_SERVICE_WITH_DESCRIPTOR_JAR; + } else { + return MODULAR_SERVICE_JAR; + } + } else { + if (addMetaInfDescriptor) { + return REGULAR_SERVICE_WITH_DESCRIPTOR_JAR; + } else { + return REGULAR_SERVICE_JAR; + } + } + } else { + if (moduleType == MODULE_TYPE.EXPLICIT) { + if (dependsOnServiceModule) { + return MODULAR_CLIENT_JAR; + } else { + return MODULAR_CLIENT_AUTO_DEPEND_JAR; + } + } else { + return REGULAR_CLIENT_JAR; + } + } + } + + //Copy pre-generated jar files to the base module path based on module type. + private static void copyJarsToModuleBase(MODULE_TYPE clientModuleType, + Path modularClientJarPath, MODULE_TYPE serviceModuletype, + Path modularServiceJarPath) throws IOException { + + if (EXPLICIT_MODULE_BASE_PATH != null) { + Files.createDirectories(EXPLICIT_MODULE_BASE_PATH); + } + if (clientModuleType != MODULE_TYPE.UNNAMED) { + Path clientArtifactName = EXPLICIT_MODULE_BASE_PATH.resolve( + modularClientJarPath.getFileName()); + System.out.println(String.format("Copy client jar path: '%s'" + + " to module base path: %s", modularClientJarPath, + clientArtifactName)); + Files.copy(modularClientJarPath, clientArtifactName); + } + if (serviceModuletype != MODULE_TYPE.UNNAMED) { + Path serviceArtifactName = EXPLICIT_MODULE_BASE_PATH.resolve( + modularServiceJarPath.getFileName()); + System.out.println(String.format("Copy service jar path: '%s'" + + " to module base path: %s", modularServiceJarPath, + serviceArtifactName)); + Files.copy(modularServiceJarPath, serviceArtifactName); + } + } + + //Pre-compile and generate the jar files required to run this test. + private static boolean createArtifacts(boolean useSignedJar) { + + boolean done = true; + try { + VM_ARGS.put("-Duser.language=", "en"); + VM_ARGS.put("-Duser.region", "US"); + //If signed jar required then prepare the keystore for first time. + if (useSignedJar) { + done &= generateKeyStore(KEYSTORE_PATH.toString(), + STORE_PASSWORD, ALIAS); + } + done &= CompilerUtils.compile(SERVICE_SRC_DIR, SERVICE_BUILD_DIR); + done &= CompilerUtils.compile(SERVICE_SRC_DIR, + SERVICE_META_BUILD_DIR); + done &= createMetaInfServiceDescriptor(META_SERVICE_DESCRIPTOR, + SERVICE_IMPL); + //Generate regular/modular jars with(out) META-INF + //service descriptor + generateJar(true, MODULE_TYPE.EXPLICIT, MODULAR_SERVICE_JAR, + SERVICE_BUILD_DIR, false, useSignedJar); + generateJar(true, MODULE_TYPE.EXPLICIT, + MODULAR_SERVICE_WITH_DESCRIPTOR_JAR, + SERVICE_META_BUILD_DIR, false, useSignedJar); + generateJar(true, MODULE_TYPE.UNNAMED, REGULAR_SERVICE_JAR, + SERVICE_BUILD_DIR, false, useSignedJar); + generateJar(true, MODULE_TYPE.UNNAMED, + REGULAR_SERVICE_WITH_DESCRIPTOR_JAR, + SERVICE_META_BUILD_DIR, false, useSignedJar); + //Generate regular/modular(depends on explicit/auto service) + //jars for client + done &= CompilerUtils.compile(CLIENT_SRC_DIR, CLIENT_BUILD_DIR, + "-cp", REGULAR_SERVICE_JAR.toRealPath().toString()); + generateJar(false, MODULE_TYPE.EXPLICIT, MODULAR_CLIENT_JAR, + CLIENT_BUILD_DIR, true, useSignedJar); + generateJar(false, MODULE_TYPE.EXPLICIT, + MODULAR_CLIENT_AUTO_DEPEND_JAR, CLIENT_BUILD_DIR, + false, useSignedJar); + generateJar(false, MODULE_TYPE.UNNAMED, + REGULAR_CLIENT_JAR, CLIENT_BUILD_DIR, false, useSignedJar); + + System.out.println(String.format( + "Artifacts generated successfully? '%s'", done)); + } catch (IOException e) { + e.printStackTrace(System.out); + done = false; + } + return done; + } + + //Generate modular/regular jar based on module type. + private static void generateJar(boolean service, MODULE_TYPE moduleType, + Path jarFile, Path compilePath, boolean depends, + boolean useSignedJar) throws IOException { + + ModuleDescriptor moduleDescriptor = null; + if (service) { + moduleDescriptor = generateModuleDescriptor(service, moduleType, + SERVICE_MODULE_NAME, SERVICE_PKG, + LOGIN_SERVICE_INTERFACE, SERVICE_IMPL, null, + REQUIRED_MODULES, depends); + } else { + moduleDescriptor = generateModuleDescriptor(service, + moduleType, CLIENT_MODULE_NAME, CLIENT_PKG, + LOGIN_SERVICE_INTERFACE, null, SERVICE_MODULE_NAME, + REQUIRED_MODULES, depends); + } + System.out.println(String.format( + "Creating jar file '%s'", jarFile)); + JarUtils.createJarFile(jarFile, compilePath); + if (moduleDescriptor != null) { + Path dir = Files.createTempDirectory("tmp"); + Path mi = dir.resolve("module-info.class"); + try (OutputStream out = Files.newOutputStream(mi)) { + ModuleInfoWriter.write(moduleDescriptor, out); + } + System.out.println(String.format( + "Adding 'module-info.class' to jar file '%s'", jarFile)); + JarUtils.updateJarFile(jarFile, dir); + } + //If the jar holds provider implementation then sign it. + if (service && useSignedJar) { + signJar(jarFile, KEYSTORE_PATH.toRealPath().toString(), + STORE_PASSWORD, ALIAS); + } + } + + //Construct class path argument value. + private static StringBuilder getClassPath(MODULE_TYPE clientModuleType, + Path clientJarPath, MODULE_TYPE serviceModuletype, + Path serviceJarPath) throws IOException { + + StringBuilder classPath = new StringBuilder(); + classPath.append((clientModuleType == MODULE_TYPE.UNNAMED) + ? (clientJarPath.toRealPath().toString() + + File.pathSeparatorChar) : ""); + classPath.append((serviceModuletype == MODULE_TYPE.UNNAMED) + ? serviceJarPath.toRealPath().toString() : ""); + return classPath; + } + + //Construct client modulename to run the client. It is fixed for explicit + //module type while it is same as jar file name for automated module type. + private static String getClientModuleName(MODULE_TYPE clientModuleType, + Path clientJarPath) { + + String jarFileName = clientJarPath.toFile().getName(); + return (clientModuleType == MODULE_TYPE.EXPLICIT) + ? CLIENT_MODULE_NAME + : ((clientModuleType == MODULE_TYPE.AUTO) + ? jarFileName.substring( + 0, jarFileName.indexOf(JAR_EXTN)) : ""); + } + + //Delete all the files inside the base module path. + private static void cleanModuleBasePath() { + + Arrays.asList(EXPLICIT_MODULE_BASE_PATH.toFile().listFiles()) + .forEach(f -> { + System.out.println("delete " + f); + f.delete(); + }); + System.out.println("------------------------------------------------"); + } + + //Generate a keystore with random keys. + public static boolean generateKeyStore(String keyStoreFile, + String password, String alias) throws IOException { + boolean created = true; + Path parent = KEYSTORE_PATH.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + try (FileOutputStream keyStoreOut + = new FileOutputStream(keyStoreFile)) { + + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(null, null); + + CertAndKeyGen keyGen + = new CertAndKeyGen("RSA", "SHA1WithRSA", null); + keyGen.generate(2048); + //Generate self signed certificate + Certificate[] chain = new X509Certificate[1]; + chain[0] = keyGen.getSelfCertificate( + new X500Name("CN=ROOT"), (long) 365 * 24 * 3600); + keyStore.setKeyEntry(alias, keyGen.getPrivateKey(), + password.toCharArray(), chain); + + keyStore.store(keyStoreOut, password.toCharArray()); + } catch (Exception e) { + created = false; + e.printStackTrace(System.out); + } + return created; + } + + //Sign a jar file by provided keystore file. + public static void signJar(Path jarFile, String keyStore, + String password, String alias) { + try { + String command = String.format( + "%s -keystore %s -storepass %s -keypass %s %s %s", + JAVA_PATH.resolve("jarsigner"), keyStore, + password, password, jarFile.toRealPath(), alias); + System.out.println(String.format( + "Command used to sign jar: %s", command)); + ProcessBuilder processBuilder + = new ProcessBuilder(command.split("[\\s]+")); + OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); + System.out.println( + "_________________BEGIN JAR SIGN OUTPUT__________________"); + System.out.println(output.getOutput()); + System.out.println( + "_______________________END OUTPUT_______________________"); + output.shouldHaveExitValue(0); + } catch (Exception e) { + throw new RuntimeException(String.format( + "Unable to sign Jar file '%s'", jarFile)); + } + } + +} --- /dev/null 2015-07-25 05:49:27.889711346 -0700 +++ new/test/java/security/Provider/modules/TEST.properties 2015-11-23 02:53:34.313935480 -0800 @@ -0,0 +1,3 @@ +modules java.base/jdk.internal.module \ + java.base/sun.security.x509 \ + java.base/sun.security.tools.keytool \ No newline at end of file --- /dev/null 2015-07-25 05:49:27.889711346 -0700 +++ new/test/java/security/Provider/modules/src/jceclientmodule/client/TestJCEClient.java 2015-11-23 02:53:34.871929098 -0800 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package client; + +import java.security.Provider; +import java.util.Iterator; +import java.util.ServiceLoader; + +/** + * Test JCE client uses different mechanism to find the custom security + * provider. It uses ServiceLoader and ClassLoader to find the TEST provider + * available in classPath/modulePath. It also tries to find, if the provider is + * configured through "java.security" file. + */ +public class TestJCEClient { + + private static final String CUSTOM_PROVIDER_NAME = "TEST"; + private static final String EXCEPTION_MESSAGE + = "Unable to find Test JCE Provider"; + private static final String USE_SERVICE_LOADER = "USE_SERVICE_LOADER"; + private static final String USE_CLASS_LOADER = "USE_CLASS_LOADER"; + + public static void main(String[] args) { + Provider provider = null; + //Try to find the TEST provider loaded by ServiceLoader. + if (args != null && args.length > 0 + && USE_SERVICE_LOADER.equals(args[0])) { + ServiceLoader services + = ServiceLoader.load(java.security.Provider.class); + Iterator iterator = services.iterator(); + while (iterator.hasNext()) { + Provider p = iterator.next(); + if (p.getName().equals(CUSTOM_PROVIDER_NAME)) { + provider = p; + break; + } + } + } else if (args != null && args.length > 0 + && USE_CLASS_LOADER.equals(args[0])) { + //Find the TEST provider loaded by ClassLoader. + provider = new provider.TestJCEProvider(); + } + //Commented the following line due to the difficulty to set 3rd party + //security provider through java.security file before running + //JTREG test. + /*else { + //Find the TEST provider configured through "java.security" file. + provider = Security.getProvider(CUSTOM_PROVIDER_NAME); + }*/ + + if (provider != null) { + System.out.printf("Test JCE provider named '%s' loaded " + + "successfully", CUSTOM_PROVIDER_NAME); + } else { + throw new RuntimeException(EXCEPTION_MESSAGE); + } + } +} --- /dev/null 2015-07-25 05:49:27.889711346 -0700 +++ new/test/java/security/Provider/modules/src/jceprovidermodule/provider/TestJCEProvider.java 2015-11-23 02:53:35.420922822 -0800 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package provider; + +import java.security.Provider; + +/** + * Custom JCE provider for modular test. + */ +public final class TestJCEProvider extends Provider { + + public TestJCEProvider() { + super("TEST", 1.0d, "Test JCE provider"); + System.out.println(String.format( + "TEST provider loaded successfully : %s", this.toString())); + } + + @Override + public String toString() { + return "TestJCEProvider [getName()=" + getName() + ", getVersion()=" + + getVersion() + ", getInfo()=" + getInfo() + ", toString()=" + + super.toString() + "]"; + } + +}