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 24 import java.nio.file.Files; 25 import java.nio.file.Path; 26 import java.nio.file.Paths; 27 import java.security.KeyStore; 28 import java.security.cert.Certificate; 29 import java.security.cert.X509Certificate; 30 import java.util.LinkedHashMap; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.Arrays; 34 import java.io.FileOutputStream; 35 import java.io.IOException; 36 import java.io.File; 37 import java.io.OutputStream; 38 import java.lang.module.ModuleDescriptor; 39 import sun.security.tools.keytool.CertAndKeyGen; 40 import sun.security.x509.X500Name; 41 import jdk.internal.module.ModuleInfoWriter; 42 import jdk.testlibrary.ProcessTools; 43 import jdk.testlibrary.OutputAnalyzer; 44 import jdk.testlibrary.JDKToolLauncher; 45 46 /** 47 * @test 48 * @bug 8130360 49 * @library /jdk/jigsaw/lib 50 * @library /lib/testlibrary 51 * @library /java/security/modules 52 * @summary Test custom JCE provider module with all possible modular condition. 53 * The test includes different combination of JCE client/provider 54 * modules interaction with or without service description. 55 * The different module types used here are, 56 * EXPLICIT - Modules have module descriptor(module-info.java) 57 * defining the module. 58 * AUTO - Are regular jar files but provided in MODULE_PATH 59 * instead of CLASS_PATH. 60 * UNNAMED - Are regular jar but provided through CLASS_PATH. 61 * This test uses a boolean argument indicating to use signed jar 62 * for the third party JCE provider. 63 * @run main/othervm -Duser.language=en -Duser.region=US JCEProviderModularTest 64 * false 65 * @run main/othervm -Duser.language=en -Duser.region=US JCEProviderModularTest 66 * true 67 */ 68 public class JCEProviderModularTest extends JigsawSecurityUtils { 69 70 private static final String TEST_SRC = System.getProperty("test.src"); 71 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 72 private static final String DESCRIPTOR = "metaservice"; 73 private static final String MODULAR = "modular"; 74 private static final String AUTO = "autodepend"; 75 private static final String JAR_EXTN = ".jar"; 76 77 private static final String SERVICE_MODULE_NAME = "jceprovidermodule"; 78 private static final Path SERVICE_SRC_DIR 79 = SRC_DIR.resolve(SERVICE_MODULE_NAME); 80 private static final String SERVICE_PKG = "provider"; 81 private static final String SERVICE_JAR_NAME = SERVICE_PKG + JAR_EXTN; 82 private static final String SERVICE_DESCRIPTOR_JAR_NAME 83 = SERVICE_PKG + DESCRIPTOR + JAR_EXTN; 84 private static final String MODULAR_SERVICE_JAR_NAME 85 = MODULAR + SERVICE_PKG + JAR_EXTN; 86 private static final String MODULE_SERVICE_DESCRIPTOR_JAR_NAME 87 = MODULAR + SERVICE_PKG + DESCRIPTOR + JAR_EXTN; 88 89 private static final String CLIENT_MODULE_NAME = "jceclientmodule"; 90 private static final Path CLIENT_SRC_DIR 91 = SRC_DIR.resolve(CLIENT_MODULE_NAME); 92 private static final String CLIENT_PKG = "client"; 93 private static final String CLIENT_JAR_NAME = CLIENT_PKG + JAR_EXTN; 94 private static final String MODULAR_CLIENT_AUTO_DEPEND_JAR_NAME 95 = MODULAR + CLIENT_PKG + AUTO + JAR_EXTN; 96 private static final String MODULAR_CLIENT_JAR_NAME 97 = MODULAR + CLIENT_PKG + JAR_EXTN; 98 99 private static final Path BUILD_DIR = Paths.get(".").resolve("build"); 100 private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin"); 101 private static final Path SERVICE_BUILD_DIR 102 = COMPILE_DIR.resolve(SERVICE_PKG); 103 private static final Path SERVICE_META_BUILD_DIR 104 = COMPILE_DIR.resolve(SERVICE_PKG + DESCRIPTOR); 105 private static final Path CLIENT_BUILD_DIR 106 = COMPILE_DIR.resolve(CLIENT_PKG); 107 108 private static final String EXPLICIT_MODULE_NAME = "jarmodule"; 109 private static final Path EXPLICIT_MODULE_BASE_PATH 110 = BUILD_DIR.resolve(EXPLICIT_MODULE_NAME); 111 112 private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts"); 113 private static final Path SERVICE_ARTIFACTS_DIR 114 = ARTIFACTS_DIR.resolve(SERVICE_PKG); 115 private static final Path REGULAR_SERVICE_JAR 116 = SERVICE_ARTIFACTS_DIR.resolve(SERVICE_JAR_NAME); 117 private static final Path REGULAR_SERVICE_WITH_DESCRIPTOR_JAR 118 = SERVICE_ARTIFACTS_DIR.resolve(SERVICE_DESCRIPTOR_JAR_NAME); 119 private static final Path MODULAR_SERVICE_JAR 120 = SERVICE_ARTIFACTS_DIR.resolve(MODULAR_SERVICE_JAR_NAME); 121 private static final Path MODULAR_SERVICE_WITH_DESCRIPTOR_JAR 122 = SERVICE_ARTIFACTS_DIR.resolve(MODULE_SERVICE_DESCRIPTOR_JAR_NAME); 123 124 private static final Path CLIENT_ARTIFACTS_DIR 125 = ARTIFACTS_DIR.resolve(CLIENT_PKG); 126 private static final Path REGULAR_CLIENT_JAR 127 = CLIENT_ARTIFACTS_DIR.resolve(CLIENT_JAR_NAME); 128 private static final Path MODULAR_CLIENT_JAR 129 = CLIENT_ARTIFACTS_DIR.resolve(MODULAR_CLIENT_JAR_NAME); 130 private static final Path MODULAR_CLIENT_AUTO_DEPEND_JAR 131 = CLIENT_ARTIFACTS_DIR.resolve(MODULAR_CLIENT_AUTO_DEPEND_JAR_NAME); 132 133 private static final Path KEYSTORE_DIR = BUILD_DIR.resolve("store"); 134 private static final Path KEYSTORE_PATH 135 = KEYSTORE_DIR.resolve("test.keystore"); 136 private static final String STORE_PASSWORD = "password"; 137 private static final String ALIAS = "test"; 138 139 private static final String MAIN_CLASS = CLIENT_PKG + ".TestJCEClient"; 140 private static final String LOGIN_SERVICE_INTERFACE 141 = "java.security.Provider"; 142 private static final String SERVICE_IMPL = SERVICE_PKG + ".TestJCEProvider"; 143 private static final List<String> REQUIRED_MODULES 144 = Arrays.asList("java.base"); 145 private static final Path META_DESCRIPTOR = Paths.get("META-INF") 146 .resolve("services").resolve(LOGIN_SERVICE_INTERFACE); 147 private static final Path META_SERVICE_DESCRIPTOR 148 = SERVICE_META_BUILD_DIR.resolve(META_DESCRIPTOR); 149 150 private static final boolean WITH_SERVICE_DESCRIPTOR = true; 151 private static final boolean WITHOUT_SERVICE_DESCRIPTOR = false; 152 private static final boolean PASS = true; 153 private static final String PROVIDER_CLASS_NOT_FOUND_MSG 154 = "NoClassDefFoundError: provider/TestJCEProvider"; 155 private static final String PROVIDER_NOT_FOUND_BY_CLIENT_MSG 156 = "Unable to find Test JCE Provider"; 157 private static final String CAN_NOT_ACCESS_MSG = "cannot access class"; 158 private static final String NO_FAILURE = null; 159 private static final String USE_SERVICE_LOADER = "USE_SERVICE_LOADER"; 160 private static final String USE_CLASS_LOADER = "USE_CLASS_LOADER"; 161 private static final String USE_SECURITY_PROP = "USE_SECURITY_PROP"; 162 private static final List<String> MECHANISMS = Arrays.asList( 163 USE_SERVICE_LOADER, USE_CLASS_LOADER, USE_SECURITY_PROP); 164 private static final Path SECURITY_PROP_EXTN 165 = Paths.get("./java.security.extn"); 166 167 public static void main(String[] args) { 168 169 boolean success = true; 170 boolean useSignedJar = (args != null && args.length > 0) 171 ? Boolean.valueOf(args[0]) : false; 172 173 boolean ready = createArtifacts(useSignedJar); 174 if (!ready) { 175 throw new RuntimeException("Unable to prepare to run this test."); 176 } 177 178 for (String mechanism : MECHANISMS) { 179 boolean useClassLoader = USE_CLASS_LOADER.equals(mechanism); 180 //PARAMETER ORDERS - 181 //client Module Type, Service Module Type, 182 //Service META Descriptor Required, Expected Result 183 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, 184 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 185 useSignedJar, mechanism); 186 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, 187 WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 188 useSignedJar, mechanism); 189 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, 190 WITH_SERVICE_DESCRIPTOR, PASS, 191 ((useClassLoader) ? CAN_NOT_ACCESS_MSG : NO_FAILURE), 192 useSignedJar, mechanism); 193 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, 194 WITHOUT_SERVICE_DESCRIPTOR, PASS, 195 PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); 196 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, 197 WITH_SERVICE_DESCRIPTOR, PASS, 198 ((useClassLoader) ? CAN_NOT_ACCESS_MSG : NO_FAILURE), 199 useSignedJar, mechanism); 200 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, 201 WITHOUT_SERVICE_DESCRIPTOR, PASS, ((useClassLoader) 202 ? CAN_NOT_ACCESS_MSG 203 : PROVIDER_NOT_FOUND_BY_CLIENT_MSG), 204 useSignedJar, mechanism); 205 206 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, 207 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 208 useSignedJar, mechanism); 209 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, 210 WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 211 useSignedJar, mechanism); 212 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, 213 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 214 useSignedJar, mechanism); 215 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, 216 WITHOUT_SERVICE_DESCRIPTOR, PASS, 217 PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); 218 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, 219 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 220 useSignedJar, mechanism); 221 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, 222 WITHOUT_SERVICE_DESCRIPTOR, PASS, 223 ((useClassLoader) ? NO_FAILURE 224 : PROVIDER_NOT_FOUND_BY_CLIENT_MSG), 225 useSignedJar, mechanism); 226 227 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, 228 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 229 useSignedJar, mechanism); 230 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, 231 WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 232 useSignedJar, mechanism); 233 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, 234 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 235 useSignedJar, mechanism); 236 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, 237 WITHOUT_SERVICE_DESCRIPTOR, PASS, 238 PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); 239 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, 240 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 241 useSignedJar, mechanism); 242 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, 243 WITHOUT_SERVICE_DESCRIPTOR, PASS, 244 ((useClassLoader) ? NO_FAILURE 245 : PROVIDER_NOT_FOUND_BY_CLIENT_MSG), 246 useSignedJar, mechanism); 247 248 if (!success) { 249 throw new RuntimeException("At least one test failed."); 250 } 251 } 252 } 253 254 public static boolean runTest(MODULE_TYPE clientModuleType, 255 MODULE_TYPE serviceModuletype, boolean addMetaInfDescriptor, 256 boolean expectedResult, String expectedFailure, 257 boolean useSignedJar, String mechanism) { 258 259 boolean result = true; 260 try { 261 262 String testName = (clientModuleType + "_") 263 + (serviceModuletype + "_") 264 + ((addMetaInfDescriptor) ? "DESCRIPTOR" : "NO_DESCRIPTOR"); 265 266 System.out.println(String.format( 267 "Starting Test case: '%s'", testName)); 268 Path clientJarPath = findJarPath(false, clientModuleType, false, 269 (serviceModuletype == MODULE_TYPE.EXPLICIT)); 270 Path serviceJarPath = findJarPath( 271 true, serviceModuletype, addMetaInfDescriptor, false); 272 System.out.println(String.format( 273 "Client jar path : %s ", clientJarPath)); 274 System.out.println(String.format( 275 "Service jar path : %s ", serviceJarPath)); 276 //For automated/explicit module type copy the corresponding 277 //jars to module base folder, which will be considered as 278 //module base path during execution. 279 if (!(clientModuleType == MODULE_TYPE.UNNAMED 280 && serviceModuletype == MODULE_TYPE.UNNAMED)) { 281 copyJarsToModuleBase(clientModuleType, clientJarPath, 282 serviceModuletype, serviceJarPath); 283 } 284 285 System.out.println("Started executing java client with required" 286 + " custom JCE provider in class/module path."); 287 String moduleName 288 = getClientModuleName(clientModuleType, clientJarPath); 289 Path moduleBasePath = (clientModuleType != MODULE_TYPE.UNNAMED 290 || serviceModuletype != MODULE_TYPE.UNNAMED) 291 ? EXPLICIT_MODULE_BASE_PATH : null; 292 StringBuilder classPath 293 = getClassPath(clientModuleType, clientJarPath, 294 serviceModuletype, serviceJarPath); 295 296 final Map<String, String> VM_ARGS = new LinkedHashMap<>(); 297 VM_ARGS.put("-Duser.language=", "en"); 298 VM_ARGS.put("-Duser.region=", "US"); 299 if (USE_SECURITY_PROP.equals(mechanism)) { 300 VM_ARGS.put("-Djava.security.properties=", 301 SECURITY_PROP_EXTN.toFile().getCanonicalPath()); 302 } 303 OutputAnalyzer output = ProcessTools.executeTestJava( 304 getJavaCommand(moduleBasePath, classPath, moduleName, 305 MAIN_CLASS, VM_ARGS, mechanism)) 306 .outputTo(System.out) 307 .errorTo(System.out); 308 309 if (output.getExitValue() != 0) { 310 if (expectedFailure != null 311 && output.getOutput().contains(expectedFailure)) { 312 System.out.println("PASS: Test is expected to fail here."); 313 } else { 314 System.out.println(String.format( 315 "Unexpected failure occured during executing '%s'" 316 + " with exit code '%s'.", 317 MAIN_CLASS, output.getExitValue())); 318 result = false; 319 } 320 } 321 } catch (Exception e) { 322 e.printStackTrace(System.out); 323 result = false; 324 } finally { 325 //clean module path so that the modulepath can only hold 326 //the required jars for next run. 327 cleanModuleBasePath(); 328 } 329 330 return (expectedResult == result); 331 } 332 333 //Decide the pre-generated client/service jar path for a given module type. 334 private static Path findJarPath(boolean service, MODULE_TYPE moduleType, 335 boolean addMetaInfDescriptor, boolean dependsOnServiceModule) { 336 if (service) { 337 if (moduleType == MODULE_TYPE.EXPLICIT) { 338 if (addMetaInfDescriptor) { 339 return MODULAR_SERVICE_WITH_DESCRIPTOR_JAR; 340 } else { 341 return MODULAR_SERVICE_JAR; 342 } 343 } else { 344 if (addMetaInfDescriptor) { 345 return REGULAR_SERVICE_WITH_DESCRIPTOR_JAR; 346 } else { 347 return REGULAR_SERVICE_JAR; 348 } 349 } 350 } else { 351 if (moduleType == MODULE_TYPE.EXPLICIT) { 352 if (dependsOnServiceModule) { 353 return MODULAR_CLIENT_JAR; 354 } else { 355 return MODULAR_CLIENT_AUTO_DEPEND_JAR; 356 } 357 } else { 358 return REGULAR_CLIENT_JAR; 359 } 360 } 361 } 362 363 //Copy pre-generated jar files to the base module path based on module type. 364 private static void copyJarsToModuleBase(MODULE_TYPE clientModuleType, 365 Path modularClientJarPath, MODULE_TYPE serviceModuletype, 366 Path modularServiceJarPath) throws IOException { 367 368 if (EXPLICIT_MODULE_BASE_PATH != null) { 369 Files.createDirectories(EXPLICIT_MODULE_BASE_PATH); 370 } 371 if (clientModuleType != MODULE_TYPE.UNNAMED) { 372 Path clientArtifactName = EXPLICIT_MODULE_BASE_PATH.resolve( 373 modularClientJarPath.getFileName()); 374 System.out.println(String.format("Copy client jar path: '%s'" 375 + " to module base path: %s", modularClientJarPath, 376 clientArtifactName)); 377 Files.copy(modularClientJarPath, clientArtifactName); 378 } 379 if (serviceModuletype != MODULE_TYPE.UNNAMED) { 380 Path serviceArtifactName = EXPLICIT_MODULE_BASE_PATH.resolve( 381 modularServiceJarPath.getFileName()); 382 System.out.println(String.format("Copy service jar path: '%s'" 383 + " to module base path: %s", modularServiceJarPath, 384 serviceArtifactName)); 385 Files.copy(modularServiceJarPath, serviceArtifactName); 386 } 387 } 388 389 //Pre-compile and generate the artifacts required to run this test. 390 private static boolean createArtifacts(boolean useSignedJar) { 391 392 boolean done = true; 393 try { 394 Files.write(SECURITY_PROP_EXTN, 395 "security.provider.13=TEST".getBytes()); 396 //If signed jar required then prepare the keystore for first time. 397 if (useSignedJar) { 398 done &= generateKeyStore(KEYSTORE_PATH.toString(), 399 STORE_PASSWORD, ALIAS); 400 } 401 done &= CompilerUtils.compile(SERVICE_SRC_DIR, SERVICE_BUILD_DIR); 402 done &= CompilerUtils.compile(SERVICE_SRC_DIR, 403 SERVICE_META_BUILD_DIR); 404 done &= createMetaInfServiceDescriptor(META_SERVICE_DESCRIPTOR, 405 SERVICE_IMPL); 406 //Generate regular/modular jars with(out) META-INF 407 //service descriptor 408 generateJar(true, MODULE_TYPE.EXPLICIT, MODULAR_SERVICE_JAR, 409 SERVICE_BUILD_DIR, false, useSignedJar); 410 generateJar(true, MODULE_TYPE.EXPLICIT, 411 MODULAR_SERVICE_WITH_DESCRIPTOR_JAR, 412 SERVICE_META_BUILD_DIR, false, useSignedJar); 413 generateJar(true, MODULE_TYPE.UNNAMED, REGULAR_SERVICE_JAR, 414 SERVICE_BUILD_DIR, false, useSignedJar); 415 generateJar(true, MODULE_TYPE.UNNAMED, 416 REGULAR_SERVICE_WITH_DESCRIPTOR_JAR, 417 SERVICE_META_BUILD_DIR, false, useSignedJar); 418 //Generate regular/modular(depends on explicit/auto service) 419 //jars for client 420 done &= CompilerUtils.compile(CLIENT_SRC_DIR, CLIENT_BUILD_DIR, 421 "-cp", REGULAR_SERVICE_JAR.toRealPath().toString()); 422 generateJar(false, MODULE_TYPE.EXPLICIT, MODULAR_CLIENT_JAR, 423 CLIENT_BUILD_DIR, true, useSignedJar); 424 generateJar(false, MODULE_TYPE.EXPLICIT, 425 MODULAR_CLIENT_AUTO_DEPEND_JAR, CLIENT_BUILD_DIR, 426 false, useSignedJar); 427 generateJar(false, MODULE_TYPE.UNNAMED, 428 REGULAR_CLIENT_JAR, CLIENT_BUILD_DIR, false, useSignedJar); 429 430 System.out.println(String.format( 431 "Artifacts generated successfully? '%s'", done)); 432 } catch (IOException e) { 433 e.printStackTrace(System.out); 434 done = false; 435 } 436 return done; 437 } 438 439 //Generate modular/regular jar based on module type. 440 private static void generateJar(boolean service, MODULE_TYPE moduleType, 441 Path jarFile, Path compilePath, boolean depends, 442 boolean useSignedJar) throws IOException { 443 444 ModuleDescriptor moduleDescriptor = null; 445 if (service) { 446 moduleDescriptor = generateModuleDescriptor(service, moduleType, 447 SERVICE_MODULE_NAME, SERVICE_PKG, 448 LOGIN_SERVICE_INTERFACE, SERVICE_IMPL, null, 449 REQUIRED_MODULES, depends); 450 } else { 451 moduleDescriptor = generateModuleDescriptor(service, 452 moduleType, CLIENT_MODULE_NAME, CLIENT_PKG, 453 LOGIN_SERVICE_INTERFACE, null, SERVICE_MODULE_NAME, 454 REQUIRED_MODULES, depends); 455 } 456 System.out.println(String.format( 457 "Creating jar file '%s'", jarFile)); 458 JarUtils.createJarFile(jarFile, compilePath); 459 if (moduleDescriptor != null) { 460 Path dir = Files.createTempDirectory("tmp"); 461 Path mi = dir.resolve("module-info.class"); 462 try (OutputStream out = Files.newOutputStream(mi)) { 463 ModuleInfoWriter.write(moduleDescriptor, out); 464 } 465 System.out.println(String.format( 466 "Adding 'module-info.class' to jar file '%s'", jarFile)); 467 JarUtils.updateJarFile(jarFile, dir); 468 } 469 //If the jar holds provider implementation then sign it. 470 if (service && useSignedJar) { 471 signJar(jarFile, KEYSTORE_PATH.toRealPath().toString(), 472 STORE_PASSWORD, ALIAS); 473 } 474 } 475 476 //Construct class path argument value. 477 private static StringBuilder getClassPath(MODULE_TYPE clientModuleType, 478 Path clientJarPath, MODULE_TYPE serviceModuletype, 479 Path serviceJarPath) throws IOException { 480 481 StringBuilder classPath = new StringBuilder(); 482 classPath.append((clientModuleType == MODULE_TYPE.UNNAMED) 483 ? (clientJarPath.toRealPath().toString() 484 + File.pathSeparatorChar) : ""); 485 classPath.append((serviceModuletype == MODULE_TYPE.UNNAMED) 486 ? serviceJarPath.toRealPath().toString() : ""); 487 return classPath; 488 } 489 490 //Construct client modulename to run the client. It is fixed for explicit 491 //module type while it is same as jar file name for automated module type. 492 private static String getClientModuleName(MODULE_TYPE clientModuleType, 493 Path clientJarPath) { 494 495 String jarFileName = clientJarPath.toFile().getName(); 496 return (clientModuleType == MODULE_TYPE.EXPLICIT) 497 ? CLIENT_MODULE_NAME 498 : ((clientModuleType == MODULE_TYPE.AUTO) 499 ? jarFileName.substring( 500 0, jarFileName.indexOf(JAR_EXTN)) : ""); 501 } 502 503 //Delete all the files inside the base module path. 504 private static void cleanModuleBasePath() { 505 506 Arrays.asList(EXPLICIT_MODULE_BASE_PATH.toFile().listFiles()) 507 .forEach(f -> { 508 System.out.println("delete " + f); 509 f.delete(); 510 }); 511 System.out.println("------------------------------------------------"); 512 } 513 514 //Generate a keystore with random keys. 515 public static boolean generateKeyStore(String keyStoreFile, 516 String password, String alias) throws IOException { 517 boolean created = true; 518 Path parent = KEYSTORE_PATH.getParent(); 519 if (parent != null) { 520 Files.createDirectories(parent); 521 } 522 try (FileOutputStream keyStoreOut 523 = new FileOutputStream(keyStoreFile)) { 524 525 KeyStore keyStore = KeyStore.getInstance("JKS"); 526 keyStore.load(null, null); 527 528 CertAndKeyGen keyGen 529 = new CertAndKeyGen("RSA", "SHA1WithRSA", null); 530 keyGen.generate(2048); 531 //Generate self signed certificate 532 Certificate[] chain = new X509Certificate[1]; 533 chain[0] = keyGen.getSelfCertificate( 534 new X500Name("CN=ROOT"), (long) 365 * 24 * 3600); 535 keyStore.setKeyEntry(alias, keyGen.getPrivateKey(), 536 password.toCharArray(), chain); 537 538 keyStore.store(keyStoreOut, password.toCharArray()); 539 } catch (Exception e) { 540 created = false; 541 e.printStackTrace(System.out); 542 } 543 return created; 544 } 545 546 //Sign a jar file by provided keystore file. 547 public static void signJar(Path jarFile, String keyStore, 548 String password, String alias) { 549 try { 550 JDKToolLauncher jarsigner = JDKToolLauncher.create("jarsigner") 551 .addToolArg("-keystore") 552 .addToolArg(keyStore) 553 .addToolArg("-storepass") 554 .addToolArg(password) 555 .addToolArg("-keypass") 556 .addToolArg(password) 557 .addToolArg(jarFile.toFile().getCanonicalPath()) 558 .addToolArg(alias); 559 ProcessBuilder processBuilder 560 = new ProcessBuilder(jarsigner.getCommand()); 561 OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); 562 System.out.println( 563 "_________________BEGIN JAR SIGN OUTPUT__________________"); 564 System.out.println(output.getOutput()); 565 System.out.println( 566 "_______________________END OUTPUT_______________________"); 567 output.shouldHaveExitValue(0); 568 } catch (Exception e) { 569 throw new RuntimeException(String.format( 570 "Unable to sign Jar file '%s'", jarFile)); 571 } 572 } 573 574 }