68 import java.util.Collections;
69 import java.util.Comparator;
70 import java.util.HashSet;
71 import java.util.Iterator;
72 import java.util.List;
73 import java.util.Locale;
74 import java.util.Locale.Category;
75 import java.util.Map;
76 import java.util.Optional;
77 import java.util.Properties;
78 import java.util.ResourceBundle;
79 import java.util.Set;
80 import java.util.TreeSet;
81 import java.util.jar.Attributes;
82 import java.util.jar.JarFile;
83 import java.util.jar.Manifest;
84 import java.util.stream.Collectors;
85 import java.util.stream.Stream;
86
87 import jdk.internal.misc.VM;
88 import jdk.internal.module.IllegalAccessLogger;
89 import jdk.internal.module.Modules;
90
91
92 public final class LauncherHelper {
93
94 // No instantiation
95 private LauncherHelper() {}
96
97 // used to identify JavaFX applications
98 private static final String JAVAFX_APPLICATION_MARKER =
99 "JavaFX-Application-Class";
100 private static final String JAVAFX_APPLICATION_CLASS_NAME =
101 "javafx.application.Application";
102 private static final String JAVAFX_FXHELPER_CLASS_NAME_SUFFIX =
103 "sun.launcher.LauncherHelper$FXHelper";
104 private static final String MAIN_CLASS = "Main-Class";
105 private static final String ADD_EXPORTS = "Add-Exports";
106 private static final String ADD_OPENS = "Add-Opens";
107
108 private static StringBuilder outBuf = new StringBuilder();
412 }
413
414 static String getMainClassFromJar(String jarname) {
415 String mainValue = null;
416 try (JarFile jarFile = new JarFile(jarname)) {
417 Manifest manifest = jarFile.getManifest();
418 if (manifest == null) {
419 abort(null, "java.launcher.jar.error2", jarname);
420 }
421 Attributes mainAttrs = manifest.getMainAttributes();
422 if (mainAttrs == null) {
423 abort(null, "java.launcher.jar.error3", jarname);
424 }
425
426 // Main-Class
427 mainValue = mainAttrs.getValue(MAIN_CLASS);
428 if (mainValue == null) {
429 abort(null, "java.launcher.jar.error3", jarname);
430 }
431
432 // Add-Exports and Add-Opens to allow illegal access
433 String exports = mainAttrs.getValue(ADD_EXPORTS);
434 if (exports != null) {
435 String warn = getLocalizedMessage("java.launcher.permitaccess.warning",
436 jarname, ADD_EXPORTS);
437 System.err.println(warn);
438 addExportsOrOpens(exports, false, ADD_EXPORTS);
439 }
440 String opens = mainAttrs.getValue(ADD_OPENS);
441 if (opens != null) {
442 String warn = getLocalizedMessage("java.launcher.permitaccess.warning",
443 jarname, ADD_OPENS);
444 System.err.println(warn);
445 addExportsOrOpens(opens, true, ADD_OPENS);
446 }
447
448 /*
449 * Hand off to FXHelper if it detects a JavaFX application
450 * This must be done after ensuring a Main-Class entry
451 * exists to enforce compliance with the jar specification
452 */
453 if (mainAttrs.containsKey(
454 new Attributes.Name(JAVAFX_APPLICATION_MARKER))) {
455 FXHelper.setFXLaunchParameters(jarname, LM_JAR);
456 return FXHelper.class.getName();
457 }
458
459 return mainValue.trim();
460 } catch (IOException ioe) {
461 abort(ioe, "java.launcher.jar.error1", jarname);
462 }
463 return null;
464 }
465
466 /**
467 * Process the Add-Exports or Add-Opens value. The value is
468 * {@code <module>/<package> ( <module>/<package>)*}.
469 */
470 static void addExportsOrOpens(String value, boolean open, String how) {
471 IllegalAccessLogger.Builder builder;
472 IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
473 if (logger == null) {
474 builder = new IllegalAccessLogger.Builder();
475 } else {
476 builder = logger.toBuilder();
477 }
478
479 for (String moduleAndPackage : value.split(" ")) {
480 String[] s = moduleAndPackage.trim().split("/");
481 if (s.length == 2) {
482 String mn = s[0];
483 String pn = s[1];
484
485 Layer.boot().findModule(mn).ifPresent(m -> {
486 if (m.getDescriptor().packages().contains(pn)) {
487 if (open) {
488 builder.logAccessToOpenPackage(m, pn, how);
489 Modules.addOpensToAllUnnamed(m, pn);
490 } else {
491 builder.logAccessToExportedPackage(m, pn, how);
492 Modules.addExportsToAllUnnamed(m, pn);
493 }
494 }
495 });
496 }
497 }
498
499 IllegalAccessLogger.setIllegalAccessLogger(builder.build());
500 }
501
502 // From src/share/bin/java.c:
503 // enum LaunchMode { LM_UNKNOWN = 0, LM_CLASS, LM_JAR, LM_MODULE }
504
505 private static final int LM_UNKNOWN = 0;
506 private static final int LM_CLASS = 1;
507 private static final int LM_JAR = 2;
508 private static final int LM_MODULE = 3;
509
510 static void abort(Throwable t, String msgKey, Object... args) {
511 if (msgKey != null) {
512 ostream.println(getLocalizedMessage(msgKey, args));
513 }
514 if (trace) {
515 if (t != null) {
516 t.printStackTrace();
517 } else {
518 Thread.dumpStack();
519 }
|
68 import java.util.Collections;
69 import java.util.Comparator;
70 import java.util.HashSet;
71 import java.util.Iterator;
72 import java.util.List;
73 import java.util.Locale;
74 import java.util.Locale.Category;
75 import java.util.Map;
76 import java.util.Optional;
77 import java.util.Properties;
78 import java.util.ResourceBundle;
79 import java.util.Set;
80 import java.util.TreeSet;
81 import java.util.jar.Attributes;
82 import java.util.jar.JarFile;
83 import java.util.jar.Manifest;
84 import java.util.stream.Collectors;
85 import java.util.stream.Stream;
86
87 import jdk.internal.misc.VM;
88 import jdk.internal.module.Modules;
89
90
91 public final class LauncherHelper {
92
93 // No instantiation
94 private LauncherHelper() {}
95
96 // used to identify JavaFX applications
97 private static final String JAVAFX_APPLICATION_MARKER =
98 "JavaFX-Application-Class";
99 private static final String JAVAFX_APPLICATION_CLASS_NAME =
100 "javafx.application.Application";
101 private static final String JAVAFX_FXHELPER_CLASS_NAME_SUFFIX =
102 "sun.launcher.LauncherHelper$FXHelper";
103 private static final String MAIN_CLASS = "Main-Class";
104 private static final String ADD_EXPORTS = "Add-Exports";
105 private static final String ADD_OPENS = "Add-Opens";
106
107 private static StringBuilder outBuf = new StringBuilder();
411 }
412
413 static String getMainClassFromJar(String jarname) {
414 String mainValue = null;
415 try (JarFile jarFile = new JarFile(jarname)) {
416 Manifest manifest = jarFile.getManifest();
417 if (manifest == null) {
418 abort(null, "java.launcher.jar.error2", jarname);
419 }
420 Attributes mainAttrs = manifest.getMainAttributes();
421 if (mainAttrs == null) {
422 abort(null, "java.launcher.jar.error3", jarname);
423 }
424
425 // Main-Class
426 mainValue = mainAttrs.getValue(MAIN_CLASS);
427 if (mainValue == null) {
428 abort(null, "java.launcher.jar.error3", jarname);
429 }
430
431 // Add-Exports and Add-Opens
432 String exports = mainAttrs.getValue(ADD_EXPORTS);
433 if (exports != null) {
434 addExportsOrOpens(exports, false);
435 }
436 String opens = mainAttrs.getValue(ADD_OPENS);
437 if (opens != null) {
438 addExportsOrOpens(opens, true);
439 }
440
441 /*
442 * Hand off to FXHelper if it detects a JavaFX application
443 * This must be done after ensuring a Main-Class entry
444 * exists to enforce compliance with the jar specification
445 */
446 if (mainAttrs.containsKey(
447 new Attributes.Name(JAVAFX_APPLICATION_MARKER))) {
448 FXHelper.setFXLaunchParameters(jarname, LM_JAR);
449 return FXHelper.class.getName();
450 }
451
452 return mainValue.trim();
453 } catch (IOException ioe) {
454 abort(ioe, "java.launcher.jar.error1", jarname);
455 }
456 return null;
457 }
458
459 /**
460 * Process the Add-Exports or Add-Opens value. The value is
461 * {@code <module>/<package> ( <module>/<package>)*}.
462 */
463 static void addExportsOrOpens(String value, boolean open) {
464 for (String moduleAndPackage : value.split(" ")) {
465 String[] s = moduleAndPackage.trim().split("/");
466 if (s.length == 2) {
467 String mn = s[0];
468 String pn = s[1];
469
470 Layer.boot().findModule(mn).ifPresent(m -> {
471 if (m.getDescriptor().packages().contains(pn)) {
472 if (open) {
473 Modules.addOpensToAllUnnamed(m, pn);
474 } else {
475 Modules.addExportsToAllUnnamed(m, pn);
476 }
477 }
478 });
479 }
480 }
481 }
482
483 // From src/share/bin/java.c:
484 // enum LaunchMode { LM_UNKNOWN = 0, LM_CLASS, LM_JAR, LM_MODULE }
485
486 private static final int LM_UNKNOWN = 0;
487 private static final int LM_CLASS = 1;
488 private static final int LM_JAR = 2;
489 private static final int LM_MODULE = 3;
490
491 static void abort(Throwable t, String msgKey, Object... args) {
492 if (msgKey != null) {
493 ostream.println(getLocalizedMessage(msgKey, args));
494 }
495 if (trace) {
496 if (t != null) {
497 t.printStackTrace();
498 } else {
499 Thread.dumpStack();
500 }
|