[SCM] jigsaw packaging branch, master, updated. 7327deefd98bfe38bceb86e806b898ed06678ec2
Guillaume Mazoyer
gmazoyer-guest at alioth.debian.org
Fri Sep 16 18:53:59 UTC 2011
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "jigsaw packaging".
The branch, master has been updated
via 7327deefd98bfe38bceb86e806b898ed06678ec2 (commit)
from b9530e7570ad7129cc257110036bf00a5287321c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 7327deefd98bfe38bceb86e806b898ed06678ec2
Author: Mandy Chung <mandy.chung at oracle.com>
Date: Fri Sep 16 20:50:39 2011 +0200
Sync the latest changes of Jigsaw.
-----------------------------------------------------------------------
Summary of changes:
jdk/.hg/branchheads.cache | 4 +-
jdk/.hg/dirstate | Bin 1389715 -> 1390463 bytes
jdk/.hg/store/00changelog.d | Bin 1307396 -> 1308925 bytes
jdk/.hg/store/00changelog.i | Bin 300928 -> 301248 bytes
jdk/.hg/store/00manifest.d | Bin 24643788 -> 24647180 bytes
jdk/.hg/store/00manifest.i | Bin 300352 -> 300672 bytes
jdk/.hg/store/data/make/common/_defs-modules.gmk.i | Bin 3180 -> 3306 bytes
.../data/make/java/java/_f_i_l_e_s__java.gmk.i | Bin 20806 -> 20952 bytes
jdk/.hg/store/data/make/modules/_makefile.i | Bin 25295 -> 25576 bytes
jdk/.hg/store/data/make/modules/modules.config.i | Bin 33108 -> 33451 bytes
jdk/.hg/store/data/make/modules/modules.group.i | Bin 11781 -> 12550 bytes
.../store/data/make/modules/modules.properties.i | Bin 1655 -> 3547 bytes
.../make/tools/classanalyzer/classanalyzer.html.i | Bin 0 -> 2278 bytes
.../sun/classanalyzer/_annotation_parser.java.i | Bin 3615 -> 3867 bytes
.../com/sun/classanalyzer/_boot_analyzer.java.i | Bin 8193 -> 8656 bytes
.../com/sun/classanalyzer/_class_analyzer.java.i | Bin 8399 -> 10177 bytes
.../sun/classanalyzer/_class_file_parser.java.i | Bin 4900 -> 5049 bytes
.../sun/classanalyzer/_class_list_reader.java.i | Bin 2026 -> 2723 bytes
.../src/com/sun/classanalyzer/_class_path.java.i | Bin 6464 -> 6741 bytes
.../src/com/sun/classanalyzer/_files.java.i | Bin 1383 -> 1521 bytes
.../classanalyzer/_jigsaw_module_builder.java.i | Bin 0 -> 1925 bytes
.../src/com/sun/classanalyzer/_modularizer.java.i | Bin 4127 -> 4291 bytes
.../src/com/sun/classanalyzer/_module.java.i | Bin 10540 -> 12653 bytes
.../com/sun/classanalyzer/_module_builder.java.i | Bin 4190 -> 6901 bytes
.../com/sun/classanalyzer/_module_config.java.i | Bin 5741 -> 6729 bytes
.../src/com/sun/classanalyzer/_module_info.java.i | Bin 3076 -> 4856 bytes
.../src/com/sun/classanalyzer/_package_info.java.i | Bin 0 -> 2498 bytes
.../classanalyzer/_platform_module_builder.java.i | Bin 4248 -> 7002 bytes
.../com/sun/classanalyzer/_resource_file.java.i | Bin 3448 -> 4017 bytes
.../data/src/share/classes/java/lang/_class.java.i | Bin 32433 -> 33636 bytes
.../classes/java/lang/_security_manager.java.i | Bin 12748 -> 13197 bytes
.../java/lang/module/_module_class_loader.java.i | Bin 3295 -> 3743 bytes
.../module/_module_not_present_exception.java.i | Bin 0 -> 1068 bytes
.../lang/module/_require_optional_module.java.i | Bin 0 -> 1025 bytes
.../_unsupported_element_type_exception.java.i | Bin 1981 -> 2109 bytes
.../src/share/classes/java/util/_properties.java.i | Bin 12758 -> 13048 bytes
.../share/classes/java/util/jar/_jar_file.java.i | Bin 7801 -> 8350 bytes
.../java/util/prefs/_abstract_preferences.java.i | Bin 14757 -> 15032 bytes
.../classes/java/util/prefs/_preferences.java.i | Bin 12865 -> 13114 bytes
.../classes/org/openjdk/jigsaw/_boot_loader.java.i | Bin 2775 -> 3346 bytes
.../classes/org/openjdk/jigsaw/_context.java.i | Bin 4684 -> 5034 bytes
.../classes/org/openjdk/jigsaw/_launcher.java.i | Bin 4558 -> 4634 bytes
.../classes/org/openjdk/jigsaw/_linker.java.i | Bin 4835 -> 5175 bytes
.../classes/org/openjdk/jigsaw/_loader.java.i | Bin 13376 -> 14337 bytes
.../classes/org/openjdk/jigsaw/_loader_pool.java.i | Bin 5348 -> 5476 bytes
.../classes/org/openjdk/jigsaw/_path_linker.java.i | Bin 2945 -> 3077 bytes
.../org/openjdk/jigsaw/_simple_library.java.i | Bin 30365 -> 30911 bytes
.../src/share/classes/sun/tools/jar/_main.java.i | Bin 15841 -> 18757 bytes
.../classes/sun/tools/jar/_module_info.java.i | Bin 0 -> 2406 bytes
.../sun/tools/jar/resources/jar.properties.i | Bin 2033 -> 2579 bytes
.../test/org/openjdk/jigsaw/___configurator.java.i | Bin 7618 -> 7986 bytes
.../jigsaw/___remote_repository_list.java.i | Bin 2792 -> 3155 bytes
.../org/openjdk/jigsaw/cli/signed-modular-jar.sh.i | Bin 1646 -> 1796 bytes
.../data/test/org/openjdk/jigsaw/hello-jar.sh.i | Bin 1317 -> 2379 bytes
.../test/org/openjdk/jigsaw/hello-optional.sh.i | Bin 0 -> 1299 bytes
.../test/org/openjdk/jigsaw/optional-base.sh.i | Bin 0 -> 1256 bytes
.../test/org/openjdk/jigsaw/optional-deps.sh.i | Bin 2485 -> 2604 bytes
.../test/org/openjdk/jigsaw/optional-jaxp.sh.i | Bin 0 -> 1124 bytes
.../test/org/openjdk/jigsaw/optional-reexport.sh.i | Bin 0 -> 1304 bytes
.../data/test/org/openjdk/jigsaw/properties.xml.i | Bin 0 -> 215 bytes
.../store/data/test/org/openjdk/jigsaw/tester.sh.i | Bin 5571 -> 5842 bytes
jdk/.hg/store/fncache | 11 +
jdk/.hg/store/undo | Bin 14507 -> 3619 bytes
jdk/.hg/undo.desc | 2 +-
jdk/.hg/undo.dirstate | Bin 1390092 -> 1389715 bytes
jdk/make/common/Defs-modules.gmk | 6 +-
jdk/make/java/java/FILES_java.gmk | 2 +
jdk/make/modules/Makefile | 14 +-
jdk/make/modules/modules.config | 17 +-
jdk/make/modules/modules.group | 47 ++-
jdk/make/modules/modules.properties | 272 ++++++++++++++-
jdk/make/tools/classanalyzer/classanalyzer.html | 131 +++++++
.../com/sun/classanalyzer/AnnotationParser.java | 12 +-
.../src/com/sun/classanalyzer/BootAnalyzer.java | 17 +-
.../src/com/sun/classanalyzer/ClassAnalyzer.java | 123 ++++---
.../src/com/sun/classanalyzer/ClassFileParser.java | 4 +-
.../src/com/sun/classanalyzer/ClassListReader.java | 79 ++---
.../src/com/sun/classanalyzer/ClassPath.java | 10 +-
.../src/com/sun/classanalyzer/Files.java | 2 +-
.../com/sun/classanalyzer/JigsawModuleBuilder.java | 133 +++++++
.../src/com/sun/classanalyzer/Modularizer.java | 4 +-
.../src/com/sun/classanalyzer/Module.java | 244 ++++++++-----
.../src/com/sun/classanalyzer/ModuleBuilder.java | 339 ++++++++---------
.../src/com/sun/classanalyzer/ModuleConfig.java | 70 +++--
.../src/com/sun/classanalyzer/ModuleInfo.java | 249 ++++++++-----
.../src/com/sun/classanalyzer/PackageInfo.java | 171 +++++++++
.../sun/classanalyzer/PlatformModuleBuilder.java | 363 +++++++++----------
.../src/com/sun/classanalyzer/ResourceFile.java | 28 ++-
jdk/src/share/classes/java/lang/Class.java | 83 ++++-
.../share/classes/java/lang/SecurityManager.java | 21 +-
.../java/lang/module/ModuleClassLoader.java | 28 ++-
.../lang/module/ModuleNotPresentException.java | 73 ++++
.../java/lang/module/RequireOptionalModule.java | 48 +++
.../module/UnsupportedElementTypeException.java | 2 +-
jdk/src/share/classes/java/util/Properties.java | 14 +
jdk/src/share/classes/java/util/jar/JarFile.java | 33 ++-
.../java/util/prefs/AbstractPreferences.java | 8 +
.../share/classes/java/util/prefs/Preferences.java | 6 +
.../classes/org/openjdk/jigsaw/BootLoader.java | 36 ++-
.../share/classes/org/openjdk/jigsaw/Context.java | 19 +
.../share/classes/org/openjdk/jigsaw/Launcher.java | 1 -
.../share/classes/org/openjdk/jigsaw/Linker.java | 10 +-
.../share/classes/org/openjdk/jigsaw/Loader.java | 107 +++---
.../classes/org/openjdk/jigsaw/LoaderPool.java | 2 +-
.../classes/org/openjdk/jigsaw/PathLinker.java | 4 +
.../classes/org/openjdk/jigsaw/SimpleLibrary.java | 41 +--
jdk/src/share/classes/sun/tools/jar/Main.java | 383 +++++++++++++-------
.../share/classes/sun/tools/jar/ModuleInfo.java | 195 ++++++++++
.../classes/sun/tools/jar/resources/jar.properties | 20 +-
jdk/test/org/openjdk/jigsaw/_Configurator.java | 21 +
.../org/openjdk/jigsaw/_RemoteRepositoryList.java | 17 +-
.../org/openjdk/jigsaw/cli/signed-modular-jar.sh | 5 +-
jdk/test/org/openjdk/jigsaw/hello-jar.sh | 103 +++++-
jdk/test/org/openjdk/jigsaw/hello-optional.sh | 160 ++++++++
jdk/test/org/openjdk/jigsaw/optional-base.sh | 89 +++++
jdk/test/org/openjdk/jigsaw/optional-deps.sh | 2 +-
jdk/test/org/openjdk/jigsaw/optional-jaxp.sh | 62 ++++
jdk/test/org/openjdk/jigsaw/optional-reexport.sh | 94 +++++
jdk/test/org/openjdk/jigsaw/properties.xml | 5 +
jdk/test/org/openjdk/jigsaw/tester.sh | 9 +-
langtools/.hg/branchheads.cache | 4 +-
langtools/.hg/dirstate | Bin 298937 -> 298937 bytes
langtools/.hg/store/00changelog.d | Bin 295230 -> 295482 bytes
langtools/.hg/store/00changelog.i | Bin 71296 -> 71360 bytes
langtools/.hg/store/00manifest.d | Bin 1844155 -> 1844323 bytes
langtools/.hg/store/00manifest.i | Bin 71168 -> 71232 bytes
.../classfile/_module_export__attribute.java.i | Bin 1332 -> 1476 bytes
.../classfile/_module_requires__attribute.java.i | Bin 1856 -> 2027 bytes
langtools/.hg/store/undo | Bin 2528 -> 247 bytes
langtools/.hg/undo.desc | 2 +-
langtools/.hg/undo.dirstate | Bin 298285 -> 298937 bytes
.../tools/classfile/ModuleExport_attribute.java | 5 +
.../tools/classfile/ModuleRequires_attribute.java | 6 +
133 files changed, 3077 insertions(+), 995 deletions(-)
diff --git a/jdk/.hg/branchheads.cache b/jdk/.hg/branchheads.cache
index f6751c3..3dc3c82 100644
--- a/jdk/.hg/branchheads.cache
+++ b/jdk/.hg/branchheads.cache
@@ -1,2 +1,2 @@
-ed4c673a9e2fe055512aa28acab433899e11b596 4701
-ed4c673a9e2fe055512aa28acab433899e11b596 default
+50f24359f6882cb6df431cd66a87865fdf2eb844 4706
+50f24359f6882cb6df431cd66a87865fdf2eb844 default
diff --git a/jdk/.hg/dirstate b/jdk/.hg/dirstate
index 76ee247..2fe9e49 100644
Binary files a/jdk/.hg/dirstate and b/jdk/.hg/dirstate differ
diff --git a/jdk/.hg/store/00changelog.d b/jdk/.hg/store/00changelog.d
index 03b62e5..8109ca2 100644
Binary files a/jdk/.hg/store/00changelog.d and b/jdk/.hg/store/00changelog.d differ
diff --git a/jdk/.hg/store/00changelog.i b/jdk/.hg/store/00changelog.i
index e2e350a..161a024 100644
Binary files a/jdk/.hg/store/00changelog.i and b/jdk/.hg/store/00changelog.i differ
diff --git a/jdk/.hg/store/00manifest.d b/jdk/.hg/store/00manifest.d
index 9f9ebf5..0b2cbbf 100644
Binary files a/jdk/.hg/store/00manifest.d and b/jdk/.hg/store/00manifest.d differ
diff --git a/jdk/.hg/store/00manifest.i b/jdk/.hg/store/00manifest.i
index 240f7e4..83c8f4d 100644
Binary files a/jdk/.hg/store/00manifest.i and b/jdk/.hg/store/00manifest.i differ
diff --git a/jdk/.hg/store/data/make/common/_defs-modules.gmk.i b/jdk/.hg/store/data/make/common/_defs-modules.gmk.i
index 25504bd..0866d3c 100644
Binary files a/jdk/.hg/store/data/make/common/_defs-modules.gmk.i and b/jdk/.hg/store/data/make/common/_defs-modules.gmk.i differ
diff --git a/jdk/.hg/store/data/make/java/java/_f_i_l_e_s__java.gmk.i b/jdk/.hg/store/data/make/java/java/_f_i_l_e_s__java.gmk.i
index 72bb3f8..f275c95 100644
Binary files a/jdk/.hg/store/data/make/java/java/_f_i_l_e_s__java.gmk.i and b/jdk/.hg/store/data/make/java/java/_f_i_l_e_s__java.gmk.i differ
diff --git a/jdk/.hg/store/data/make/modules/_makefile.i b/jdk/.hg/store/data/make/modules/_makefile.i
index b081a04..7141399 100644
Binary files a/jdk/.hg/store/data/make/modules/_makefile.i and b/jdk/.hg/store/data/make/modules/_makefile.i differ
diff --git a/jdk/.hg/store/data/make/modules/modules.config.i b/jdk/.hg/store/data/make/modules/modules.config.i
index a7a5d6b..2087795 100644
Binary files a/jdk/.hg/store/data/make/modules/modules.config.i and b/jdk/.hg/store/data/make/modules/modules.config.i differ
diff --git a/jdk/.hg/store/data/make/modules/modules.group.i b/jdk/.hg/store/data/make/modules/modules.group.i
index 085f162..fc22baf 100644
Binary files a/jdk/.hg/store/data/make/modules/modules.group.i and b/jdk/.hg/store/data/make/modules/modules.group.i differ
diff --git a/jdk/.hg/store/data/make/modules/modules.properties.i b/jdk/.hg/store/data/make/modules/modules.properties.i
index 93bb9e4..6acb7e5 100644
Binary files a/jdk/.hg/store/data/make/modules/modules.properties.i and b/jdk/.hg/store/data/make/modules/modules.properties.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/classanalyzer.html.i b/jdk/.hg/store/data/make/tools/classanalyzer/classanalyzer.html.i
new file mode 100644
index 0000000..eebe298
Binary files /dev/null and b/jdk/.hg/store/data/make/tools/classanalyzer/classanalyzer.html.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_annotation_parser.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_annotation_parser.java.i
index 9ec3abe..955ae74 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_annotation_parser.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_annotation_parser.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_boot_analyzer.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_boot_analyzer.java.i
index 4848b90..35d393a 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_boot_analyzer.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_boot_analyzer.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_analyzer.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_analyzer.java.i
index d4274fb..c336e2c 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_analyzer.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_analyzer.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_file_parser.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_file_parser.java.i
index 0a81ca8..1a3ba18 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_file_parser.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_file_parser.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_list_reader.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_list_reader.java.i
index 414ce24..327a23f 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_list_reader.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_list_reader.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_path.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_path.java.i
index 570163f..692f770 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_path.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_class_path.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_files.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_files.java.i
index 3c17889..c569e1c 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_files.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_files.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_jigsaw_module_builder.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_jigsaw_module_builder.java.i
new file mode 100644
index 0000000..017d87d
Binary files /dev/null and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_jigsaw_module_builder.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_modularizer.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_modularizer.java.i
index b1c16fe..6401dd6 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_modularizer.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_modularizer.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module.java.i
index 63ab72c..588ace9 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_builder.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_builder.java.i
index ae3d37b..e61ae97 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_builder.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_builder.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_config.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_config.java.i
index 8adbe7b..aed6f4c 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_config.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_config.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_info.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_info.java.i
index c77161a..284b015 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_info.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_module_info.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_package_info.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_package_info.java.i
new file mode 100644
index 0000000..2a1e031
Binary files /dev/null and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_package_info.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_platform_module_builder.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_platform_module_builder.java.i
index 5bed7bf..58d6d4a 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_platform_module_builder.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_platform_module_builder.java.i differ
diff --git a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_resource_file.java.i b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_resource_file.java.i
index 0ea8e60..adffea8 100644
Binary files a/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_resource_file.java.i and b/jdk/.hg/store/data/make/tools/classanalyzer/src/com/sun/classanalyzer/_resource_file.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/lang/_class.java.i b/jdk/.hg/store/data/src/share/classes/java/lang/_class.java.i
index 7b9a84c..8086022 100644
Binary files a/jdk/.hg/store/data/src/share/classes/java/lang/_class.java.i and b/jdk/.hg/store/data/src/share/classes/java/lang/_class.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/lang/_security_manager.java.i b/jdk/.hg/store/data/src/share/classes/java/lang/_security_manager.java.i
index f2060e5..c37ed9a 100644
Binary files a/jdk/.hg/store/data/src/share/classes/java/lang/_security_manager.java.i and b/jdk/.hg/store/data/src/share/classes/java/lang/_security_manager.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/lang/module/_module_class_loader.java.i b/jdk/.hg/store/data/src/share/classes/java/lang/module/_module_class_loader.java.i
index cfc2322..3fb9ac8 100644
Binary files a/jdk/.hg/store/data/src/share/classes/java/lang/module/_module_class_loader.java.i and b/jdk/.hg/store/data/src/share/classes/java/lang/module/_module_class_loader.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/lang/module/_module_not_present_exception.java.i b/jdk/.hg/store/data/src/share/classes/java/lang/module/_module_not_present_exception.java.i
new file mode 100644
index 0000000..256257c
Binary files /dev/null and b/jdk/.hg/store/data/src/share/classes/java/lang/module/_module_not_present_exception.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/lang/module/_require_optional_module.java.i b/jdk/.hg/store/data/src/share/classes/java/lang/module/_require_optional_module.java.i
new file mode 100644
index 0000000..436629b
Binary files /dev/null and b/jdk/.hg/store/data/src/share/classes/java/lang/module/_require_optional_module.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/lang/module/_unsupported_element_type_exception.java.i b/jdk/.hg/store/data/src/share/classes/java/lang/module/_unsupported_element_type_exception.java.i
index efb8371..50750d4 100644
Binary files a/jdk/.hg/store/data/src/share/classes/java/lang/module/_unsupported_element_type_exception.java.i and b/jdk/.hg/store/data/src/share/classes/java/lang/module/_unsupported_element_type_exception.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/util/_properties.java.i b/jdk/.hg/store/data/src/share/classes/java/util/_properties.java.i
index be09b6b..ecd2bbf 100644
Binary files a/jdk/.hg/store/data/src/share/classes/java/util/_properties.java.i and b/jdk/.hg/store/data/src/share/classes/java/util/_properties.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/util/jar/_jar_file.java.i b/jdk/.hg/store/data/src/share/classes/java/util/jar/_jar_file.java.i
index cf62547..3bd797d 100644
Binary files a/jdk/.hg/store/data/src/share/classes/java/util/jar/_jar_file.java.i and b/jdk/.hg/store/data/src/share/classes/java/util/jar/_jar_file.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/util/prefs/_abstract_preferences.java.i b/jdk/.hg/store/data/src/share/classes/java/util/prefs/_abstract_preferences.java.i
index 4192a8a..aafe95b 100644
Binary files a/jdk/.hg/store/data/src/share/classes/java/util/prefs/_abstract_preferences.java.i and b/jdk/.hg/store/data/src/share/classes/java/util/prefs/_abstract_preferences.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/java/util/prefs/_preferences.java.i b/jdk/.hg/store/data/src/share/classes/java/util/prefs/_preferences.java.i
index e59c149..f3ebc09 100644
Binary files a/jdk/.hg/store/data/src/share/classes/java/util/prefs/_preferences.java.i and b/jdk/.hg/store/data/src/share/classes/java/util/prefs/_preferences.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_boot_loader.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_boot_loader.java.i
index 694d101..574b337 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_boot_loader.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_boot_loader.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_context.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_context.java.i
index 69eb3c1..d890bef 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_context.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_context.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_launcher.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_launcher.java.i
index 472f2d6..68baaf1 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_launcher.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_launcher.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_linker.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_linker.java.i
index 68cad89..6efaae9 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_linker.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_linker.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_loader.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_loader.java.i
index 37584c4..3caad1a 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_loader.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_loader.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_loader_pool.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_loader_pool.java.i
index 114d2e0..9e93655 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_loader_pool.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_loader_pool.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_path_linker.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_path_linker.java.i
index 94e1b77..255c4df 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_path_linker.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_path_linker.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_simple_library.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_simple_library.java.i
index a1a20d3..df2da6c 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_simple_library.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_simple_library.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/sun/tools/jar/_main.java.i b/jdk/.hg/store/data/src/share/classes/sun/tools/jar/_main.java.i
index 25d720d..34a1db7 100644
Binary files a/jdk/.hg/store/data/src/share/classes/sun/tools/jar/_main.java.i and b/jdk/.hg/store/data/src/share/classes/sun/tools/jar/_main.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/sun/tools/jar/_module_info.java.i b/jdk/.hg/store/data/src/share/classes/sun/tools/jar/_module_info.java.i
new file mode 100644
index 0000000..77233b2
Binary files /dev/null and b/jdk/.hg/store/data/src/share/classes/sun/tools/jar/_module_info.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/sun/tools/jar/resources/jar.properties.i b/jdk/.hg/store/data/src/share/classes/sun/tools/jar/resources/jar.properties.i
index f872de3..7260ddf 100644
Binary files a/jdk/.hg/store/data/src/share/classes/sun/tools/jar/resources/jar.properties.i and b/jdk/.hg/store/data/src/share/classes/sun/tools/jar/resources/jar.properties.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/___configurator.java.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/___configurator.java.i
index e3d6e17..8e3cd12 100644
Binary files a/jdk/.hg/store/data/test/org/openjdk/jigsaw/___configurator.java.i and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/___configurator.java.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/___remote_repository_list.java.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/___remote_repository_list.java.i
index 06b4632..b67b049 100644
Binary files a/jdk/.hg/store/data/test/org/openjdk/jigsaw/___remote_repository_list.java.i and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/___remote_repository_list.java.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/cli/signed-modular-jar.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/cli/signed-modular-jar.sh.i
index 7cec966..b70c20e 100644
Binary files a/jdk/.hg/store/data/test/org/openjdk/jigsaw/cli/signed-modular-jar.sh.i and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/cli/signed-modular-jar.sh.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-jar.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-jar.sh.i
index 11aba1f..621ccf8 100644
Binary files a/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-jar.sh.i and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-jar.sh.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-optional.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-optional.sh.i
new file mode 100644
index 0000000..5f23c29
Binary files /dev/null and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-optional.sh.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-base.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-base.sh.i
new file mode 100644
index 0000000..4069600
Binary files /dev/null and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-base.sh.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-deps.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-deps.sh.i
index 40ad515..0c3c89e 100644
Binary files a/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-deps.sh.i and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-deps.sh.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-jaxp.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-jaxp.sh.i
new file mode 100644
index 0000000..f6f4229
Binary files /dev/null and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-jaxp.sh.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-reexport.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-reexport.sh.i
new file mode 100644
index 0000000..89c5ec0
Binary files /dev/null and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/optional-reexport.sh.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/properties.xml.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/properties.xml.i
new file mode 100644
index 0000000..8dbdcf4
Binary files /dev/null and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/properties.xml.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/tester.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/tester.sh.i
index 39a8e07..1447c9a 100644
Binary files a/jdk/.hg/store/data/test/org/openjdk/jigsaw/tester.sh.i and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/tester.sh.i differ
diff --git a/jdk/.hg/store/fncache b/jdk/.hg/store/fncache
index 9af905d..194c303 100644
--- a/jdk/.hg/store/fncache
+++ b/jdk/.hg/store/fncache
@@ -20783,3 +20783,14 @@ data/test/java/text/Bidi/Bug7051769.java.i
data/test/javax/swing/GroupLayout/7071166/bug7071166.java.i
data/test/sun/security/krb5/auto/PrincipalNameEquals.java.i
data/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsProxyStackOverflow.java.i
+data/make/tools/classanalyzer/classanalyzer.html.i
+data/make/tools/classanalyzer/src/com/sun/classanalyzer/JigsawModuleBuilder.java.i
+data/make/tools/classanalyzer/src/com/sun/classanalyzer/PackageInfo.java.i
+data/src/share/classes/java/lang/module/ModuleNotPresentException.java.i
+data/src/share/classes/java/lang/module/RequireOptionalModule.java.i
+data/src/share/classes/sun/tools/jar/ModuleInfo.java.i
+data/test/org/openjdk/jigsaw/hello-optional.sh.i
+data/test/org/openjdk/jigsaw/optional-base.sh.i
+data/test/org/openjdk/jigsaw/optional-jaxp.sh.i
+data/test/org/openjdk/jigsaw/optional-reexport.sh.i
+data/test/org/openjdk/jigsaw/properties.xml.i
diff --git a/jdk/.hg/store/undo b/jdk/.hg/store/undo
index d3e3205..ca1cd96 100644
Binary files a/jdk/.hg/store/undo and b/jdk/.hg/store/undo differ
diff --git a/jdk/.hg/undo.desc b/jdk/.hg/undo.desc
index dc7660b..aa0595c 100644
--- a/jdk/.hg/undo.desc
+++ b/jdk/.hg/undo.desc
@@ -1,3 +1,3 @@
-4629
+4702
pull
http://hg.openjdk.java.net/jigsaw/jigsaw/jdk
diff --git a/jdk/.hg/undo.dirstate b/jdk/.hg/undo.dirstate
index ea2c614..76ee247 100644
Binary files a/jdk/.hg/undo.dirstate and b/jdk/.hg/undo.dirstate differ
diff --git a/jdk/make/common/Defs-modules.gmk b/jdk/make/common/Defs-modules.gmk
index 2eb031c..ee13f56 100644
--- a/jdk/make/common/Defs-modules.gmk
+++ b/jdk/make/common/Defs-modules.gmk
@@ -67,9 +67,9 @@ endif
# Modules for imports
CORBA_MODULE = sun.corba
JTA_MODULE = sun.jta
-XML_MODULE = sun.jaxp
-XERCES_MODULE = sun.jaxp
-XALAN_MODULE = sun.jaxp
+XML_MODULE = jdk.jaxp
+XERCES_MODULE = jdk.jaxp
+XALAN_MODULE = jdk.jaxp
JAXWS_MODULE = jdk.jaxws
JX_ANNOTATION_MODULE = jdk.jx.annotations
IDLJ_MODULE = jdk.tools
diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk
index bc5c82a..02cd286 100644
--- a/jdk/make/java/java/FILES_java.gmk
+++ b/jdk/make/java/java/FILES_java.gmk
@@ -505,6 +505,8 @@ JAVA_JAVA_jigsaw = \
java/lang/module/ModuleInfoAnnotation.java \
java/lang/module/ModuleInfoReader.java \
java/lang/module/ModuleSystem.java \
+ java/lang/module/ModuleNotPresentException.java \
+ java/lang/module/RequireOptionalModule.java \
java/lang/module/Version.java \
java/lang/module/VersionQuery.java \
java/lang/module/UnsupportedElementTypeException.java \
diff --git a/jdk/make/modules/Makefile b/jdk/make/modules/Makefile
index f285470..6f3f5d3 100644
--- a/jdk/make/modules/Makefile
+++ b/jdk/make/modules/Makefile
@@ -97,8 +97,11 @@ OPTIONAL_DEP_CONFIG = optional.depconfig
#
ORB_IDL=$(MODULEPATH_DIR)/$(IDLJ_MODULE)/lib/orb.idl
IR_IDL=$(MODULEPATH_DIR)/$(IDLJ_MODULE)/lib/ir.idl
+
+
all: $(MODULES_LIST) module-info-classes $(ORB_IDL) $(IR_IDL) modularize
+
# clean modules build
define clean-build
$(RM) -rf $(JIGSAW_MODULE_LIB)
@@ -125,6 +128,7 @@ $(MODULES_LIST):: $(MODULES_UPDATE_MARKER)
$(HOST_JAVA_CMD) \
-jar $(CLASSANALYZER_JAR_FILE) \
-jdkhome $(OUTPUTDIR) \
+ -platform \
-config $(MODULES_CONFIG) \
-config $(MODULES_GROUP) \
-depconfig $(DEP_CONFIG) \
@@ -133,8 +137,7 @@ $(MODULES_LIST):: $(MODULES_UPDATE_MARKER)
-version $(MODULE_VERSION) \
-update \
-output $(MODULE_CLASSLIST_DIR) \
- -moduleinfo $(MODULEINFO_SRC) \
- -noncorepkgs $(BUILDDIR)/docs/NON_CORE_PKGS.gmk
+ -moduleinfo $(MODULEINFO_SRC)
@$(java-vm-cleanup)
@$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..."
@@ -155,13 +158,12 @@ JAVAC_CMD = $(HOST_JAVAC_CMD) \
-Xbootclasspath:$(BOOTCLASSPATH) \
-modulepath $(MODULEPATH_DIR) \
-sourcepath $(MODULEINFO_SRC)
-FILES_java := $(shell $(CD) $(MODULEINFO_SRC) && \
- $(FIND) . -name '*.java' -print)
+FILES_java := $(shell $(NAWK) '{print $$1 "/module-info.java"}' ${MODULES_LIST})
CLASSDESTDIR = $(MODULEPATH_DIR)
include $(BUILDDIR)/common/Classes.gmk
-# Compile module-info.java
+# Compile module-info.java
# javac depends on the jigsaw module library to exist
module-info-classes:
if [ ! -d $(JIGSAW_MODULE_LIB) ] ; then \
@@ -263,7 +265,7 @@ $(JIGSAW_MODULE_LIB)/%/$(MODULE_VERSION)/info: $(MODULEPATH_DIR)/%/classes/modul
$(MODULEPATH_DIR)/$(IDLJ_MODULE)/lib/%.idl : $(LIBDIR)/%.idl
$(install-non-module-file)
-clean clobber::
+clean clobber:: classes.clean
$(clean-build)
diff --git a/jdk/make/modules/modules.config b/jdk/make/modules/modules.config
index b2e4ca2..1c552a9 100644
--- a/jdk/make/modules/modules.config
+++ b/jdk/make/modules/modules.config
@@ -106,9 +106,10 @@ module base {
include java.io.*;
- include java.nio.**, com.sun.nio.**;
+ include java.nio.**, com.sun.nio.file.*;
include sun.nio.fs.*, sun.nio.ch.*, sun.nio.ByteBuffered;
- exclude com.sun.nio.sctp.*, sun.nio.ch.Sctp*;
+ exclude sun.nio.ch.Sctp*;
+ exclude META-INF/services/java.nio.file.spi.FileSystemProvider;
// security APIs
// javax.crypto and javax.security.auth are included to avoid inconsistent
@@ -516,7 +517,7 @@ module security-kerberos {
module security-sasl-ntlm {
include com.sun.security.ntlm.**;
- include com.sun.security.sasl.ntml.**;
+ include com.sun.security.sasl.ntlm.**;
// NTLM authentication support
include sun.net.www.protocol.http.ntlm.*;
@@ -659,6 +660,11 @@ module sctp {
include com.sun.nio.sctp.**, sun.nio.ch.Sctp*;
}
+module zipfs {
+ include com.sun.nio.zipfs.*;
+ include META-INF/services/java.nio.file.spi.FileSystemProvider;
+}
+
// networking extension
module net-ext {
include sctp;
@@ -681,6 +687,9 @@ module jaxp-api {
org.w3c.sax.**,
org.xml.sax.**;
+ // Not part of JAXP API; bundled with xalan
+ exclude org.w3c.dom.xpath.*;
+
exclude javax.xml.crypto.**, // XML-DSIG
javax.xml.bind.**, // JAX-WS
javax.xml.soap.**,
@@ -704,6 +713,8 @@ module jaxp-xerces-resolver {
}
module jaxp-xalan {
+ include org.w3c.dom.xpath.*;
+
include com.sun.org.apache.xalan.internal.**,
com.sun.org.apache.xpath.internal.**,
com.sun.org.apache.xml.internal.dtm.**,
diff --git a/jdk/make/modules/modules.group b/jdk/make/modules/modules.group
index 3888791..af4ec5f 100644
--- a/jdk/make/modules/modules.group
+++ b/jdk/make/modules/modules.group
@@ -65,14 +65,14 @@ module jdk.base {
include US_export_policy;
include local_policy;
- include instrument;
-
requires public local jdk.boot;
// explicit optional dependences
- requires optional local sun.resources;
- requires optional local sun.localedata;
- requires optional local sun.charsets;
+ requires optional jdk.jaxp;
+ requires optional jdk.desktop;
+ requires optional sun.resources;
+ requires optional sun.localedata;
+ requires optional sun.charsets;
class org.openjdk.jigsaw.Hi; // testing
}
@@ -82,6 +82,11 @@ module jdk.advanced {
include j4b;
}
+module jdk.instrument {
+ requires local jdk.boot;
+ include instrument;
+}
+
/*
* Names of jdk platform modules must start with "jdk." or "sun."
* ("sun." prefix is added as a temporary solution for now until
@@ -114,6 +119,21 @@ module sun.desktop {
include sun.callback.dialog;
}
+module jdk.desktop {
+ // ## To be revisited:
+ // There are packages splitted between sun.desktop, jdk.boot, and
+ // other modules. sun.desktop only permits certain modules to
+ // require due to the split packages.
+ //
+ // As jdk.base requires optionally jdk.desktop and jdk.base is
+ // in the same context with sun.desktop, jdk.desktop must be in
+ // the same context with sun.desktop; otherwise, packages be defined in
+ // the boot context and exported by jdk.jaxp context.
+
+ requires public local sun.desktop;
+ requires optional jdk.jaxp;
+}
+
module sun.management {
requires local jdk.boot; // ensure loaded by bootstrap class loader
include management;
@@ -200,23 +220,29 @@ module jdk.smartcardio {
}
module sun.xml {
- requires local jdk.boot; // ensure loaded by bootstrap class loader
include jaxp-api;
}
module sun.xalan {
- requires local jdk.boot; // ensure loaded by bootstrap class loader
include jaxp-xalan;
}
module sun.xerces {
- requires local jdk.boot; // ensure loaded by bootstrap class loader
include jaxp-xerces-impl;
include jaxp-xerces-resolver;
}
-module sun.jaxp {
- requires local jdk.boot; // ensure loaded by bootstrap class loader
+module jdk.jaxp {
+ // ## VM has an optimization to load classes directly
+ // ## from the null class loader; java.util.Properties fails
+ // ## to load classes from this module if not local
+ //
+ // In other words, jdk.jaxp would require public local sun.jaxp.
+ // Otherwise, javax.xml and other packages would be defined in
+ // the boot context and exported by jdk.jaxp context.
+ //
+ requires local jdk.boot;
+
include sun.xml;
include sun.xalan;
include sun.xerces;
@@ -320,6 +346,7 @@ module jdk.ext {
requires local jdk.boot; // loaded by bootstrap class loader
include httpserver;
include net-ext;
+ include zipfs;
}
// ## langtools maintains the list of modules and names
diff --git a/jdk/make/modules/modules.properties b/jdk/make/modules/modules.properties
index ff56b2c..a68a008 100644
--- a/jdk/make/modules/modules.properties
+++ b/jdk/make/modules/modules.properties
@@ -40,9 +40,9 @@ platform.jre.tools.module = jdk.tools.jre
#
# supported properties of a module
-# <module-name>.allow.empty
-# <module-name>.alias
-# <module-name>.modules.list - print an ordered list of its required modules
+# <module-name>.allow.empty: include the module even if it's empty (default = false)
+# <module-name>.modules.list: print an ordered list of its required modules (default = false)
+# <module-name>.exports.all: exports all local APIs or not (default = true)
#
jdwp.allow.empty = true
@@ -51,3 +51,269 @@ jdk.modules.list = true
jdk.jre.modules.list = true
jdk.base.modules.list = true
jdk.tools.base.modules.list = true
+
+# List of external exported packages
+# Copied from jdk/make/docs/CORE_PKGS.gmk
+#
+# sun.reflect.annotation is exported as an interim solution
+# it's required by javac for serializaton of annotation these
+# types are essentially de facto platform classes
+#
+exported.packages = \
+ java.applet \
+ java.awt \
+ java.awt.color \
+ java.awt.datatransfer \
+ java.awt.dnd \
+ java.awt.event \
+ java.awt.font \
+ java.awt.geom \
+ java.awt.im \
+ java.awt.im.spi \
+ java.awt.image \
+ java.awt.image.renderable \
+ java.awt.print \
+ java.beans \
+ java.beans.beancontext \
+ java.io \
+ java.lang \
+ java.lang.annotation \
+ java.lang.instrument \
+ java.lang.invoke \
+ java.lang.management \
+ java.lang.module \
+ java.lang.ref \
+ java.lang.reflect \
+ java.math \
+ java.net \
+ java.nio \
+ java.nio.channels \
+ java.nio.channels.spi \
+ java.nio.charset \
+ java.nio.charset.spi \
+ java.nio.file \
+ java.nio.file.attribute \
+ java.nio.file.spi \
+ java.rmi \
+ java.rmi.activation \
+ java.rmi.dgc \
+ java.rmi.registry \
+ java.rmi.server \
+ java.security \
+ java.security.acl \
+ java.security.cert \
+ java.security.interfaces \
+ java.security.spec \
+ java.sql \
+ java.sql \
+ java.text \
+ java.text.spi \
+ java.util \
+ java.util.concurrent \
+ java.util.concurrent.atomic \
+ java.util.concurrent.locks \
+ java.util.jar \
+ java.util.logging \
+ java.util.prefs \
+ java.util.regex \
+ java.util.spi \
+ java.util.zip \
+ javax.accessibility \
+ javax.activation \
+ javax.activation \
+ javax.activity \
+ javax.annotation \
+ javax.annotation.processing \
+ javax.crypto \
+ javax.crypto.interfaces \
+ javax.crypto.spec \
+ javax.imageio \
+ javax.imageio.event \
+ javax.imageio.metadata \
+ javax.imageio.plugins.bmp \
+ javax.imageio.plugins.jpeg \
+ javax.imageio.spi \
+ javax.imageio.stream \
+ javax.jws \
+ javax.jws.soap \
+ javax.lang.model \
+ javax.lang.model.element \
+ javax.lang.model.type \
+ javax.lang.model.util \
+ javax.management \
+ javax.management.loading \
+ javax.management.modelmbean \
+ javax.management.monitor \
+ javax.management.openmbean \
+ javax.management.relation \
+ javax.management.remote \
+ javax.management.remote.rmi \
+ javax.management.timer \
+ javax.naming \
+ javax.naming.directory \
+ javax.naming.event \
+ javax.naming.ldap \
+ javax.naming.spi \
+ javax.net \
+ javax.net.ssl \
+ javax.print \
+ javax.print.attribute \
+ javax.print.attribute.standard \
+ javax.print.event \
+ javax.rmi \
+ javax.rmi.CORBA \
+ javax.rmi.ssl \
+ javax.script \
+ javax.script \
+ javax.security.auth \
+ javax.security.auth.callback \
+ javax.security.auth.kerberos \
+ javax.security.auth.login \
+ javax.security.auth.spi \
+ javax.security.auth.x500 \
+ javax.security.cert \
+ javax.security.sasl \
+ javax.sound.midi \
+ javax.sound.midi.spi \
+ javax.sound.sampled \
+ javax.sound.sampled.spi \
+ javax.sql \
+ javax.sql.rowset \
+ javax.sql.rowset.serial \
+ javax.sql.rowset.spi \
+ javax.swing \
+ javax.swing.border \
+ javax.swing.colorchooser \
+ javax.swing.event \
+ javax.swing.filechooser \
+ javax.swing.plaf \
+ javax.swing.plaf.basic \
+ javax.swing.plaf.metal \
+ javax.swing.plaf.multi \
+ javax.swing.plaf.nimbus \
+ javax.swing.plaf.synth \
+ javax.swing.table \
+ javax.swing.text \
+ javax.swing.text.html \
+ javax.swing.text.html.parser \
+ javax.swing.text.rtf \
+ javax.swing.tree \
+ javax.swing.undo \
+ javax.tools \
+ javax.tools \
+ javax.transaction \
+ javax.transaction.xa \
+ javax.xml \
+ javax.xml.bind \
+ javax.xml.bind.annotation \
+ javax.xml.bind.annotation.adapters \
+ javax.xml.bind.attachment \
+ javax.xml.bind.helpers \
+ javax.xml.bind.util \
+ javax.xml.crypto \
+ javax.xml.crypto.dom \
+ javax.xml.crypto.dsig \
+ javax.xml.crypto.dsig.dom \
+ javax.xml.crypto.dsig.keyinfo \
+ javax.xml.crypto.dsig.spec \
+ javax.xml.datatype \
+ javax.xml.namespace \
+ javax.xml.parsers \
+ javax.xml.soap \
+ javax.xml.stream \
+ javax.xml.stream.events \
+ javax.xml.stream.util \
+ javax.xml.transform \
+ javax.xml.transform.dom \
+ javax.xml.transform.sax \
+ javax.xml.transform.stax \
+ javax.xml.transform.stream \
+ javax.xml.validation \
+ javax.xml.ws \
+ javax.xml.ws.handler \
+ javax.xml.ws.handler.soap \
+ javax.xml.ws.http \
+ javax.xml.ws.soap \
+ javax.xml.ws.spi \
+ javax.xml.ws.spi.http \
+ javax.xml.ws.wsaddressing \
+ javax.xml.xpath \
+ org.ietf.jgss \
+ org.omg.CORBA \
+ org.omg.CORBA.DynAnyPackage \
+ org.omg.CORBA.ORBPackage \
+ org.omg.CORBA.TypeCodePackage \
+ org.omg.CORBA.portable \
+ org.omg.CORBA_2_3 \
+ org.omg.CORBA_2_3.portable \
+ org.omg.CosNaming \
+ org.omg.CosNaming.NamingContextExtPackage \
+ org.omg.CosNaming.NamingContextPackage \
+ org.omg.Dynamic \
+ org.omg.DynamicAny \
+ org.omg.DynamicAny.DynAnyFactoryPackage \
+ org.omg.DynamicAny.DynAnyPackage \
+ org.omg.IOP \
+ org.omg.IOP.CodecFactoryPackage \
+ org.omg.IOP.CodecPackage \
+ org.omg.Messaging \
+ org.omg.PortableInterceptor \
+ org.omg.PortableInterceptor.ORBInitInfoPackage \
+ org.omg.PortableServer \
+ org.omg.PortableServer.CurrentPackage \
+ org.omg.PortableServer.POAManagerPackage \
+ org.omg.PortableServer.POAPackage \
+ org.omg.PortableServer.ServantLocatorPackage \
+ org.omg.PortableServer.portable \
+ org.omg.SendingContext \
+ org.omg.stub.java.rmi \
+ org.w3c \
+ org.w3c.dom \
+ org.w3c.dom.bootstrap \
+ org.w3c.dom.events \
+ org.w3c.dom.ls \
+ org.xml.sax \
+ org.xml.sax \
+ org.xml.sax.ext \
+ org.xml.sax.helpers \
+ com.sun.java.browser.dom \
+ com.sun.javadoc \
+ com.sun.jdi \
+ com.sun.jdi.connect \
+ com.sun.jdi.connect.spi \
+ com.sun.jdi.event \
+ com.sun.jdi.request \
+ com.sun.management \
+ com.sun.mirror.apt \
+ com.sun.mirror.declaration \
+ com.sun.mirror.type \
+ com.sun.mirror.util \
+ com.sun.net.httpserver \
+ com.sun.net.httpserver.spi \
+ com.sun.net.ssl \
+ com.sun.nio.file \
+ com.sun.nio.sctp \
+ com.sun.security.auth \
+ com.sun.security.auth.callback \
+ com.sun.security.auth.login \
+ com.sun.security.auth.module \
+ com.sun.security.jgss \
+ com.sun.source.tree \
+ com.sun.source.util \
+ com.sun.tools.attach \
+ com.sun.tools.attach.spi \
+ com.sun.tools.jconsole \
+ javax.smartcardio \
+ org.w3c.dom \
+ org.w3c.dom.bootstrap \
+ org.w3c.dom.css \
+ org.w3c.dom.events \
+ org.w3c.dom.html \
+ org.w3c.dom.ls \
+ org.w3c.dom.ranges \
+ org.w3c.dom.stylesheets \
+ org.w3c.dom.traversal \
+ org.w3c.dom.views \
+ org.openjdk.jigsaw \
+ sun.reflect.annotation
+
diff --git a/jdk/make/tools/classanalyzer/classanalyzer.html b/jdk/make/tools/classanalyzer/classanalyzer.html
new file mode 100644
index 0000000..6e0dd64
--- /dev/null
+++ b/jdk/make/tools/classanalyzer/classanalyzer.html
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/xhtml1-strict.dtd">
+<!--
+ Copyright (c) 2011, 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. Oracle designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Oracle in the LICENSE file that accompanied this code.
+
+ 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.
+-->
+
+<html>
+<head>
+ <title>ClassAnalyzer</title>
+</head>
+<body>
+
+<h1>ClassAnalyzer</h1>
+The ClassAnalyzer tool analyzes the class dependencies among
+the input class files. It parses the class files, finds
+all class references, assigns classes to modules per the
+specified configuration files and then generates a set
+of reports for each module, including the list of classes,
+the list of resource files, and its dependencies on
+classes from another module.
+
+<p>
+<em>Input:</em>
+<ol>
+ <li>Class files to be analyzed</li>
+ <li>Input configuration file to include/exclude classes in modules</li>
+</ol>
+
+<em>Output:</em>
+<ol>
+ <li>ClassAnalyzer generated reports:
+ <code>*.classlist, *.resources, *.dependencies</code></li>
+ <li>module-info.java for modules</li>
+</ol>
+
+The ClassAnalyzer can only find <i>static</i> dependencies
+from the bytecode but not <i>implicit</i> dependencies which include
+classes loaded by <code>Class.forName</code>, service providers,
+constants inlined by the compiler, and <code>JNI_FindClass</code>.
+In addition, it does not parse the annotations.
+
+<h3>ClassAnalyzer's Configuration File</h3>
+
+Example:
+<pre>
+module swingset3 {
+ // include classes in this module
+ include com.sun.swingset3.**;
+
+ // include resource files in this module
+ include META-INF/demolist;
+
+ // main entry point
+ class com.sun.swingset3.SwingSet3;
+}
+</pre>
+
+
+The syntax is similar to <code>module-info.java</code>.
+Directives are:
+<ul>
+ <li><code>include</code>: classes or resources to be included in this module.
+ It can also include a module.</li>
+ <li><code>exclude</code>: classes or resources to be excluded in this module.</li>
+ <li><code>root</code>: classes and all of its referenced classes (transitive closure)
+ to be included in this module.</li>
+ <li><code>class</code>: main entry point for this module</li>
+ <li><code>require [optional]</code>: explicitly require a module</li>
+</ul>
+
+<h3>JDK Modularization</h3>
+
+The ClassAnalyzer tool is used in the jigsaw modules build to
+analyze the class dependencies amongst the JDK classes and
+generate the <code>module-info.java</code> files for JDK modules
+as a post-processing step. This is an interim solution
+enabling us prototype a modular JDK and make change to
+the module definitions during the course of our development,
+for example, synchronizing the on-going JDK development
+with the jdk8 repository.
+Utimately, we will restructure the source tree so that
+JDK modules will be compiled in the modulepath
+that can be used for development and the image build.
+Source tree restructuring has a big impact on all JDK engineers
+and thus we should do this when the module definitions and
+graph are close to final to minimize the disruption to the teams.
+
+<p>
+The configuration file for JDK is at:
+<a href="../../make/modules/modules.config"> <code>modules.config</code></a> and
+<a href="../../make/modules/modules.group"> <code>modules.group</code></a>.
+
+<h3>Help</h3>
+<pre>
+Usage: ClassAnalyzer <options>
+Options:
+ -classpath classpath where classes and jars will be parsed
+ -config config file
+ This option can be repeated to specify multiple config files.
+ -jigsawLibrary module-library-path
+ Default is the system module library if present.
+ -moduleinfo output dir for module-info.java.
+ If not specified, no module-info.java will be generated.
+ -output output dir for the generated reports
+ -properties module's properties
+ -version version of the modules
+</pre>
+</body>
+</html>
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/AnnotationParser.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/AnnotationParser.java
index 0d6a76a..2bde5d4 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/AnnotationParser.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/AnnotationParser.java
@@ -59,7 +59,9 @@ public class AnnotationParser {
private AnnotatedDependency addAnnotation(Annotation annot, Klass.Method method) {
String type = getType(annot.type_index);
- AnnotatedDependency dep = AnnotatedDependency.newAnnotatedDependency(type, cfparser.this_klass);
+ AnnotatedDependency dep =
+ AnnotatedDependency.newAnnotatedDependency(type, cfparser.this_klass);
+
if (dep != null) {
for (int i = 0; i < annot.num_element_value_pairs; i++) {
Element element = getElement(annot.element_value_pairs[i]);
@@ -181,8 +183,12 @@ public class AnnotationParser {
}
}
- void parseAttributes(Attributes attributes) {
- parseAttributes(attributes, null);
+ void parseAttributes(Field f) {
+ parseAttributes(f.attributes, null);
+ }
+
+ void parseAttributes(ClassFile cf) throws ConstantPoolException {
+ parseAttributes(cf.attributes, null);
}
public static void main(String[] args) throws Exception {
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/BootAnalyzer.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/BootAnalyzer.java
index e68c820..7a8fed1 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/BootAnalyzer.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/BootAnalyzer.java
@@ -44,7 +44,6 @@ import com.sun.tools.classfile.ConstantPool.*;
import static com.sun.tools.classfile.ConstantPool.*;
import com.sun.tools.classfile.Instruction.TypeKind;
import com.sun.tools.classfile.Type.*;
-import com.sun.classanalyzer.ModuleInfo.PackageInfo;
import static com.sun.classanalyzer.Trace.*;
/**
@@ -150,9 +149,9 @@ public class BootAnalyzer {
ModuleBuilder builder =
new ModuleBuilder(Collections.singletonList(bootconfig), version);
- assert Module.getAllModules().size() == 1;
+ assert builder.getModules().size() == 1;
Module module = null;
- for (Module m : Module.getAllModules()) {
+ for (Module m : builder.getModules()) {
module = m;
break;
}
@@ -176,13 +175,11 @@ public class BootAnalyzer {
long total = 0L;
int count = 0;
summary.format("%10s\t%10s\t%s%n", "Bytes", "Classes", "Package name");
- for (PackageInfo info : m.getModuleInfo().packages()) {
- if (info.count > 0) {
- summary.format("%10d\t%10d\t%s%n",
- info.filesize, info.count, info.pkgName);
- total += info.filesize;
- count += info.count;
- }
+ for (PackageInfo info : m.packages()) {
+ summary.format("%10d\t%10d\t%s%n",
+ info.classBytes, info.classCount, info.pkgName);
+ total += info.classBytes;
+ count += info.classCount;
}
summary.format("%nTotal: %d bytes (uncompressed) %d classes%n",
total, count);
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassAnalyzer.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassAnalyzer.java
index 26640bf..b2645b9 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassAnalyzer.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassAnalyzer.java
@@ -65,8 +65,9 @@ public class ClassAnalyzer {
String version = null;
String classlistDir = ".";
String minfoDir = null;
- String nonCorePkgsFile = null;
+ String jigsawLibrary = null;
ClassPath cpath = null;
+ boolean usePlatformModuleBuilder = false;
boolean mergeModules = true;
boolean apiOnly = false;
boolean showDynamic = false;
@@ -102,16 +103,19 @@ public class ClassAnalyzer {
minfoDir = getOption(args, i++);
} else if (arg.equals("-version")) {
version = getOption(args, i++);
- } else if (arg.equals("-nomerge")) {
- // analyze the fine-grained module dependencies
- mergeModules = false;
+ } else if (arg.equals("-platform")) {
+ // a special case for generating JDK modules
+ usePlatformModuleBuilder = true;
+ } else if (arg.equals("-jigsawLibrary")) {
+ jigsawLibrary = getOption(args, i++);
} else if (arg.equals("-api")) {
// analyze the fine-grained module dependencies
apiOnly = true;
+ } else if (arg.equals("-nomerge")) {
+ // analyze the fine-grained module dependencies
+ mergeModules = false;
} else if (arg.equals("-showdynamic")) {
showDynamic = true;
- } else if (arg.equals("-noncorepkgs")) {
- nonCorePkgsFile = getOption(args, i++);
} else {
error("Invalid option: " + arg);
}
@@ -130,49 +134,69 @@ public class ClassAnalyzer {
}
ModuleBuilder builder;
- if (jdkhome != null) {
- PlatformModuleBuilder pmb =
+ if (usePlatformModuleBuilder) {
+ builder =
new PlatformModuleBuilder(configs, depconfigs, mergeModules, version);
- if (nonCorePkgsFile != null) {
- pmb.readNonCorePackagesFrom(nonCorePkgsFile);
- }
- builder = pmb;
} else {
builder = new ModuleBuilder(configs, depconfigs, mergeModules, version);
}
+ File systemLib;
+ if (jigsawLibrary != null) {
+ systemLib = new File(jigsawLibrary);
+ } else {
+ systemLib = new File(new File(System.getProperty("java.home"),
+ "lib"),
+ "modules");
+ }
+ if (systemLib.exists() && jdkhome == null) {
+ // if running on a modular JDK, first load the jigsaw modules
+ // The jigsaw modules are not added to the ModuleBuilder
+ // as they are only used in the module dependency graph.
+ JigsawModuleBuilder jb = new JigsawModuleBuilder(systemLib);
+ builder.addModules(jb.run());
+ }
+
+ // incremental build
+ boolean incremental = update && doIncremental(classlistDir);
+ if (incremental) {
+ // Load modules from the existing class list and resource list
+ // Add them in the builder to be included in the analysis
+ ClassListReader reader = new ClassListReader(builder.getFactory(), classlistDir, version);
+ reader.run();
+ }
+
ClassAnalyzer analyzer = new ClassAnalyzer(cpath, builder, classlistDir);
// parse class and resource files
- analyzer.run(update, apiOnly);
-
- // print reports and module-info.java
- analyzer.generateReports(classlistDir, showDynamic);
+ analyzer.run(incremental, apiOnly);
+ // print classlist and dependencies reports
+ analyzer.generateReports(showDynamic);
+ // print module-info.java
if (minfoDir != null) {
analyzer.printModuleInfos(minfoDir);
}
}
+
+ static boolean doIncremental(String classlistDir) {
+ File moduleList = new File(classlistDir, "modules.list");
+ return (moduleList.exists() && moduleList.lastModified() > 0);
+ }
+
private final ClassPath cpath;
private final ModuleBuilder builder;
- private final File classlistDir;
+ private final String classlistDir;
private final File moduleList;
private final Set<Module> updatedModules; // updated modules
ClassAnalyzer(ClassPath cpath, ModuleBuilder builder, String clistDir) {
this.cpath = cpath;
this.builder = builder;
- this.classlistDir = new File(clistDir);
- this.moduleList = new File(clistDir, "modules.list");
+ this.classlistDir = clistDir;
+ this.moduleList = new File(new File(clistDir), "modules.list");
this.updatedModules = new TreeSet<Module>();
}
void run(boolean update, boolean apiOnly) throws IOException {
- if (update) {
- // incremental
- if (!moduleList.exists()) {
- // fall back to the default - analyze the entire jdk
- update = false;
- }
- }
// parse class and resource files
processClassPath(update, apiOnly);
@@ -184,11 +208,16 @@ public class ClassAnalyzer {
} else {
updatedModules.addAll(builder.getModules());
}
+
+ Module unknown = builder.getFactory().nullModule;
+ if (builder.getModules().contains(unknown))
+ System.out.println("WARNING: classes are not assigned to any module."
+ + " Please see the unknown.classlist report.");
}
- public void generateReports(String output, boolean showDynamic)
+ public void generateReports(boolean showDynamic)
throws IOException {
- File outputDir = new File(output);
+ File outputDir = new File(classlistDir);
if (!outputDir.exists())
Files.mkdirs(outputDir);
@@ -237,9 +266,6 @@ public class ClassAnalyzer {
return lastModified <= 0 || lastModified > ts;
}
};
-
- // load modules from the existing class list and resource list
- builder.loadModulesFrom(classlistDir);
}
// parse class and resource files
@@ -279,20 +305,25 @@ public class ClassAnalyzer {
PrintWriter summary =
new PrintWriter(Files.resolve(dir, m.name(), "summary"));
try {
- ModuleInfo mi = m.getModuleInfo();
- long total = 0L;
+ long total = 0;
int count = 0;
+ long resBytes = 0;
+ int resCount = 0;
summary.format("%10s\t%10s\t%s%n", "Bytes", "Classes", "Package name");
- for (PackageInfo info : mi.packages()) {
- if (info.count > 0) {
- summary.format("%10d\t%10d\t%s%n",
- info.filesize, info.count, info.pkgName);
- total += info.filesize;
- count += info.count;
- }
+ for (PackageInfo info : m.packages()) {
+ summary.format("%10d\t%10d\t%s%n",
+ info.classBytes, info.classCount, info.pkgName);
+ total += info.classBytes;
+ count += info.classCount;
+ }
+ for (ResourceFile rf : m.resources()) {
+ resCount++;
+ resBytes += rf.getFileSize();
}
- summary.format("%nTotal: %d bytes (uncompressed) %d classes%n",
- total, count);
+
+ summary.format("%nTotal: %d bytes (uncompressed) %d classes " +
+ "%d bytes %d resources %n",
+ total, count, resBytes, resCount);
} finally {
summary.close();
}
@@ -390,7 +421,7 @@ public class ClassAnalyzer {
private void printModulesDot(File dir, boolean showDynamic) throws IOException {
PrintWriter writer = new PrintWriter(new File(dir, "modules.dot"));
try {
- writer.println("digraph jdk {");
+ writer.println("digraph modules {");
for (Module m : builder.getModules()) {
ModuleInfo mi = m.getModuleInfo();
for (Dependence dep : mi.requires()) {
@@ -477,12 +508,12 @@ public class ClassAnalyzer {
sb.append("\t-config <module config file>\n");
sb.append("\t This option can be repeated for multiple module config files\n");
sb.append("\t-output <output dir>\n");
- sb.append("\t-update update modules with newer files\n");
sb.append("\t-moduleinfo <output dir of module-info.java>\n");
+ sb.append("\t-jigsawLibrary <module-library-path>\n");
+ sb.append("\t-platform platform modules\n");
sb.append("\t-properties module's properties\n");
- sb.append("\t-noncorepkgs NON_CORE_PKGS.gmk\n");
sb.append("\t-version <module's version>\n");
- sb.append("\t-showdynamic show dynamic dependencies in the reports\n");
+ sb.append("\t-update update modules with newer files\n");
sb.append("\t-nomerge specify not to merge modules\n");
return sb.toString();
}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassFileParser.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassFileParser.java
index 394f5f3..11f4db5 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassFileParser.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassFileParser.java
@@ -145,7 +145,7 @@ public class ClassFileParser {
}
}
// parse attributes
- annotationParser.parseAttributes(classfile.attributes);
+ annotationParser.parseAttributes(classfile);
} catch (ConstantPoolException ex) {
throw new RuntimeException(ex);
}
@@ -172,7 +172,7 @@ public class ClassFileParser {
addFieldTypes(getKlass(t), info, flags);
}
// parse attributes
- annotationParser.parseAttributes(f.attributes);
+ annotationParser.parseAttributes(f);
} catch (ConstantPoolException ex) {
throw new RuntimeException(ex);
} catch (InvalidDescriptor ex) {
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassListReader.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassListReader.java
index 74ea3b2..e78ff6f 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassListReader.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassListReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2011, 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
@@ -23,6 +23,7 @@
*/
package com.sun.classanalyzer;
+import com.sun.classanalyzer.Module.Factory;
import java.io.*;
import java.util.*;
@@ -30,32 +31,47 @@ import java.util.*;
* ClassListReader constructs modules from the .classlist and
* .resources files
*
- * @author Mandy Chung
- *
* @see ClassListWriter
*/
public class ClassListReader {
- private final ModuleBuilder builder;
- ClassListReader() {
- ModuleBuilder mb = null;
- try {
- mb = new ModuleBuilder(null, ""); // use default module builder
- } catch (IOException e) {
- // should not reach here
- }
- this.builder = mb;
+ private final Factory factory;
+ private final File cldir;
+ private final String version;
+ public ClassListReader(String dir, String version) {
+ this(Module.getFactory(), new File(dir), version);
+ }
+
+ public ClassListReader(Factory factory, String dir, String version) {
+ this(factory, new File(dir), version);
+ }
+
+ public ClassListReader(Factory factory, File dir, String version) {
+ this.factory = factory;
+ this.cldir = dir;
+ this.version = version;
}
- ClassListReader(ModuleBuilder builder) {
- this.builder = builder;
+
+ public Set<Module> run() throws IOException {
+ String[] summaryFiles = cldir.list(new FilenameFilter() {
+ public boolean accept(File f, String fname) {
+ return fname.endsWith(".summary") && !fname.equals("modules.summary");
+ }
+ });
+
+ for (String fn : summaryFiles) {
+ String name = fn.substring(0, fn.length() - ".summary".length());
+ Module m = loadModuleFrom(cldir, name);
+ }
+ return factory.getAllModules();
}
- Module loadModule(String name, Set<String> classes, Set<String> resources)
+ private Module loadModule(String name, Set<String> classes, Set<String> resources)
throws IOException {
- Module module = Module.findModule(name);
+ Module module = factory.findModule(name);
if (module == null) {
- module = builder.newModule(name);
+ module = factory.newModule(name, version);
+ factory.addModule(module);
}
-
for (String pathname : classes) {
String cn = pathname.substring(0, pathname.length() - ".class".length())
.replace(File.separatorChar, '.');
@@ -72,36 +88,9 @@ public class ClassListReader {
return module;
}
- /**
- * Returns the list of modules constructed from the classlist
- * and resources list in the given directory.
- */
- public Set<Module> loadModulesFrom(File dir) throws IOException {
- String[] summaryFiles = dir.list(new FilenameFilter() {
- public boolean accept(File f, String fname) {
- if (fname.endsWith(".summary")) {
- return true;
- }
- return false;
- }
- });
-
- Set<Module> modules = new LinkedHashSet<Module>();
- for (String fn : summaryFiles) {
- String name = fn.substring(0, fn.length() - ".summary".length());
- Module m = loadModuleFrom(dir, name);
- if (m != null) {
- modules.add(m);
- }
- }
-
- return modules;
- }
-
private Module loadModuleFrom(File dir, String name) throws IOException {
File clist = new File(dir, name + ".classlist");
File rlist = new File(dir, name + ".resources");
- assert clist.exists() || rlist.exists();
Module module = loadModule(name, readFile(clist), readFile(rlist));
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassPath.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassPath.java
index d194eea..06c7a87 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassPath.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ClassPath.java
@@ -301,7 +301,7 @@ public class ClassPath {
@Override
public void visitClass(File f, String cn) throws IOException {
- ClassFileParser cfparser = ClassFileParser.newParser(f, true);
+ ClassFileParser cfparser = ClassFileParser.newParser(f, parseDeps);
classes.add(cfparser.this_klass);
if (parseDeps) {
cfparser.parseDependency(apiOnly);
@@ -310,7 +310,7 @@ public class ClassPath {
@Override
public void visitClass(JarFile jf, JarEntry e) throws IOException {
- ClassFileParser cfparser = ClassFileParser.newParser(jf.getInputStream(e), e.getSize(), true);
+ ClassFileParser cfparser = ClassFileParser.newParser(jf.getInputStream(e), e.getSize(), parseDeps);
classes.add(cfparser.this_klass);
if (parseDeps) {
cfparser.parseDependency(apiOnly);
@@ -321,7 +321,7 @@ public class ClassPath {
public void visitResource(File f, String rn) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
try {
- ResourceFile res = ResourceFile.addResource(rn, in);
+ ResourceFile res = ResourceFile.addResource(rn, in, f.length());
resources.add(res);
} finally {
in.close();
@@ -330,7 +330,7 @@ public class ClassPath {
@Override
public void visitResource(JarFile jf, JarEntry e) throws IOException {
- ResourceFile res = ResourceFile.addResource(e.getName(), jf.getInputStream(e));
+ ResourceFile res = ResourceFile.addResource(e.getName(), jf.getInputStream(e), e.getSize());
resources.add(res);
}
}
@@ -374,7 +374,7 @@ public class ClassPath {
public Void visitDir(final File dir, final ClassPathEntry cp, Void v) throws IOException {
List<File> ls = Files.walkTree(dir, null);
for (File f : ls) {
- visitFile(f, (ClassPathEntry) cp, null);
+ visitFile(f, cp, null);
}
return null;
}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Files.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Files.java
index 90834b8..7c6b84a 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Files.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Files.java
@@ -76,7 +76,7 @@ public class Files {
public boolean accept(T x) throws IOException;
}
- public static List<File> walkTree(File src, Filter filter)
+ public static List<File> walkTree(File src, Filter<File> filter)
throws IOException {
ensureIsDirectory(src);
List<File> result = new ArrayList<File>();
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/JigsawModuleBuilder.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/JigsawModuleBuilder.java
new file mode 100644
index 0000000..3261a13
--- /dev/null
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/JigsawModuleBuilder.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2011, 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 com.sun.classanalyzer;
+
+import com.sun.classanalyzer.Module.Factory;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+import java.lang.module.ModuleId;
+import org.openjdk.jigsaw.*;
+
+/**
+ * Builds modules from a given jigsaw module library.
+ * To run ClassAnalyzer on JDK7 (non-jigsaw JDK),
+ * the JigsawModuleBuilder can also take the jdk's classlists
+ * from the jigsaw build.
+ */
+public class JigsawModuleBuilder extends ClassListReader {
+ private static JigsawFactory factory = new JigsawFactory();
+ private static String DEFAULT_VERSION = "8-ea";
+
+ private final File path;
+ public JigsawModuleBuilder(File path) {
+ super(factory, path, DEFAULT_VERSION);
+ this.path = path;
+ }
+
+ public Set<Module> run() throws IOException {
+ File f = new File(path, "%jigsaw-library");
+ if (f.exists()) {
+ // create modules from the jigsaw system module library
+ loadModulesFromLibrary();
+ } else {
+ // create modules from the input class lists
+ super.run();
+ }
+ return factory.getAllModules();
+ }
+
+ private void loadModulesFromLibrary() throws IOException {
+ Library lib = SimpleLibrary.open(path);
+ List<ModuleId> mids = lib.listLocalModuleIds();
+ for (ModuleId mid : mids) {
+ java.lang.module.ModuleInfo minfo = lib.readLocalModuleInfo(mid);
+ Module m = factory.newModule(mid.name(), mid.version().toString());
+ factory.addModule(m);
+
+ // ## probably list only exported classes??
+ for (String cn : lib.listLocalClasses(mid, true)) {
+ Klass k = Klass.findKlass(cn);
+ if (k != null) {
+ throw new RuntimeException(mid.name() + ":" + cn + " already exists");
+ }
+ k = Klass.getKlass(cn);
+ m.addKlass(k);
+ }
+ }
+ }
+
+
+ private static class JigsawFactory extends Factory {
+
+ @Override
+ public Module newModule(String name, String version) {
+ return new JigsawModule(new ModuleConfig(name, version));
+ }
+
+ @Override
+ public Module newModule(ModuleConfig config) {
+ return new JigsawModule(config);
+ }
+ };
+
+ private static class JigsawModule extends Module {
+ Module altgroup;
+
+ JigsawModule(ModuleConfig config) {
+ super(config);
+ }
+
+ /*
+ * Only present the "jdk." modules for application
+ * to use.
+ */
+ @Override
+ public synchronized Module group() {
+ if (altgroup == null) {
+ altgroup = this;
+ String n = name();
+ if (n.startsWith("sun.")) {
+ String mn = "jdk." + n.substring(4);
+ Module pm = factory.findModule(mn);
+ if (pm != null) {
+ altgroup = pm;
+ }
+ } else if (n.equals("jdk.boot")) {
+ altgroup = factory.findModule("jdk.base");
+ if (altgroup == null) {
+ throw new RuntimeException("jdk.base not found");
+ }
+ }
+ }
+ return altgroup;
+ }
+
+ @Override
+ boolean allowEmpty() {
+ // jdk.* module that reexports sun.* module is empty
+ return true;
+ }
+ }
+}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Modularizer.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Modularizer.java
index f0b3dae..e37ebed 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Modularizer.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Modularizer.java
@@ -459,8 +459,8 @@ public class Modularizer {
cpath = ClassPath.newInstance(classpath);
}
- ClassListReader reader = new ClassListReader();
- Set<Module> modules = reader.loadModulesFrom(new File(classlistDir));
+ ClassListReader reader = new ClassListReader(classlistDir, "default");
+ Set<Module> modules = reader.run();
Modularizer modularizer = new Modularizer(cpath, new File(modulepath), modules);
modularizer.run(update);
}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Module.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Module.java
index 82a3e83..60693e2 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Module.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/Module.java
@@ -23,58 +23,29 @@
*/
package com.sun.classanalyzer;
+import com.sun.classanalyzer.ModuleInfo.Dependence;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayDeque;
-import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
-
/**
* Module contains a list of classes and resources.
*
* @author Mandy Chung
*/
public class Module implements Comparable<Module> {
-
- private static final Map<String, Module> modules =
- new LinkedHashMap<String, Module>();
-
- public static Collection<Module> getAllModules() {
- return Collections.unmodifiableCollection(modules.values());
- }
-
- public static void addModule(Module m) {
- String name = m.name();
- if (modules.containsKey(name)) {
- throw new RuntimeException("module \"" + name + "\" already exists");
- }
- modules.put(name, m);
- }
-
- public static Module addModule(ModuleConfig config) {
- String name = config.module;
- if (modules.containsKey(name)) {
- throw new RuntimeException("module \"" + name + "\" already exists");
- }
- Module m = new Module(config);
- addModule(m);
- return m;
- }
-
- public static Module findModule(String name) {
- return modules.get(name);
- }
-
private static String baseModuleName = "base";
static void setBaseModule(String name) {
if (name == null || name.isEmpty()) {
@@ -83,11 +54,19 @@ public class Module implements Comparable<Module> {
baseModuleName = name;
}
- private static Properties moduleProps = new Properties();
+ static Properties moduleProps = new Properties();
static String getModuleProperty(String key) {
- return moduleProps.getProperty(key);
+ return getModuleProperty(key, null);
+ }
+ static String getModuleProperty(String key, String defaultValue) {
+ String value = moduleProps.getProperty(key);
+ if (value == null)
+ return defaultValue;
+ else
+ return value;
}
+
static void setModuleProperties(String file) throws IOException {
File f = new File(file);
BufferedReader reader = null;
@@ -100,20 +79,27 @@ public class Module implements Comparable<Module> {
}
}
}
+
private final String name;
+ private final String version;
private final ModuleConfig config;
private final Set<Klass> classes;
private final Set<ResourceFile> resources;
private final Set<Reference> unresolved;
private final Set<Module> members;
// update during the analysis
+
private Module group;
private ModuleInfo minfo;
+ private Set<PackageInfo> pkgInfos;
+ private Set<PackageInfo> resourcePkgInfos;
+
private boolean isBaseModule;
protected String mainClassName;
protected Module(ModuleConfig config) {
this.name = config.module;
+ this.version = config.version;
this.isBaseModule = name.equals(baseModuleName);
this.classes = new TreeSet<Klass>();
this.resources = new TreeSet<ResourceFile>();
@@ -128,6 +114,10 @@ public class Module implements Comparable<Module> {
return name;
}
+ String version() {
+ return version;
+ }
+
ModuleConfig config() {
return config;
}
@@ -144,6 +134,22 @@ public class Module implements Comparable<Module> {
return Collections.unmodifiableSet(classes);
}
+ synchronized Set<PackageInfo> packages() {
+ if (pkgInfos == null) {
+ pkgInfos = new TreeSet<PackageInfo>();
+ resourcePkgInfos = new TreeSet<PackageInfo>();
+ for (PackageInfo pi : PackageInfo.getPackageInfos(this)) {
+ if (pi.classCount > 0) {
+ pkgInfos.add(pi);
+ }
+ if (pi.resourceCount > 0) {
+ resourcePkgInfos.add(pi);
+ }
+ }
+ }
+ return Collections.unmodifiableSet(pkgInfos);
+ }
+
Set<ResourceFile> resources() {
return Collections.unmodifiableSet(resources);
}
@@ -166,15 +172,21 @@ public class Module implements Comparable<Module> {
return moduleProps.getProperty(name + ".allow.empty") != null;
}
- // returns itself.
- public Module exporter(Module from) {
- return this;
+ boolean exportAllPackages() {
+ // default - only exported packages
+ String value = moduleProps.getProperty(name + ".exports.all");
+ return value != null && Boolean.valueOf(value);
}
protected boolean isTopLevel() {
// module with no class is not included except the base module
- return this.group == this
- && (isBase() || !isEmpty() || !config.requires().isEmpty() || allowEmpty());
+ // or reexporting APIs from required modules
+ boolean reexports = false;
+ for (Dependence d : config().requires()) {
+ reexports = reexports || d.isPublic();
+ }
+ return this.group() == this
+ && (isBase() || !isEmpty() || allowEmpty() || reexports);
}
Klass mainClass() {
@@ -282,9 +294,9 @@ public class Module implements Comparable<Module> {
Module getModuleDependence(Klass k) {
if (isModuleDependence(k)) {
Module m = k.getModule();
- if (group == this && m != null) {
+ if (group() == this && m != null) {
// top-level module
- return m.group;
+ return m.group();
} else {
return m;
}
@@ -330,76 +342,128 @@ public class Module implements Comparable<Module> {
}
}
- static void buildModuleMembers() {
- // set up module member relationship
- for (Module m : modules.values()) {
- m.group = m; // initialize to itself
- for (String name : m.config.members()) {
- Module member = modules.get(name);
- if (member == null) {
- throw new RuntimeException("module \"" + name + "\" doesn't exist");
- }
- m.members.add(member);
+ private static Factory INSTANCE = new Factory();
+ public static Factory getFactory() {
+ return INSTANCE;
+ }
+
+ static class Factory {
+ protected Map<String, Module> modules =
+ new LinkedHashMap<String, Module>();
+ protected final void addModule(Module m) {
+ // ## For now, maintain the static all modules list.
+ // ## Need to revisit later
+ String name = m.name();
+ if (modules.containsKey(name)) {
+ throw new RuntimeException("module \"" + name + "\" already exists");
}
+ modules.put(name, m);
}
- // set up the top-level module
- ModuleVisitor<Module> groupSetter = new ModuleVisitor<Module>() {
+ public final Module findModule(String name) {
+ return modules.get(name);
+ }
- public void preVisit(Module m, Module p) {
- m.group = p;
- if (p.isBaseModule) {
- // all members are also base
- m.isBaseModule = true;
- }
- }
+ public final Set<Module> getAllModules() {
+ Set<Module> ms = new LinkedHashSet<Module>(modules.values());
+ // always add nullModule the last as classes may be added later
+ ms.add(nullModule);
+ return ms;
+ }
- public void visited(Module m, Module child, Module p) {
- // nop - breadth-first search
+ public void init(List<ModuleConfig> mconfigs) {
+ for (ModuleConfig mconfig : mconfigs) {
+ Module m = this.newModule(mconfig);
+ addModule(m);
}
+ }
- public void postVisit(Module m, Module p) {
- // nop - breadth-first search
- }
- };
+ public Module newModule(String name, String version) {
+ return this.newModule(new ModuleConfig(name, version));
+ }
- // propagate the top-level module to all its members
- for (Module p : modules.values()) {
- for (Module m : p.members) {
- if (m.group == m) {
- m.visitMembers(new TreeSet<Module>(), groupSetter, p);
- }
+ public Module newModule(ModuleConfig config) {
+ return new Module(config);
+ }
+
+ public final void addModules(Set<Module> ms) {
+ for (Module m : ms) {
+ addModule(m);
}
}
- ModuleVisitor<Module> mergeClassList = new ModuleVisitor<Module>() {
+ Module nullModule = initNullModule();
+ private Module initNullModule() {
+ return this.newModule(new ModuleConfig("unknown", "unknown"));
+ }
- public void preVisit(Module m, Module p) {
- // nop - depth-first search
+ void buildModuleMembers() {
+ // set up module member relationship
+ for (Module m : getAllModules()) {
+ m.group = m; // initialize to itself
+ for (String name : m.config.members()) {
+ Module member = findModule(name);
+ if (member != null) {
+ m.members.add(member);
+ }
+ }
}
- public void visited(Module m, Module child, Module p) {
- m.addMember(child);
- }
+ // set up the top-level module
+ ModuleVisitor<Module> groupSetter = new ModuleVisitor<Module>() {
+ public void preVisit(Module m, Module p) {
+ m.group = p;
+ if (p.isBaseModule) {
+ // all members are also base
+ m.isBaseModule = true;
+ }
+ }
+
+ public void visited(Module m, Module child, Module p) {
+ // nop - breadth-first search
+ }
+
+ public void postVisit(Module m, Module p) {
+ // nop - breadth-first search
+ }
+ };
- public void postVisit(Module m, Module p) {
+ // propagate the top-level module to all its members
+ for (Module p : getAllModules()) {
+ for (Module m : p.members) {
+ if (m.group == m) {
+ m.visitMembers(new TreeSet<Module>(), groupSetter, p);
+ }
+ }
}
- };
-
- Set<Module> visited = new TreeSet<Module>();
- Set<Module> groups = new TreeSet<Module>();
- for (Module m : modules.values()) {
- if (m.group() == m) {
- groups.add(m);
- if (m.members().size() > 0) {
- // merge class list from all its members
- m.visitMembers(visited, mergeClassList, m);
+
+ ModuleVisitor<Module> mergeClassList = new ModuleVisitor<Module>() {
+ public void preVisit(Module m, Module p) {
+ // nop - depth-first search
+ }
+
+ public void visited(Module m, Module child, Module p) {
+ m.addMember(child);
+ }
+
+ public void postVisit(Module m, Module p) {
+ }
+ };
+
+ Set<Module> visited = new TreeSet<Module>();
+ Set<Module> groups = new TreeSet<Module>();
+ for (Module m : getAllModules()) {
+ if (m.group() == m) {
+ groups.add(m);
+ if (m.members().size() > 0) {
+ // merge class list from all its members
+ m.visitMembers(visited, mergeClassList, m);
+ }
}
}
}
}
-
ModuleInfo getModuleInfo() {
return minfo;
}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleBuilder.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleBuilder.java
index ffc7105..7b1ad29 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleBuilder.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleBuilder.java
@@ -23,11 +23,10 @@
package com.sun.classanalyzer;
import com.sun.classanalyzer.AnnotatedDependency.OptionalDependency;
+import com.sun.classanalyzer.Module.Factory;
import com.sun.classanalyzer.Module.ModuleVisitor;
import com.sun.classanalyzer.ModuleInfo.Dependence;
-import com.sun.classanalyzer.ModuleInfo.PackageInfo;
import static com.sun.classanalyzer.ModuleInfo.Dependence.Modifier.*;
-import java.io.File;
import java.io.IOException;
import java.util.*;
@@ -42,12 +41,12 @@ import java.util.*;
* @author mchung
*/
public class ModuleBuilder {
+ protected Set<Module> result = new LinkedHashSet<Module>();
- private final List<String> depConfigs = new ArrayList<String>();
- private final Map<Module, ModuleInfo> moduleinfos =
- new LinkedHashMap<Module, ModuleInfo>();
- private final String version;
- private final boolean mergeModules;
+ protected final List<ModuleConfig> mconfigs = new ArrayList<ModuleConfig>();
+ protected final List<String> depConfigs = new ArrayList<String>();
+ protected final boolean mergeModules;
+ protected final String version;
public ModuleBuilder(List<String> configs, String version)
throws IOException {
@@ -60,11 +59,8 @@ public class ModuleBuilder {
String version)
throws IOException {
if (configs != null) {
- // create modules based on the input config files
for (String file : configs) {
- for (ModuleConfig mconfig : ModuleConfig.readConfigurationFile(file)) {
- newModule(mconfig);
- }
+ mconfigs.addAll(ModuleConfig.readConfigurationFile(file, version));
}
}
if (depconfigs != null) {
@@ -72,30 +68,21 @@ public class ModuleBuilder {
}
this.mergeModules = merge;
this.version = version;
- }
- /**
- * Returns a module of a given name with no main entry point.
- */
- public Module newModule(String name) throws IOException {
- return newModule(new ModuleConfig(name, null));
}
/**
- * Returns a module of a given ModuleConfig.
+ * Returns the module factory.
*/
- public Module newModule(ModuleConfig mconfig) {
- return Module.addModule(mconfig);
+ protected Factory getFactory() {
+ return Module.getFactory();
}
/**
- * Loads modules from the .classlist and .resources files in
- * the given classListDir.
- *
+ * Returns the resulting modules from this builder.
*/
- public Set<Module> loadModulesFrom(File classlistDir) throws IOException {
- ClassListReader reader = new ClassListReader(this);
- return reader.loadModulesFrom(classlistDir);
+ public final Set<Module> getModules() {
+ return result;
}
/**
@@ -105,23 +92,20 @@ public class ModuleBuilder {
*
* This method can be overridden in a subclass implementation.
*/
- public void run() throws IOException {
+ public Set<Module> run() throws IOException {
// assign classes and resource files to the modules and
// group fine-grained modules per configuration files
buildModules();
- // generate package information
+ // generate package infos and determine if there is any split package
buildPackageInfos();
// analyze cross-module dependencies and generate ModuleInfo
- buildModuleInfos();
- }
+ List<ModuleInfo> minfos = buildModuleInfos();
- /**
- * Returns the resulting top-level, non-empty modules.
- */
- public Set<Module> getModules() {
- return moduleinfos.keySet();
+ // generate an ordered list from the module dependency graph
+ result = Collections.unmodifiableSet(orderedModuleList(minfos));
+ return result;
}
/**
@@ -130,64 +114,81 @@ public class ModuleBuilder {
*
*/
protected void buildModules() throws IOException {
+ // create the modules for the given configs
+ getFactory().init(mconfigs);
+
// Add additional dependencies after classes are added to the modules
DependencyConfig.parse(depConfigs);
// process the roots and dependencies to get the classes for each module
- Collection<Module> modules = Module.getAllModules();
- for (Module m : modules) {
+ for (Module m : getFactory().getAllModules()) {
m.processRootsAndReferences();
}
if (mergeModules) {
// group fine-grained modules
- Module.buildModuleMembers();
+ getFactory().buildModuleMembers();
}
}
/**
* Build ModuleInfo for the top level modules.
*/
- protected void buildModuleInfos() {
- // backedges (i.e. reverse dependences)
- Map<Module, Set<Module>> backedges = new TreeMap<Module, Set<Module>>();
+ protected List<ModuleInfo> buildModuleInfos() {
+ List<ModuleInfo> minfos = new LinkedList<ModuleInfo>();
+ Set<Module> ms = new LinkedHashSet<Module>();
// analyze the module's dependences and create ModuleInfo
- for (Module m : Module.getAllModules()) {
+ // for all modules including the system modules
+ for (Module m : getFactory().getAllModules()) {
if (m.isTopLevel()) {
ModuleInfo mi = buildModuleInfo(m);
m.setModuleInfo(mi);
- moduleinfos.put(m, mi);
- // keep track of the backedges
- for (Dependence d : mi.requires()) {
- // only add the top level modules
- Module dep = d.getModule();
- Set<Module> set = backedges.get(dep);
- if (set == null) {
- set = new TreeSet<Module>();
- backedges.put(dep, set);
- }
- set.add(m);
- }
+ minfos.add(mi);
}
}
+ fixupPermits(minfos);
+
+ return minfos;
+ }
+
+ private void fixupPermits(List<ModuleInfo> minfos) {
+ // backedges (i.e. reverse dependences)
+ Map<Module, Set<Module>> backedges = new TreeMap<Module, Set<Module>>();
+ Map<Module, ModuleInfo> map = new LinkedHashMap<Module, ModuleInfo>();
+
// fixup permits after all ModuleInfo are created in two passes:
// 1. permits the requesting module if it requires local dependence
// 2. if permits set is non-empty, permits
// all of its requesting modules
- for (ModuleInfo mi : moduleinfos.values()) {
+ for (ModuleInfo mi : minfos) {
+ // keep track of the backedges
+ map.put(mi.getModule(), mi);
+ for (Dependence d : mi.requires()) {
+ // only add the top level modules
+ Module dep = d.getModule();
+ Set<Module> set = backedges.get(dep);
+ if (set == null) {
+ set = new TreeSet<Module>();
+ backedges.put(dep, set);
+ }
+ set.add(mi.getModule());
+ }
+ }
+
+ for (ModuleInfo mi : minfos) {
for (Dependence d : mi.requires()) {
if (d.isLocal()) {
Module dm = d.getModule();
- moduleinfos.get(dm).addPermit(mi.getModule());
+ map.get(dm).addPermit(mi.getModule());
}
}
}
for (Map.Entry<Module, Set<Module>> e : backedges.entrySet()) {
Module dm = e.getKey();
- ModuleInfo dmi = moduleinfos.get(dm);
+ ModuleInfo dmi = map.get(dm);
if (dmi == null) {
throw new RuntimeException(dm + " null moduleinfo");
}
@@ -199,106 +200,84 @@ public class ModuleBuilder {
}
}
- // module to packages
- private final Map<Module, Set<PackageInfo>> packagesForModule =
- new TreeMap<Module, Set<PackageInfo>>();
- // package name to PackageInfo set
- private final Map<String, Set<PackageInfo>> packages =
- new TreeMap<String, Set<PackageInfo>>();
- // module with split packages
- private final Map<Module, Set<PackageInfo>> modulesWithSplitPackage =
- new TreeMap<Module, Set<PackageInfo>>();
+ private Set<Module> otherModules = new LinkedHashSet<Module>();
+ public final void addModules(Set<Module> ms) {
+ otherModules.addAll(ms);
+ // ## current implementation requires ModuleInfo be created
+ // ## for all modules for the analysis. Need to add them
+ // ## in the factory's modules list.
+ getFactory().addModules(ms);
+ }
- /**
- * Builds PackageInfo for each top level module.
- */
- protected void buildPackageInfos() {
- for (Module m : Module.getAllModules()) {
- if (m.isTopLevel()) {
- Set<PackageInfo> pkgs = getPackageInfos(m);
- packagesForModule.put(m, pkgs);
- }
- }
+ private Set<Module> orderedModuleList(Collection<ModuleInfo> minfos) {
+ // add modules to the moduleinfos map in order
+ // its dependences first before the module
+ // TODO: what if there is a cycle??
+ Set<Module> visited = new TreeSet<Module>();
+ Set<Module> orderedList = new LinkedHashSet<Module>();
+ Dependence.Filter filter = new Dependence.Filter() {
- for (Map.Entry<Module, Set<PackageInfo>> e : packagesForModule.entrySet()) {
- Module m = e.getKey();
- for (PackageInfo p : e.getValue()) {
- Set<PackageInfo> set = packages.get(p.pkgName);
- if (set == null) {
- set = new TreeSet<PackageInfo>();
- packages.put(p.pkgName, set);
- }
- set.add(p);
+ @Override
+ public boolean accept(Dependence d) {
+ return !d.isOptional();
}
+ };
+
+ for (ModuleInfo mi : minfos) {
+ mi.visitDependence(filter, visited, orderedList);
}
+ // only return the modules that this builder is interested in
+ Set<Module> ms = new LinkedHashSet<Module>(orderedList);
+ ms.removeAll(otherModules);
+ return ms;
+ }
- for (Map.Entry<String, Set<PackageInfo>> e : packages.entrySet()) {
- String pkg = e.getKey();
- if (e.getValue().size() > 1) {
- for (PackageInfo pi : e.getValue()) {
- Set<PackageInfo> set = modulesWithSplitPackage.get(pi.module);
+ // module with split packages
+ private final Map<String, Set<Module>> splitPackages =
+ new LinkedHashMap<String, Set<Module>>();
+ public Map<String, Set<Module>> getSplitPackages() {
+ return splitPackages;
+ }
+ /**
+ * Builds PackageInfo for each top level module.
+ */
+ protected void buildPackageInfos() {
+ // package name to PackageInfo set
+ Map<String, Set<PackageInfo>> packages =
+ new TreeMap<String, Set<PackageInfo>>();
+ // build the map of a package name to PackageInfo set
+ // It only looks at its own list of modules.
+ // Subclass of ModuleBuilder can exclude any modules
+ for (Module m : getFactory().getAllModules()) {
+ if (m.isTopLevel() && !otherModules.contains(m)) {
+ for (PackageInfo p : m.packages()) {
+ Set<PackageInfo> set = packages.get(p.pkgName);
if (set == null) {
set = new TreeSet<PackageInfo>();
- modulesWithSplitPackage.put(pi.module, set);
+ packages.put(p.pkgName, set);
}
- set.add(pi);
+ set.add(p);
}
}
}
- }
- public Map<String, Set<Module>> getSplitPackages() {
- Map<String, Set<Module>> result = new LinkedHashMap<String, Set<Module>>();
for (Map.Entry<String, Set<PackageInfo>> e : packages.entrySet()) {
String pkg = e.getKey();
+ // split package if there are more than one PackageInfo
if (e.getValue().size() > 1) {
for (PackageInfo pi : e.getValue()) {
- Set<Module> set = result.get(pkg);
- if (set == null) {
- set = new TreeSet<Module>();
- result.put(pkg, set);
+ Set<Module> mset = splitPackages.get(pkg);
+ if (mset == null) {
+ mset = new TreeSet<Module>();
+ splitPackages.put(pkg, mset);
}
- set.add(pi.module);
+ mset.add(pi.module);
}
}
}
- return result;
- }
-
- private Set<PackageInfo> getPackageInfos(final Module m) {
- Map<String, PackageInfo> packages = new TreeMap<String, PackageInfo>();
- Module.Visitor<Void, Map<String, PackageInfo>> visitor =
- new Module.Visitor<Void, Map<String, PackageInfo>>() {
-
- @Override
- public Void visitClass(Klass k, Map<String, PackageInfo> packages) {
- // update package statistics
- String pkg = k.getPackageName();
- PackageInfo pkginfo = packages.get(pkg);
- if (pkginfo == null) {
- pkginfo = new PackageInfo(m, pkg);
- packages.put(pkg, pkginfo);
- }
-
- if (k.exists()) {
- // only count the class that is parsed
- pkginfo.add(k.getFileSize());
- }
- return null;
- }
-
- @Override
- public Void visitResource(ResourceFile r, Map<String, PackageInfo> packages) {
- // nop
- return null;
- }
- };
-
- m.visit(visitor, packages);
- return new TreeSet<PackageInfo>(packages.values());
}
- private ModuleInfo buildModuleInfo(Module m) {
+ protected ModuleInfo buildModuleInfo(Module m) {
Map<Module, Dependence> requires = new LinkedHashMap<Module, Dependence>();
Set<Module> permits = new TreeSet<Module>();
@@ -308,25 +287,30 @@ public class ModuleBuilder {
if (m.isModuleDependence(to)) {
// is this dependence overridden as optional?
boolean optional = OptionalDependency.isOptional(from, to);
- addDependence(requires, new Dependence(from, to, optional));
+ // if class is not assigned to any module, assign it to unknown
+ if (to.getModule() == null)
+ getFactory().nullModule.addKlass(to);
+ addDependence(requires, to, optional);
}
}
}
+ // add requires and permits specified in the config files
+ processModuleConfigs(m, requires, permits);
+
// add dependency due to the main class
Klass k = m.mainClass();
if (k != null && m.isModuleDependence(k)) {
- addDependence(requires, new Dependence(k.getModule()));
+ if (k.getModule() == null)
+ getFactory().nullModule.addKlass(k);
+ addDependence(requires, k);
}
- // add requires and permits specified in the config files
- processModuleConfigs(m, requires, permits);
-
// add dependencies due to the AnnotatedDependency
for (Dependence d : AnnotatedDependency.getDependencies(m)) {
if (d.isOptional()) {
Trace.trace("Warning: annotated dependency from %s to %s ignored%n",
- m.name(), d.toString());
+ m.name(), d.toString());
continue;
}
addDependence(requires, d);
@@ -334,75 +318,74 @@ public class ModuleBuilder {
// Add LOCAL to the dependence and permits will be added
// in the separate phase
- Set<PackageInfo> splitPkgs = modulesWithSplitPackage.get(m);
- if (splitPkgs != null) {
- for (PackageInfo sp : splitPkgs) {
- Set<PackageInfo> pis = packages.get(sp.pkgName);
- for (PackageInfo pi : pis) {
- // is the package splitted with its dependence?
- if (requires.containsKey(pi.module)) {
- // If so, the dependence has to be LOCAL
- requires.get(pi.module).addModifier(LOCAL);
- }
- }
+ for (PackageInfo pi : m.packages()) {
+ Set<Module> mset = splitPackages.get(pi.pkgName);
+ if (mset == null) {
+ continue;
}
- }
- // use the module's exporter in the dependence
- Set<Dependence> depset = new TreeSet<Dependence>();
- for (Dependence d : requires.values()) {
- Dependence dep = d;
- if (!d.isLocal()) {
- Module exp = d.getModule().exporter(m);
- if (exp == null) {
- throw new RuntimeException(d.getModule() + " null exporter");
- }
- if (d.getModule() != exp && exp != m) {
- dep = new Dependence(exp, d.modifiers());
+ assert mset.contains(m);
+ for (Module sm : mset) {
+ // is the package splitted with its dependence?
+ if (requires.containsKey(sm)) {
+ // If so, the dependence has to be LOCAL
+ requires.get(sm).addModifier(LOCAL);
}
}
- // ## not to include optional dependences in jdk.boot
- // ## should move this to jdk.base
- if (m instanceof PlatformModuleBuilder.BootModule && d.isOptional()) {
- continue;
- }
-
- depset.add(dep);
}
- ModuleInfo mi = new ModuleInfo(m, version, packagesForModule.get(m), depset, permits);
+
+ ModuleInfo mi = new ModuleInfo(m,
+ new TreeSet<Dependence>(requires.values()),
+ permits);
return mi;
}
+ private void addDependence(Map<Module, Dependence> requires, Klass k) {
+ addDependence(requires, k, false);
+ }
+
+ private void addDependence(Map<Module, Dependence> requires, Klass k, boolean optional) {
+ Dependence d = new Dependence(k.getModule(), optional);
+ d.setInternal(PackageInfo.isExportedPackage(k.getPackageName()) == false);
+ addDependence(requires, d);
+ }
+
private void addDependence(Map<Module, Dependence> requires, Dependence d) {
Module dm = d.getModule();
Dependence dep = requires.get(dm);
- if (dep == null || dep.equals(d)) {
- requires.put(dm, d);
- } else {
+ if (dep != null && !dep.equals(d)) {
if (dep.getModule() != d.getModule()) {
throw new RuntimeException("Unexpected dependence " + dep + " != " + d);
}
// update the modifiers
dep.update(d);
- requires.put(dm, dep);
+ d = dep;
}
+ requires.put(dm, d);
}
private void processModuleConfigs(final Module module,
final Map<Module, Dependence> requires,
final Set<Module> permits) {
ModuleVisitor<Void> v = new ModuleVisitor<Void>() {
-
public void preVisit(Module p, Void dummy) {
}
public void visited(Module p, Module m, Void dummy) {
for (Dependence d : m.config().requires()) {
+ if (d.getModule() == null) {
+ // set the module in the Dependence as it
+ // was unknown when ModuleConfig was initialized.
+ Module dm = getFactory().findModule(d.id);
+ if (dm == null)
+ throw new RuntimeException("Module " + d.id + " doesn't exist");
+ d.setModule(dm);
+ }
addDependence(requires, d);
}
for (String name : m.config().permits()) {
- Module pm = Module.findModule(name);
+ Module pm = getFactory().findModule(name);
if (pm != null) {
permits.add(pm.group());
} else {
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleConfig.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleConfig.java
index 7be9111..6f06f68 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleConfig.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleConfig.java
@@ -37,6 +37,7 @@ import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.Map;
import com.sun.classanalyzer.ModuleInfo.Dependence;
+import com.sun.classanalyzer.ModuleInfo.Dependence.Modifier;
/**
*
@@ -48,20 +49,27 @@ public class ModuleConfig {
protected final Set<String> includes;
protected final Set<String> permits;
protected final Map<String, Dependence> requires;
+ protected final Set<String> exports;
private final Filter filter;
private List<String> members;
private String mainClass;
final String module;
+ final String version;
- ModuleConfig(String name) throws IOException {
- this(name, null);
+ ModuleConfig(String name, String version) {
+ this(name, version, null);
}
- ModuleConfig(String name, String mainClass) throws IOException {
+ ModuleConfig(String name, String version, String mainClass)
+ {
+ assert name != null && version != null;
+
this.module = name;
+ this.version = version;
this.roots = new TreeSet<String>();
this.includes = new TreeSet<String>();
this.permits = new TreeSet<String>();
+ this.exports = new TreeSet<String>();
this.requires = new LinkedHashMap<String, Dependence>();
this.filter = new Filter(this);
this.mainClass = mainClass;
@@ -72,8 +80,8 @@ public class ModuleConfig {
members = new LinkedList<String>();
for (String s : includes) {
- if (!s.contains("*") && Module.findModule(s) != null) {
- // module member
+ if (!s.contains("*")) {
+ // this isn't necessarily a module. Will determine later.
members.add(s);
}
}
@@ -85,18 +93,28 @@ public class ModuleConfig {
return permits;
}
+ Set<String> exports() {
+ return exports;
+ }
+
Collection<Dependence> requires() {
return requires.values();
}
- void export(Module m) {
+ void reexportModule(Module m) {
+ reexportModule(m, false);
+ }
+
+ void reexportModule(Module m, boolean optional) {
Dependence d = requires.get(m.name());
if (d == null) {
- d = new Dependence(m, EnumSet.of(Dependence.Modifier.PUBLIC));
+ EnumSet<Modifier> mods = optional ?
+ EnumSet.of(Modifier.PUBLIC, Modifier.OPTIONAL) :
+ EnumSet.of(Modifier.PUBLIC);
+ requires.put(m.name(), new Dependence(m, mods));
} else if (!d.isPublic()){
throw new RuntimeException(module + " should require public " + m.name());
}
- requires.put(m.name(), d);
}
void addPermit(Module m) {
@@ -204,13 +222,12 @@ public class ModuleConfig {
int pos = pattern.indexOf('*');
String prefix = pattern.substring(0, pos);
String suffix = pattern.substring(pos + 1, pattern.length());
- String tail = name.substring(pos, name.length());
-
if (!name.startsWith(prefix)) {
// prefix has to exact match
return false;
}
+ String tail = name.substring(pos, name.length());
if (pattern.indexOf('*') == pattern.lastIndexOf('*')) {
// exact match prefix with no '/' in the tail string
String wildcard = tail.substring(0, tail.length() - suffix.length());
@@ -414,7 +431,7 @@ public class ModuleConfig {
// the naming convention for the module names without dashes
static final Pattern classNamePattern = Pattern.compile("[\\w\\.\\*_$-/]+");
- static List<ModuleConfig> readConfigurationFile(String file) throws IOException {
+ static List<ModuleConfig> readConfigurationFile(String file, String version) throws IOException {
List<ModuleConfig> result = new ArrayList<ModuleConfig>();
// parse configuration file
FileInputStream in = new FileInputStream(file);
@@ -459,7 +476,8 @@ public class ModuleConfig {
}
String values;
- if (inRoots || inIncludes || inExcludes || inAllows || inPermits || inRequires) {
+ if (inRoots || inIncludes || inExcludes || inAllows ||
+ inPermits || inRequires) {
values = line;
} else {
String[] s = line.split("\\s+");
@@ -470,7 +488,8 @@ public class ModuleConfig {
throw new RuntimeException(file + ", line " +
lineNumber + ", is malformed");
}
- config = new ModuleConfig(s[1].trim());
+ // use the given version
+ config = new ModuleConfig(s[1].trim(), version);
result.add(config);
// switch to a new module; so reset the flags
inRoots = false;
@@ -481,12 +500,12 @@ public class ModuleConfig {
inPermits = false;
continue;
} else if (keyword.equals("class")) {
- if (s.length != 2 || !s[1].trim().endsWith(";")) {
- throw new RuntimeException(file + ", line " +
- lineNumber + ", is malformed");
- }
- config.mainClass = s[1].substring(0, s[1].length() - 1);
- continue;
+ if (s.length != 2 || !s[1].trim().endsWith(";")) {
+ throw new RuntimeException(file + ", line "
+ + lineNumber + ", is malformed");
+ }
+ config.mainClass = s[1].substring(0, s[1].length() - 1);
+ continue;
} else if (keyword.equals("roots")) {
inRoots = true;
} else if (keyword.equals("include")) {
@@ -497,6 +516,14 @@ public class ModuleConfig {
inAllows = true;
} else if (keyword.equals("permits")) {
inPermits = true;
+ } else if (keyword.equals("export")) {
+ // only support one class/package/wildcard in each export statement
+ if (s.length != 2 || !s[1].trim().endsWith(";")) {
+ throw new RuntimeException(file + ", line "
+ + lineNumber + ", is malformed");
+ }
+ config.exports.add(s[1].substring(0, s[1].length() - 1));
+ continue;
} else if (keyword.equals("requires")) {
inRequires = true;
optional = false;
@@ -573,11 +600,6 @@ public class ModuleConfig {
throw new RuntimeException(file + ", line " +
lineNumber + " duplicated requires: \"" + s + "\"");
}
- boolean isBootModule = s.equals("jdk.boot");
- if (!local && isBootModule) {
- throw new RuntimeException(file + ", line " +
- lineNumber + " requires: \"" + s + "\" must be local");
- }
Dependence d = new Dependence(s, optional, reexport, local);
config.requires.put(s, d);
}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleInfo.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleInfo.java
index 43a5514..e28ebe9 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleInfo.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ModuleInfo.java
@@ -33,25 +33,20 @@ import java.util.*;
public class ModuleInfo {
private final Module module;
- private final String version;
- private final Set<PackageInfo> packages;
private final Set<Dependence> requires;
private final Set<Module> permits;
- ModuleInfo(Module m, String version,
- Collection<PackageInfo> packages,
- Collection<Dependence> reqs,
- Collection<Module> permits) {
+ ModuleInfo(Module m,
+ Collection<Dependence> reqs,
+ Collection<Module> permits) {
this.module = m;
- this.version = version;
- this.packages = new TreeSet<PackageInfo>(packages);
this.permits = new TreeSet<Module>(permits);
-
this.requires = new TreeSet<Dependence>();
// filter non-top level module
for (Dependence d : reqs) {
- if (d.getModule().isTopLevel())
+ if (d.getModule().isTopLevel()) {
requires.add(d);
+ }
}
}
@@ -67,11 +62,7 @@ public class ModuleInfo {
}
public String id() {
- return module.name() + " @ " + version;
- }
-
- public Set<PackageInfo> packages() {
- return Collections.unmodifiableSet(packages);
+ return module.name() + " @ " + module.version();
}
/**
@@ -100,7 +91,7 @@ public class ModuleInfo {
return k != null ? k.getClassName() : "";
}
- private void visitDependence(Dependence.Filter filter, Set<Module> visited, Set<Module> result) {
+ void visitDependence(Dependence.Filter filter, Set<Module> visited, Set<Module> result) {
if (!visited.contains(module)) {
visited.add(module);
@@ -122,7 +113,45 @@ public class ModuleInfo {
return result;
}
+ private Set<String> reexports;
+
+ private synchronized Set<String> reexports() {
+ if (reexports != null) {
+ return reexports;
+ }
+
+ final Module m = module;
+ Set<Module> deps = dependences(new Dependence.Filter() {
+
+ @Override
+ public boolean accept(Dependence d) {
+ // filter itself
+ return d.isPublic();
+ }
+ });
+
+ reexports = new TreeSet<String>();
+ for (Module dm : deps) {
+ if (dm != module) {
+ // exports all local packages
+ for (PackageInfo p : dm.packages()) {
+ if (PackageInfo.isExportedPackage(p.pkgName)) {
+ reexports.add(p.pkgName + ".*");
+ }
+ }
+ reexports.addAll(dm.getModuleInfo().reexports());
+ }
+ }
+ return reexports;
+ }
+
+ // a system property to specify to use "requires public"
+ // or the "exports" statement
+ private static final boolean requiresPublic =
+ Boolean.parseBoolean(System.getProperty("classanalyzer.requiresPublic", "true"));
private static final String INDENT = " ";
+
+
/**
* Returns a string representation of module-info.java for
* this module.
@@ -130,15 +159,18 @@ public class ModuleInfo {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("module ").append(id()).append(" {\n");
+ sb.append(String.format("module %s {%n", id()));
for (Dependence d : requires()) {
- sb.append(INDENT).append("requires");
+ String mods = "";
for (Dependence.Modifier mod : d.mods) {
- sb.append(" ").append(mod);
+ if (requiresPublic || mod != Dependence.Modifier.PUBLIC) {
+ mods += mod.toString() + " ";
+ }
}
- String did = d.getModule().getModuleInfo().id();
- sb.append(" ").append(did).append(";\n");
+ sb.append(String.format("%srequires %s%s;%n", INDENT,
+ mods,
+ d.getModule().getModuleInfo().id()));
}
String permits = INDENT + "permits ";
@@ -146,8 +178,9 @@ public class ModuleInfo {
for (Module pm : permits()) {
if (i > 0) {
permits += ", ";
- if ((i % 5) == 0)
+ if ((i % 5) == 0) {
permits += "\n" + INDENT + " "; // "permits"
+ }
}
permits += pm.name();
i++;
@@ -157,12 +190,74 @@ public class ModuleInfo {
sb.append(permits).append(";\n");
}
if (module.mainClass() != null) {
- sb.append(INDENT).append("class ").append(mainClass()).append(";\n");
+ sb.append(String.format("%sclass %s;%n", INDENT, mainClass()));
}
+
+ if (!requiresPublic)
+ printExports(sb);
+
sb.append("}\n");
return sb.toString();
}
+ private void printExports(StringBuilder sb) {
+ Set<Module> modules = dependences(new Dependence.Filter() {
+
+ @Override
+ public boolean accept(Dependence d) {
+ // filter itself
+ return d.isPublic();
+ }
+ });
+
+ // explicit exports in the given config file
+ Set<String> cexports = new TreeSet<String>();
+ for (Module m : modules) {
+ cexports.addAll(m.config().exports());
+ }
+
+ if (cexports.size() > 0) {
+ sb.append("\n" + INDENT + "// explicit exports\n");
+ for (String e : cexports) {
+ sb.append(String.format("%sexport %s;%n", INDENT, e));
+ }
+ }
+
+ // exports all local packages
+ Set<String> pkgs = new TreeSet<String>();
+ for (PackageInfo pi : module.packages()) {
+ String p = pi.pkgName;
+ if (module.exportAllPackages() || PackageInfo.isExportedPackage(p))
+ pkgs.add(p);
+ }
+
+ if (pkgs.size() > 0) {
+ sb.append(String.format("%n%s// exports %s packages%n", INDENT,
+ module.exportAllPackages() ? "all local" : "supported"));
+ for (String p : pkgs) {
+ sb.append(String.format("%sexport %s.*;%n", INDENT, p));
+ }
+ }
+
+ // reexports
+ if (reexports().size() > 0) {
+ Set<String> rexports = new TreeSet<String>();
+ if (modules.size() == 2) {
+ // special case?
+ rexports.addAll(reexports());
+ } else {
+ for (String e : reexports()) {
+ int j = e.indexOf('.');
+ rexports.add(e.substring(0, j) + ".**");
+ }
+ }
+ sb.append("\n" + INDENT + "// reexports\n");
+ for (String p : rexports) {
+ sb.append(String.format("%sexport %s;%n", INDENT, p));
+ }
+ }
+ }
+
static class Dependence implements Comparable<Dependence> {
static enum Modifier {
@@ -181,27 +276,25 @@ public class ModuleInfo {
return name;
}
}
- private final String id;
+ final String id;
private EnumSet<Modifier> mods;
- private Module sm = null;
+ private Module dm = null;
+ private boolean internal = false;
- public Dependence(Module sm) {
- this(sm, false);
+ public Dependence(Module dm) {
+ this(dm, false);
}
- public Dependence(Module sm, boolean optional) {
- this(sm, modifier(optional));
+ public Dependence(Module dm, boolean optional) {
+ this(dm, modifier(optional));
}
- public Dependence(Klass from, Klass to, boolean optional) {
- this(to.getModule(), modifier(optional));
- }
-
- public Dependence(Module sm, EnumSet<Modifier> mods) {
- this.sm = sm.group();
- this.id = this.sm.name();
+ public Dependence(Module dm, EnumSet<Modifier> mods) {
+ this.dm = dm.group();
+ this.id = dm.name();
this.mods = mods;
}
+
public Dependence(String name, boolean optional) {
this(name, optional, false, false);
}
@@ -224,19 +317,25 @@ public class ModuleInfo {
}
private static EnumSet<Modifier> modifier(boolean optional) {
- return optional ? EnumSet.of(Modifier.OPTIONAL) :
- EnumSet.noneOf(Modifier.class);
+ return optional ? EnumSet.of(Modifier.OPTIONAL)
+ : EnumSet.noneOf(Modifier.class);
}
- synchronized Module getModule() {
- if (sm == null) {
- Module m = Module.findModule(id);
- if (m == null) {
- throw new RuntimeException("Module " + id + " doesn't exist");
- }
- sm = m.group();
- }
- return sm;
+ void setModule(Module m) {
+ assert dm == null && m != null;
+ dm = m.group();
+ }
+
+ void setInternal(boolean b) {
+ internal = b;
+ }
+
+ boolean isInternal() {
+ return internal;
+ }
+
+ Module getModule() {
+ return dm;
}
public boolean isOptional() {
@@ -269,6 +368,7 @@ public class ModuleInfo {
if (!isPublic() && d.isPublic()) {
mods.add(Modifier.PUBLIC);
}
+ internal = internal || d.internal;
}
public EnumSet<Modifier> modifiers() {
@@ -276,6 +376,7 @@ public class ModuleInfo {
}
static interface Filter {
+
public boolean accept(Dependence d);
}
@@ -317,58 +418,4 @@ public class ModuleInfo {
return sb.toString();
}
}
-
- static class PackageInfo implements Comparable<PackageInfo> {
-
- final Module module;
- final String pkgName;
- int count;
- long filesize;
-
- public PackageInfo(Module m, String name) {
- this.module = m;
- this.pkgName = name;
- this.count = 0;
- this.filesize = 0;
- }
-
- void add(PackageInfo pkg) {
- this.count += pkg.count;
- this.filesize += pkg.filesize;
- }
-
- void add(long size) {
- count++;
- filesize += size;
-
- }
-
- @Override
- public int hashCode() {
- int hash = 5;
- hash = 59 * hash + (this.module != null ? this.module.hashCode() : 0);
- hash = 59 * hash + (this.pkgName != null ? this.pkgName.hashCode() : 0);
- return hash;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof PackageInfo) {
- PackageInfo p = (PackageInfo) o;
- return p.module.equals(this.module) && p.pkgName.equals(this.pkgName);
- }
- return false;
- }
-
- @Override
- public int compareTo(PackageInfo p) {
- if (this.equals(p)) {
- return 0;
- } else if (pkgName.compareTo(p.pkgName) == 0) {
- return module.compareTo(p.module);
- } else {
- return pkgName.compareTo(p.pkgName);
- }
- }
- }
}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/PackageInfo.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/PackageInfo.java
new file mode 100644
index 0000000..8c4f845
--- /dev/null
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/PackageInfo.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2011, 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 com.sun.classanalyzer;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Package Information
+ */
+public class PackageInfo implements Comparable<PackageInfo> {
+
+ final Module module;
+ final String pkgName;
+ final boolean exportPkg;
+ int classCount;
+ long classBytes;
+ int publicClassCount;
+ int innerClassCount;
+ int resourceCount;
+ long resourceBytes;
+
+ PackageInfo(Module m, String name) {
+ this.module = m;
+ this.pkgName = name;
+ this.exportPkg = isExportedPackage(name);
+ this.classCount = 0;
+ this.classBytes = 0;
+ this.publicClassCount = 0;
+ this.innerClassCount = 0;
+ this.resourceCount = 0;
+ this.resourceBytes = 0;
+ }
+
+ private void add(PackageInfo pkg) {
+ this.classCount += pkg.classCount;
+ this.classBytes += pkg.classBytes;
+ this.publicClassCount += pkg.publicClassCount;
+ this.innerClassCount += pkg.innerClassCount;
+ this.resourceCount += pkg.resourceCount;
+ this.resourceBytes += pkg.resourceBytes;
+ }
+
+ void addKlass(Klass k) {
+ classCount++;
+ classBytes += k.getFileSize();
+ if (k.isPublic()) {
+ publicClassCount++;
+ }
+ if (k.getClassName().contains("$")) {
+ innerClassCount++;
+ }
+ }
+
+ private void addResource(ResourceFile r) {
+ resourceCount++;
+ resourceBytes += r.getFileSize();
+ }
+
+ boolean isExported() {
+ return exportPkg;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 59 * hash + (this.module != null ? this.module.hashCode() : 0);
+ hash = 59 * hash + (this.pkgName != null ? this.pkgName.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof PackageInfo) {
+ PackageInfo p = (PackageInfo) o;
+ return p.module.equals(this.module) && p.pkgName.equals(this.pkgName);
+ }
+ return false;
+ }
+
+ @Override
+ public int compareTo(PackageInfo p) {
+ if (this.equals(p)) {
+ return 0;
+ } else if (pkgName.compareTo(p.pkgName) == 0) {
+ return module.compareTo(p.module);
+ } else {
+ return pkgName.compareTo(p.pkgName);
+ }
+ }
+
+ public static Collection<PackageInfo> getPackageInfos(final Module m) {
+ Map<String, PackageInfo> packages = new HashMap<String, PackageInfo>();
+ Module.Visitor<Void, Map<String, PackageInfo>> visitor =
+ new Module.Visitor<Void, Map<String, PackageInfo>>() {
+ private PackageInfo getPackageInfo(Map<String, PackageInfo> packages, String pkg) {
+ PackageInfo pkginfo = packages.get(pkg);
+ if (pkginfo == null) {
+ pkginfo = new PackageInfo(m, pkg);
+ packages.put(pkg, pkginfo);
+ }
+ return pkginfo;
+ }
+ @Override
+ public Void visitClass(Klass k, Map<String, PackageInfo> packages) {
+ if (k.exists()) {
+ // update package statistics
+ String pkg = k.getPackageName();
+ PackageInfo pkginfo = getPackageInfo(packages, pkg);
+ // only count the class that is parsed
+ pkginfo.addKlass(k);
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitResource(ResourceFile r, Map<String, PackageInfo> packages) {
+ String pkg = "";
+ int i = r.getName().lastIndexOf('/');
+ if (i > 0) {
+ pkg = r.getName().substring(0, i).replace('/', '.');
+ }
+ PackageInfo pkginfo = getPackageInfo(packages, pkg);
+ pkginfo.addResource(r);
+ return null;
+ }
+ };
+
+ m.visit(visitor, packages);
+ return packages.values();
+ }
+ final static Set<String> exportedPackages = new TreeSet<String>();
+
+ static {
+ // if exported.packages property is not set,
+ // exports all packages
+ String apis = Module.getModuleProperty("exported.packages");
+ if (apis != null) {
+ for (String s : apis.split("\\s+")) {
+ exportedPackages.add(s.trim());
+ }
+ }
+ }
+
+ static boolean isExportedPackage(String pkg) {
+ return exportedPackages.isEmpty() || exportedPackages.contains(pkg);
+ }
+}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/PlatformModuleBuilder.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/PlatformModuleBuilder.java
index 7215c3f..0a09d8a 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/PlatformModuleBuilder.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/PlatformModuleBuilder.java
@@ -22,12 +22,10 @@
*/
package com.sun.classanalyzer;
+import com.sun.classanalyzer.Module.Factory;
import com.sun.classanalyzer.ModuleInfo.Dependence;
-import static com.sun.classanalyzer.PlatformModuleBuilder.PlatformModuleNames.*;
+import static com.sun.classanalyzer.PlatformModuleBuilder.PlatformFactory.*;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
import java.io.IOException;
import java.util.*;
@@ -43,33 +41,7 @@ import java.util.*;
* @author Mandy Chung
*/
public class PlatformModuleBuilder extends ModuleBuilder {
- /**
- * Platform modules that must be defined in the modules.properties
- */
- static class PlatformModuleNames {
- static final String BOOT_MODULE =
- getValue("platform.boot.module");
- static final String BASE_MODULE =
- getValue("platform.base.module");
- static final String JDK_MODULE =
- getValue("platform.jdk.module");
- static final String JRE_MODULE =
- getValue("platform.jre.module");
- static final String JRE_TOOLS_MODULE =
- getValue("platform.jre.tools.module");
-
- private static String getValue(String key) {
- String value = Module.getModuleProperty(key);
- if (value == null || value.isEmpty()) {
- throw new RuntimeException("Null or empty module property: " + key);
- }
- return value;
- }
- }
-
- private BootModule bootModule;
- private final PlatformModule jdkModule;
- private final PlatformModule jreModule;
+ private final PlatformFactory factory;
public PlatformModuleBuilder(List<String> configs, String version)
throws IOException {
@@ -77,33 +49,22 @@ public class PlatformModuleBuilder extends ModuleBuilder {
}
public PlatformModuleBuilder(List<String> configs,
- List<String> depconfigs,
- boolean merge,
- String version)
+ List<String> depconfigs,
+ boolean merge,
+ String version)
throws IOException {
super(null, depconfigs, merge, version);
-
- Module.setBaseModule(BASE_MODULE);
-
- // create modules based on the input config files
- for (String file : configs) {
- for (ModuleConfig mconfig : ModuleConfig.readConfigurationFile(file)) {
- newModule(mconfig);
- }
- }
-
- // Create the full jdk and jre modules
- jdkModule = (PlatformModule) newModule(JDK_MODULE);
- jreModule = (PlatformModule) newModule(JRE_MODULE);
+ // the factory will create the modules for the input config files
+ this.factory = new PlatformFactory(configs, version);
}
@Override
- public Module newModule(ModuleConfig mconfig) {
- return addPlatformModule(mconfig);
+ protected Factory getFactory() {
+ return factory;
}
@Override
- public void run() throws IOException {
+ public Set<Module> run() throws IOException {
// assign classes and resource files to the modules
// group fine-grained modules per configuration files
buildModules();
@@ -111,39 +72,35 @@ public class PlatformModuleBuilder extends ModuleBuilder {
// build public jdk modules to reexport sun.* modules
buildJDKModules();
- // generate package information
+ // generate package infos and determine if there is any split package
buildPackageInfos();
// analyze cross-module dependencies and generate ModuleInfo
- buildModuleInfos();
+ List<ModuleInfo> minfos = buildModuleInfos();
- // ## Hack: add local to all requires
- for (Module m : Module.getAllModules()) {
- if (m.isTopLevel()) {
- PlatformModule pm = (PlatformModule) m;
- if (pm.isBootConnected()) {
- for (Dependence d : pm.getModuleInfo().requires()) {
- d.addModifier(Dependence.Modifier.LOCAL);
- }
- }
- }
- }
+ // generate an ordered list from the module dependency graph
+ result = Collections.unmodifiableSet(orderedModuleList(minfos));
+ return result;
}
private void buildJDKModules() {
- Set<PlatformModule> modules = new LinkedHashSet<PlatformModule>();
+ Set<PlatformModule> pmodules = new LinkedHashSet<PlatformModule>();
PlatformModule jreToolModule = (PlatformModule)
- Module.findModule(JRE_TOOLS_MODULE);
+ factory.findModule(JRE_TOOLS_MODULE);
+ BootModule bootModule = (BootModule)
+ factory.findModule(BOOT_MODULE);
+ PlatformModule jdkModule = (PlatformModule) factory.findModule(JDK_MODULE);
+ PlatformModule jreModule = (PlatformModule) factory.findModule(JRE_MODULE);
- for (Module m : Module.getAllModules()) {
+ for (Module m : factory.getAllModules()) {
if (m.isTopLevel()) {
PlatformModule pm = (PlatformModule) m;
- modules.add(pm);
+ pmodules.add(pm);
}
}
// set exporter
- for (PlatformModule pm : modules) {
+ for (PlatformModule pm : pmodules) {
PlatformModule exporter = pm;
String name = pm.name();
if (name.startsWith("sun.")) {
@@ -152,7 +109,7 @@ public class PlatformModuleBuilder extends ModuleBuilder {
String mainClassName =
pm.mainClass() == null ? null : pm.mainClass().getClassName();
- PlatformModule rm = (PlatformModule) Module.findModule(mn);
+ PlatformModule rm = (PlatformModule) factory.findModule(mn);
if (rm != null) {
if (pm.mainClass() != rm.mainClass()) {
// propagate the main class to its aggregator module
@@ -160,13 +117,8 @@ public class PlatformModuleBuilder extends ModuleBuilder {
}
exporter = rm;
} else if (pm.hasPlatformAPIs()) {
- ModuleConfig config = null;
- try {
- config = new ModuleConfig(mn, mainClassName);
- } catch (IOException ex) {
- throw new RuntimeException(ex);
- }
- exporter = addPlatformModule(config);
+ ModuleConfig config = new ModuleConfig(mn, version, mainClassName);
+ exporter = factory.addPlatformModule(config);
}
if (pm != exporter) {
@@ -176,10 +128,10 @@ public class PlatformModuleBuilder extends ModuleBuilder {
}
// base module to reexport boot module
- bootModule.reexportBy((PlatformModule) Module.findModule(BASE_MODULE));
+ bootModule.reexportBy((PlatformModule) factory.findModule(BASE_MODULE));
- // set up the jdk, jdk.jre and jdk.legacy modules
- for (Module m : Module.getAllModules()) {
+ // set up the jdk and jdk.jre modules
+ for (Module m : factory.getAllModules()) {
if (m.isTopLevel()) {
PlatformModule pm = (PlatformModule) m;
String name = pm.name();
@@ -187,61 +139,146 @@ public class PlatformModuleBuilder extends ModuleBuilder {
if (pm != jdkModule && pm != jreModule) {
Module exp = pm.exporter(jdkModule);
// the "jdk" module requires all platform modules (public ones)
- jdkModule.config().export(exp);
+ jdkModule.config().reexportModule(exp);
if (pm.isBootConnected() || pm == jreToolModule) {
// add all modules that are strongly connected to jdk.boot to JRE
- jreModule.config().export(exp);
+ jreModule.config().reexportModule(exp);
}
}
}
}
}
-
}
/*
* Returns an ordered list of platform modules according to
* their dependencies with jdk.boot always be the first.
*/
- @Override
- public Set<Module> getModules() {
- Set<Module> modules = new LinkedHashSet<Module>();
- // put the boot module first
- modules.add(bootModule);
- Module base = Module.findModule(BASE_MODULE);
- modules.addAll(base.getModuleInfo().dependences(
- new Dependence.Filter() {
- @Override
- public boolean accept(Dependence d) {
- return !d.isOptional();
- }
- }));
- modules.addAll(jdkModule.getModuleInfo().dependences(null));
- for (Module m : Module.getAllModules()) {
- if (m.isTopLevel() && !modules.contains(m)) {
- modules.addAll(m.getModuleInfo().dependences(null));
+ private Set<Module> orderedModuleList(Collection<ModuleInfo> minfos) {
+ Set<Module> visited = new TreeSet<Module>();
+ Set<Module> orderedList = new LinkedHashSet<Module>();
+ Dependence.Filter filter = new Dependence.Filter() {
+
+ @Override
+ public boolean accept(Dependence d) {
+ return !d.isOptional();
}
+ };
+
+ BootModule bootModule = (BootModule)
+ factory.findModule(BOOT_MODULE);
+
+ // put the boot module first
+ visited.add(bootModule);
+ orderedList.add(bootModule);
+ factory.findModule(BASE_MODULE).getModuleInfo().visitDependence(filter, visited, orderedList);
+ factory.findModule(JDK_MODULE).getModuleInfo().visitDependence(filter, visited, orderedList);
+ for (ModuleInfo mi : minfos) {
+ mi.visitDependence(filter, visited, orderedList);
}
- return modules;
+
+ return orderedList;
}
- void readNonCorePackagesFrom(String nonCorePkgsFile) throws IOException {
- PlatformPackage.addNonCorePkgs(nonCorePkgsFile);
+ @Override
+ protected ModuleInfo buildModuleInfo(Module m) {
+ ModuleInfo mi = super.buildModuleInfo(m);
+
+ // use the module's exporter in the dependence
+ Set<Dependence> depset = new TreeSet<Dependence>();
+ for (Dependence d : mi.requires()) {
+ Dependence dep = d;
+ if (!d.isInternal() && !d.isLocal()) {
+ Module exp = ((PlatformModule)d.getModule()).exporter(m);
+ if (exp == null) {
+ throw new RuntimeException(d.getModule() + " null exporter");
+ }
+ if (d.getModule() != exp && exp != m) {
+ dep = new Dependence(exp, d.modifiers());
+ }
+ }
+
+ // ## not to include optional dependences in jdk.boot
+ // ## should move this to jdk.base
+ if (m instanceof PlatformModuleBuilder.BootModule && d.isOptional()) {
+ continue;
+ }
+ depset.add(dep);
+
+ }
+
+ // return a new ModuleInfo with patched dependences
+ return new ModuleInfo(m, depset, mi.permits());
}
- private PlatformModule addPlatformModule(ModuleConfig config) {
- PlatformModule m;
- if (config.module.equals(BOOT_MODULE)) {
- bootModule = new BootModule(config);
- m = bootModule;
- } else {
- m = new PlatformModule(config);
+ static class PlatformFactory extends Factory {
+ /**
+ * Platform modules that must be defined in the modules.properties
+ */
+ static final String BOOT_MODULE =
+ getValue("platform.boot.module");
+ static final String BASE_MODULE =
+ getValue("platform.base.module");
+ static final String JDK_MODULE =
+ getValue("platform.jdk.module");
+ static final String JRE_MODULE =
+ getValue("platform.jre.module");
+ static final String JRE_TOOLS_MODULE =
+ getValue("platform.jre.tools.module");
+
+ static String getValue(String key) {
+ String value = Module.getModuleProperty(key);
+ if (value == null || value.isEmpty()) {
+ throw new RuntimeException("Null or empty module property: " + key);
+ }
+ return value;
+ }
+
+ PlatformFactory(List<String> configs, String version) throws IOException {
+ Module.setBaseModule(BASE_MODULE);
+
+ // create modules based on the input config files
+ List<ModuleConfig> mconfigs = new ArrayList<ModuleConfig>();
+ for (String file : configs) {
+ mconfigs.addAll(ModuleConfig.readConfigurationFile(file, version));
+ }
+ init(mconfigs);
+
+ // Create the full jdk and jre modules
+ addModule(new NoClassModule(JDK_MODULE, version));
+ addModule(new NoClassModule(JRE_MODULE, version));
+ }
+
+ @Override
+ public Module newModule(String name, String version) {
+ return newPlatformModule(new ModuleConfig(name, version));
+ }
+
+ @Override
+ public Module newModule(ModuleConfig config) {
+ return newPlatformModule(config);
+ }
+
+ private PlatformModule newPlatformModule(ModuleConfig config) {
+ if (config.module.equals(BOOT_MODULE)) {
+ return new BootModule(config);
+ } else {
+ return new PlatformModule(config);
+ }
+ }
+
+ PlatformModule addPlatformModule(String name, String version) {
+ return addPlatformModule(new ModuleConfig(name, version));
+ }
+
+ PlatformModule addPlatformModule(ModuleConfig config) {
+ PlatformModule m = newPlatformModule(config);
+ addModule(m);
+ return m;
}
- Module.addModule(m);
- return m;
}
- public class PlatformModule extends Module {
+ static class PlatformModule extends Module {
private Module exporter; // module that reexports this platform module
public PlatformModule(ModuleConfig config) {
super(config);
@@ -255,34 +292,32 @@ public class PlatformModuleBuilder extends ModuleBuilder {
void setMainClass(String classname) {
String mn = name();
if (!mn.startsWith("jdk") || !isEmpty()) {
- throw new RuntimeException("module " + name() +
- " not an aggregator");
+ throw new RuntimeException("module " + name()
+ + " not an aggregator");
}
- if (classname == null)
+ if (classname == null) {
throw new RuntimeException("Null main class for module " + name());
+ }
mainClassName = classname;
}
- @Override
- boolean allowEmpty() {
- return this == jdkModule || this == jreModule || super.allowEmpty();
- }
-
// requires local for JRE modules that are strongly
// connected with the boot module
boolean isBootConnected() {
// ## should it check for local?
- return config().requires.containsKey(BOOT_MODULE);
+ Dependence d = config().requires.get(BOOT_MODULE);
+ return d != null; // && d.isLocal());
}
-
private int platformAPIs;
+
boolean hasPlatformAPIs() {
platformAPIs = 0;
Visitor<Void, PlatformModule> v = new Visitor<Void, PlatformModule>() {
+
public Void visitClass(Klass k, PlatformModule pm) {
- if (PlatformPackage.isOfficialClass(k.getClassName())) {
+ if (PackageInfo.isExportedPackage(k.getPackageName())) {
pm.platformAPIs++;
}
return null;
@@ -299,8 +334,7 @@ public class PlatformModuleBuilder extends ModuleBuilder {
// returns the module that is used by the requires statement
// in other module's module-info
- @Override
- public Module exporter(Module from) {
+ Module exporter(Module from) {
PlatformModule pm = (PlatformModule) from;
if (pm.isBootConnected()) {
// If it's a local module requiring jdk.boot, retain
@@ -317,11 +351,11 @@ public class PlatformModuleBuilder extends ModuleBuilder {
// sun.<m> permits jdk.<m>
this.config().addPermit(pm);
// jdk.<m> requires public sun.<m>;
- pm.config().export(this);
+ pm.config().reexportModule(this);
}
}
- public class BootModule extends PlatformModule {
+ static class BootModule extends PlatformModule {
BootModule(ModuleConfig config) {
super(config);
}
@@ -331,77 +365,14 @@ public class PlatformModuleBuilder extends ModuleBuilder {
return true;
}
}
-
- static class PlatformPackage {
-
- private static String[] corePkgs = new String[]{
- "java", "javax",
- "org.omg", "org.w3c.dom",
- "org.xml.sax", "org.ietf.jgss"
- };
- private static Set<String> nonCorePkgs = new TreeSet<String>();
-
- static boolean isOfficialClass(String classname) {
- for (String pkg : corePkgs) {
- if (classname.startsWith(pkg + ".")) {
- return true;
- }
- }
-
- // TODO: include later
- /*
- for (String pkg : nonCorePkgs) {
- if (classname.startsWith(pkg + ".")) {
- return true;
- }
- }
- */
- return false;
+ static class NoClassModule extends PlatformModule {
+ NoClassModule(String name, String version) {
+ super(new ModuleConfig(name, version));
}
- // process a properties file listing the non core packages
- static void addNonCorePkgs(String file) throws IOException {
- File f = new File(file);
- Properties props = new Properties();
- BufferedReader reader = null;
-
- try {
- reader = new BufferedReader(new FileReader(f));
- props.load(reader);
- String s = props.getProperty("NON_CORE_PKGS");
- String[] ss = s.split("\\s+");
- Deque<String> values = new LinkedList<String>();
-
- for (String v : ss) {
- values.add(v.trim());
- }
-
- String pval;
- while ((pval = values.poll()) != null) {
- if (pval.startsWith("$(") && pval.endsWith(")")) {
- String key = pval.substring(2, pval.length() - 1);
- String value = props.getProperty(key);
- if (value == null) {
- throw new RuntimeException("key " + key + " not found");
- }
- ss = value.split("\\s+");
- for (String v : ss) {
- values.add(v.trim());
- }
- continue;
- }
- if (pval.startsWith("java.") || pval.startsWith("javax")
- || pval.startsWith("com.") || pval.startsWith("org.")) {
- nonCorePkgs.add(pval);
- } else {
- throw new RuntimeException("Invalid non core package: " + pval);
- }
- }
- } finally {
- if (reader != null) {
- reader.close();
- }
- }
+ @Override
+ boolean allowEmpty() {
+ return true;
}
}
}
diff --git a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ResourceFile.java b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ResourceFile.java
index caef018..e874365 100644
--- a/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ResourceFile.java
+++ b/jdk/make/tools/classanalyzer/src/com/sun/classanalyzer/ResourceFile.java
@@ -40,12 +40,18 @@ import java.util.TreeSet;
*/
public class ResourceFile implements Comparable<ResourceFile> {
private final String pathname;
+ private final long filesize;
protected final String name;
private Module module;
ResourceFile(String fname) {
+ this(fname, 0);
+ }
+
+ ResourceFile(String fname, long size) {
this.pathname = fname.replace('/', File.separatorChar);
this.name = fname.replace(File.separatorChar, '/');
+ this.filesize = size;
}
Module getModule() {
@@ -67,6 +73,10 @@ public class ResourceFile implements Comparable<ResourceFile> {
return pathname;
}
+ long getFileSize() {
+ return filesize;
+ }
+
@Override
public String toString() {
return name;
@@ -80,6 +90,7 @@ public class ResourceFile implements Comparable<ResourceFile> {
static Set<ResourceFile> resources = new TreeSet<ResourceFile>();
static boolean isResource(String pathname) {
+ // skip these files
String name = pathname.replace(File.separatorChar, '/');
if (name.endsWith("META-INF/MANIFEST.MF")) {
return false;
@@ -87,20 +98,22 @@ public class ResourceFile implements Comparable<ResourceFile> {
if (name.contains("META-INF/JCE_RSA.")) {
return false;
}
- if (name.contains("META-INF/ORACLE_J.")) {
+ if (name.contains("META-INF/") &&
+ (name.endsWith(".RSA") || name.endsWith(".SF"))) {
return false;
}
+
return true;
}
- static ResourceFile addResource(String fname, InputStream in) {
+ static ResourceFile addResource(String fname, InputStream in, long size) {
ResourceFile res;
fname = fname.replace(File.separatorChar, '/');
if (fname.startsWith("META-INF/services")) {
- res = new ServiceProviderConfigFile(fname, in);
+ res = new ServiceProviderConfigFile(fname, in, size);
} else {
- res = new ResourceFile(fname);
+ res = new ResourceFile(fname, size);
}
resources.add(res);
return res;
@@ -113,8 +126,13 @@ public class ResourceFile implements Comparable<ResourceFile> {
static class ServiceProviderConfigFile extends ResourceFile {
final List<String> providers = new ArrayList<String>();
final String service;
+
ServiceProviderConfigFile(String fname, InputStream in) {
- super(fname);
+ this(fname, in, 0);
+ }
+
+ ServiceProviderConfigFile(String fname, InputStream in, long size) {
+ super(fname, size);
readServiceConfiguration(in, providers);
this.service = name.substring("META-INF/services".length() + 1, name.length());
}
diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java
index c0dd63b..6342acc 100644
--- a/jdk/src/share/classes/java/lang/Class.java
+++ b/jdk/src/share/classes/java/lang/Class.java
@@ -25,6 +25,9 @@
package java.lang;
+import java.lang.annotation.Annotation;
+import java.lang.module.ModuleClassLoader;
+import java.lang.module.ModuleNotPresentException;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Member;
@@ -49,6 +52,7 @@ import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
+import org.openjdk.jigsaw.BootLoader;
import sun.misc.Unsafe;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
@@ -60,7 +64,6 @@ import sun.reflect.generics.repository.MethodRepository;
import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
-import java.lang.annotation.Annotation;
import sun.reflect.annotation.*;
/**
@@ -602,8 +605,15 @@ public final class Class<T>
*/
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
- if (cl == null)
+ if (cl == null) {
+ // ## Should return the boot loader when running in module mode
+ // ## but this would impact many places in the JDK that checks
+ // ## for null class loader for bootclasspath. Also need to
+ // ## carefully deal with bootstrapping. BootLoader is not
+ // ## created until a system class is loaded by the libs (not VM).
+ //
return null;
+ }
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader();
@@ -617,7 +627,6 @@ public final class Class<T>
// Package-private to allow ClassLoader access
native ClassLoader getClassLoader0();
-
/**
* Returns an array of {@code TypeVariable} objects that represent the
* type variables declared by the generic declaration represented by this
@@ -3121,7 +3130,7 @@ public final class Class<T>
// Invoked by java.lang.module.ModuleClassLoader
// via sun.misc.JavaLangAccess
- void setModule(Module m) {
+ synchronized void setModule(Module m) {
module = m;
}
@@ -3133,8 +3142,72 @@ public final class Class<T>
* this class, or {@code null} if this class is a member of the
* unnamed module
*/
- public Module getModule() {
+ public synchronized Module getModule() {
+ // For platform classes defined directly by the VM bootstrap
+ // class loader, this module will be null and thus
+ // initialize the module field the first time this method is called.
+ //
+ // ## Should the VM define the Module when loading a Class?
+ //
+ if (module == null) {
+ try {
+ module = BootLoader.getLoader().findModule(this);
+ } catch (java.io.IOException x) {
+ // ## if Module has not been defined, possibly run into
+ // ## I/O error when reading module-info.
+ throw new AssertionError(x);
+ }
+ }
+
return module;
}
+ /**
+ * Tests if a {@linkplain java.lang.reflect.Module module}
+ * of the given name is present in the class loader's context.
+ *
+ * @param mn a module's name
+ * @return {@code true} if the module of the given name is present;
+ * {@code false} otherwise.
+ * @throws UnsupportedOperationException if this class
+ * is loaded by a legacy class loader
+ *
+ * @since 1.8
+ */
+ public boolean isModulePresent(String mn) {
+ ClassLoader cl = getClassLoader();
+ if (cl != null && !(cl instanceof ModuleClassLoader))
+ throw new UnsupportedOperationException("Not supported in legacy class loader");
+
+ ModuleClassLoader mcl = (ModuleClassLoader)cl;
+ if (cl == null)
+ mcl = BootLoader.getLoader();
+
+ // ## Remove the following when legacy mode support is implemented
+ if (mcl == null) {
+ // if not full JRE, ClassNotFoundException will be thrown
+ return true;
+ }
+
+ return mcl.isModulePresent(mn);
+ }
+
+ /**
+ * Checks if a {@linkplain java.lang.reflect.Module module}
+ * of the given name is present in the class loader's context.
+ *
+ * @param mn a module's name
+ * @throws ModuleNotPresentException if the module of the given name
+ * is not present in its class loader's context.
+ * @throws UnsupportedOperationException if the caller's class
+ * is loaded by a legacy class loader
+ *
+ * @since 1.8
+ */
+ public void requireModulePresent(String mn) {
+ if (!isModulePresent(mn)) {
+ throw new ModuleNotPresentException("module " + mn + " not present");
+ }
+ }
+
}
diff --git a/jdk/src/share/classes/java/lang/SecurityManager.java b/jdk/src/share/classes/java/lang/SecurityManager.java
index 27f7d90..f9d03e5 100644
--- a/jdk/src/share/classes/java/lang/SecurityManager.java
+++ b/jdk/src/share/classes/java/lang/SecurityManager.java
@@ -29,7 +29,6 @@ import java.security.*;
import java.io.FileDescriptor;
import java.io.File;
import java.io.FilePermission;
-import java.awt.AWTPermission;
import java.util.PropertyPermission;
import java.lang.RuntimePermission;
import java.net.SocketPermission;
@@ -39,6 +38,8 @@ import java.net.InetAddress;
import java.lang.reflect.Member;
import java.lang.reflect.*;
import java.net.URL;
+import java.lang.module.RequireOptionalModule;
+import java.lang.module.ModuleNotPresentException;
import sun.security.util.SecurityConstants;
@@ -1331,12 +1332,15 @@ class SecurityManager {
* @param window the new window that is being created.
* @return <code>true</code> if the calling thread is trusted to put up
* top-level windows; <code>false</code> otherwise.
- * @exception NullPointerException if the <code>window</code> argument is
- * <code>null</code>.
+ * @throws NullPointerException if the {@code window} argument is
+ * {@code null}.
+ * @throws ModuleNotPresentException if the desktop module is not present.
* @see java.awt.Window
* @see #checkPermission(java.security.Permission) checkPermission
*/
+ @RequireOptionalModule("jdk.desktop")
public boolean checkTopLevelWindow(Object window) {
+ SecurityManager.class.requireModulePresent("jdk.desktop");
if (window == null) {
throw new NullPointerException("window can't be null");
}
@@ -1368,6 +1372,7 @@ class SecurityManager {
* @since JDK1.1
* @see #checkPermission(java.security.Permission) checkPermission
*/
+ @RequireOptionalModule("jdk.desktop")
public void checkPrintJobAccess() {
checkPermission(new RuntimePermission("queuePrintJob"));
}
@@ -1386,11 +1391,14 @@ class SecurityManager {
* exception.
*
* @since JDK1.1
- * @exception SecurityException if the calling thread does not have
+ * @throws SecurityException if the calling thread does not have
* permission to access the system clipboard.
+ * @throws ModuleNotPresentException if the desktop module is not present.
* @see #checkPermission(java.security.Permission) checkPermission
*/
+ @RequireOptionalModule("jdk.desktop")
public void checkSystemClipboardAccess() {
+ SecurityManager.class.requireModulePresent("jdk.desktop");
checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION);
}
@@ -1407,11 +1415,14 @@ class SecurityManager {
* exception.
*
* @since JDK1.1
- * @exception SecurityException if the calling thread does not have
+ * @throws SecurityException if the calling thread does not have
* permission to access the AWT event queue.
+ * @throws ModuleNotPresentException if the desktop module is not present.
* @see #checkPermission(java.security.Permission) checkPermission
*/
+ @RequireOptionalModule("jdk.desktop")
public void checkAwtEventQueueAccess() {
+ SecurityManager.class.requireModulePresent("jdk.desktop");
checkPermission(SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION);
}
diff --git a/jdk/src/share/classes/java/lang/module/ModuleClassLoader.java b/jdk/src/share/classes/java/lang/module/ModuleClassLoader.java
index 4b535e1..a71c345 100644
--- a/jdk/src/share/classes/java/lang/module/ModuleClassLoader.java
+++ b/jdk/src/share/classes/java/lang/module/ModuleClassLoader.java
@@ -31,7 +31,7 @@ import java.security.CodeSource;
import java.security.SecureClassLoader;
import sun.reflect.ReflectionFactory;
-public class ModuleClassLoader
+public abstract class ModuleClassLoader
extends SecureClassLoader
{
@@ -74,4 +74,30 @@ public class ModuleClassLoader
throw new ClassNotFoundException(name);
}
+ /**
+ * Tests if a {@linkplain java.lang.reflect.Module module}
+ * of the given name is present in this module loader's context.
+ *
+ * @param mn a module's name
+ * @return {@code true} if the module of the given name is present;
+ * {@code false} otherwise.
+ */
+ public boolean isModulePresent(String mn) {
+ return ((org.openjdk.jigsaw.Loader)this).isModulePresent(mn);
+ }
+
+ /**
+ * Checks if a {@linkplain java.lang.reflect.Module module}
+ * of the given name is present in this module loader's context.
+ *
+ * @param mn a module's name
+ * @throws ModuleNotPresentException if the module of the given name
+ * is not present in this module class loader's context.
+ */
+ public void requireModulePresent(String mn) {
+ if (!isModulePresent(mn)) {
+ throw new ModuleNotPresentException("module " + mn + " not present");
+ }
+ }
+
}
diff --git a/jdk/src/share/classes/java/lang/module/ModuleNotPresentException.java b/jdk/src/share/classes/java/lang/module/ModuleNotPresentException.java
new file mode 100644
index 0000000..003518a
--- /dev/null
+++ b/jdk/src/share/classes/java/lang/module/ModuleNotPresentException.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 java.lang.module;
+
+/**
+ * Thrown when a module is not present in a {@linkplain ModuleClassLoader
+ * module class loader}'s context.
+ */
+public class ModuleNotPresentException extends RuntimeException {
+ private static final long serialVersionUID = 6548519553178935875L;
+
+ /**
+ * Constructs a {@code ModuleNotPresentException} with no
+ * detail message.
+ */
+ public ModuleNotPresentException() {
+ super();
+ }
+
+ /**
+ * Constructs a {@code ModuleNotPresentException} with the
+ * specified detail message.
+ *
+ * @param message the detail message.
+ */
+ public ModuleNotPresentException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a {@code ModuleNotPresentException} with the
+ * specified detail message and cause.
+ *
+ * @param message the detail message.
+ * @param cause the cause.
+ */
+ public ModuleNotPresentException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a {@code ModuleNotPresentException} with the
+ * specified cause.
+ *
+ * @param cause the cause.
+ */
+ public ModuleNotPresentException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/jdk/src/share/classes/java/lang/module/RequireOptionalModule.java b/jdk/src/share/classes/java/lang/module/RequireOptionalModule.java
new file mode 100644
index 0000000..12155f0
--- /dev/null
+++ b/jdk/src/share/classes/java/lang/module/RequireOptionalModule.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 java.lang.module;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * Indicates that the annotated element requires the named modules be
+ * presented when being referenced.
+ *
+ * @see ModuleNotPresentException
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Documented @Target({TYPE, METHOD, CONSTRUCTOR})
+public @interface RequireOptionalModule {
+ /**
+ * The set of modules required by the annotated method.
+ */
+ String[] value();
+}
diff --git a/jdk/src/share/classes/java/lang/module/UnsupportedElementTypeException.java b/jdk/src/share/classes/java/lang/module/UnsupportedElementTypeException.java
index 8041468..b781af7 100644
--- a/jdk/src/share/classes/java/lang/module/UnsupportedElementTypeException.java
+++ b/jdk/src/share/classes/java/lang/module/UnsupportedElementTypeException.java
@@ -47,7 +47,7 @@ public class UnsupportedElementTypeException extends RuntimeException {
/**
* Constructs a new UnsupportedElementTypeException.
*
- * @param classnames a list of fully-qualified class name
+ * @param classname a fully-qualified class name
* specified in the element being accessed.
*/
public UnsupportedElementTypeException(String classname) {
diff --git a/jdk/src/share/classes/java/util/Properties.java b/jdk/src/share/classes/java/util/Properties.java
index d27e608..6b6f0d1 100644
--- a/jdk/src/share/classes/java/util/Properties.java
+++ b/jdk/src/share/classes/java/util/Properties.java
@@ -34,6 +34,8 @@ import java.io.Reader;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
+import java.lang.module.RequireOptionalModule;
+import java.lang.module.ModuleNotPresentException;
/**
* The <code>Properties</code> class represents a persistent set of
@@ -857,12 +859,16 @@ class Properties extends Hashtable<Object,Object> {
* @throws InvalidPropertiesFormatException Data on input stream does not
* constitute a valid XML document with the mandated document type.
* @throws NullPointerException if <code>in</code> is null.
+ * @throws ModuleNotPresentException if XML module is not present.
* @see #storeToXML(OutputStream, String, String)
* @since 1.5
*/
+ @RequireOptionalModule("jdk.jaxp")
public synchronized void loadFromXML(InputStream in)
throws IOException, InvalidPropertiesFormatException
{
+ Properties.class.requireModulePresent("jdk.jaxp");
+
if (in == null)
throw new NullPointerException();
XMLUtils.load(this, in);
@@ -886,12 +892,16 @@ class Properties extends Hashtable<Object,Object> {
* @throws ClassCastException if this <code>Properties</code> object
* contains any keys or values that are not
* <code>Strings</code>.
+ * @throws ModuleNotPresentException if XML module is not present.
* @see #loadFromXML(InputStream)
* @since 1.5
*/
+ @RequireOptionalModule("jdk.jaxp")
public void storeToXML(OutputStream os, String comment)
throws IOException
{
+ Properties.class.requireModulePresent("jdk.jaxp");
+
if (os == null)
throw new NullPointerException();
storeToXML(os, comment, "UTF-8");
@@ -925,12 +935,16 @@ class Properties extends Hashtable<Object,Object> {
* @throws ClassCastException if this <code>Properties</code> object
* contains any keys or values that are not
* <code>Strings</code>.
+ * @throws ModuleNotPresentException if XML module is not present.
* @see #loadFromXML(InputStream)
* @since 1.5
*/
+ @RequireOptionalModule("jdk.jaxp")
public void storeToXML(OutputStream os, String comment, String encoding)
throws IOException
{
+ Properties.class.requireModulePresent("jdk.jaxp");
+
if (os == null)
throw new NullPointerException();
XMLUtils.save(this, os, comment, encoding);
diff --git a/jdk/src/share/classes/java/util/jar/JarFile.java b/jdk/src/share/classes/java/util/jar/JarFile.java
index 79d0f84..2634adb 100644
--- a/jdk/src/share/classes/java/util/jar/JarFile.java
+++ b/jdk/src/share/classes/java/util/jar/JarFile.java
@@ -26,6 +26,8 @@
package java.util.jar;
import java.io.*;
+import java.lang.module.ModuleInfo;
+import java.lang.module.ModuleSystem;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.*;
@@ -44,8 +46,10 @@ import sun.misc.SharedSecrets;
* It extends the class <code>java.util.zip.ZipFile</code> with support
* for reading an optional <code>Manifest</code> entry. The
* <code>Manifest</code> can be used to specify meta-information about the
- * jar file and its entries.
- *
+ * jar file and its entries. A jar file with a {@link
+ * #MODULEINFO_NAME module-info.class} entry is a modular jar file
+ * that can be installed as a module in a module library.
+ *
* <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
* or method in this class will cause a {@link NullPointerException} to be
* thrown.
@@ -77,6 +81,12 @@ class JarFile extends ZipFile {
public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
/**
+ * The module definition file name in a modular JAR file.
+ * @since 1.8
+ */
+ public static final String MODULEINFO_NAME = "module-info.class";
+
+ /**
* Creates a new <code>JarFile</code> to read from the specified
* file <code>name</code>. The <code>JarFile</code> will be verified if
* it is signed.
@@ -192,6 +202,25 @@ class JarFile extends ZipFile {
private native String[] getMetaInfEntryNames();
/**
+ * Returns the {@code ModuleInfo}, or {@code null} if none.
+ *
+ * @return the {@code ModuleInfo}, or {@code null} if none
+ *
+ * @throws IllegalStateException
+ * may be thrown if the jar file has been closed
+ *
+ * @since 1.8
+ */
+ public ModuleInfo getModuleInfo() throws IOException {
+ JarEntry je = getJarEntry(MODULEINFO_NAME);
+ if (je == null)
+ return null;
+
+ byte[] bs = getBytes(je);
+ return ModuleSystem.base().parseModuleInfo(bs);
+ }
+
+ /**
* Returns the <code>JarEntry</code> for the given entry name or
* <code>null</code> if not found.
*
diff --git a/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java b/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java
index f4a7e5e..d74ce64 100644
--- a/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java
+++ b/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java
@@ -34,6 +34,8 @@ import java.lang.Integer;
import java.lang.Long;
import java.lang.Float;
import java.lang.Double;
+import java.lang.module.RequireOptionalModule;
+import java.lang.module.ModuleNotPresentException;
/**
* This class provides a skeletal implementation of the {@link Preferences}
@@ -1588,10 +1590,13 @@ public abstract class AbstractPreferences extends Preferences {
* results in an <tt>IOException</tt>.
* @throws BackingStoreException if preference data cannot be read from
* backing store.
+ * @throws ModuleNotPresentException if XML module is not present.
*/
+ @RequireOptionalModule("jdk.jaxp")
public void exportNode(OutputStream os)
throws IOException, BackingStoreException
{
+ AbstractPreferences.class.requireModulePresent("jdk.jaxp");
XmlSupport.export(os, this, false);
}
@@ -1604,10 +1609,13 @@ public abstract class AbstractPreferences extends Preferences {
* results in an <tt>IOException</tt>.
* @throws BackingStoreException if preference data cannot be read from
* backing store.
+ * @throws ModuleNotPresentException if XML module is not present.
*/
+ @RequireOptionalModule("jdk.jaxp")
public void exportSubtree(OutputStream os)
throws IOException, BackingStoreException
{
+ AbstractPreferences.class.requireModulePresent("jdk.jaxp");
XmlSupport.export(os, this, true);
}
}
diff --git a/jdk/src/share/classes/java/util/prefs/Preferences.java b/jdk/src/share/classes/java/util/prefs/Preferences.java
index 9446183..8a3fce2 100644
--- a/jdk/src/share/classes/java/util/prefs/Preferences.java
+++ b/jdk/src/share/classes/java/util/prefs/Preferences.java
@@ -42,6 +42,9 @@ import java.lang.Long;
import java.lang.Float;
import java.lang.Double;
+import java.lang.module.RequireOptionalModule;
+import java.lang.module.ModuleNotPresentException;
+
/**
* A node in a hierarchical collection of preference data. This class
* allows applications to store and retrieve user and system
@@ -1246,11 +1249,14 @@ public abstract class Preferences {
* constitute a valid XML document with the mandated document type.
* @throws SecurityException If a security manager is present and
* it denies <tt>RuntimePermission("preferences")</tt>.
+ * @throws ModuleNotPresentException if XML module is not present.
* @see RuntimePermission
*/
+ @RequireOptionalModule("jdk.jaxp")
public static void importPreferences(InputStream is)
throws IOException, InvalidPreferencesFormatException
{
+ Preferences.class.isModulePresent("jdk.jaxp");
XmlSupport.importPreferences(is);
}
}
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/BootLoader.java b/jdk/src/share/classes/org/openjdk/jigsaw/BootLoader.java
index 02661ad..209839b 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/BootLoader.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/BootLoader.java
@@ -52,7 +52,7 @@ public final class BootLoader // ## TEMPORARY should be package-private
extendBootPath0(path.getPath());
}
- BootLoader(LoaderPool lp, Context cx) {
+ private BootLoader(LoaderPool lp, Context cx) {
super(lp, cx);
// Add the rest of the boot context's modules
@@ -82,7 +82,41 @@ public final class BootLoader // ## TEMPORARY should be package-private
Class<?> c = findBootClass(cn);
if (tracing)
trace(0, "%s: found %s:%s (boot)", this, mid, cn);
+
+ sun.misc.SharedSecrets.getJavaLangAccess().setModule(c, m);
return c;
}
+ private static BootLoader bootLoader;
+ static BootLoader newLoader(LoaderPool p, Context cx) {
+ if (bootLoader != null)
+ throw new AssertionError("Not supporting multiple LoaderPool yet");
+
+ bootLoader = new BootLoader(p, cx);
+ return bootLoader;
+ }
+
+ public static BootLoader getLoader() {
+ if (bootLoader == null)
+ throw new AssertionError("BootLoader not initialized: booted=" +
+ sun.misc.VM.isBooted());
+ return bootLoader;
+ }
+
+ /**
+ * Returns the Module for the given class loaded by the VM
+ * bootstrap class loader.
+ */
+ public Module findModule(Class<?> c) throws IOException {
+ Context cx = context;
+ ModuleId mid = cx.findModuleForLocalClass(c.getName());
+ if (mid == null)
+ return null;
+
+ // Find the library from which we'll load the class
+ //
+ Library lib = bootLoader.pool.library(cx, mid);
+ return findModule(lib, mid);
+ }
+
}
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/Context.java b/jdk/src/share/classes/org/openjdk/jigsaw/Context.java
index b35786c..df77529 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/Context.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/Context.java
@@ -153,6 +153,25 @@ public class Context
return Collections.unmodifiableSet(contextForRemotePackage.keySet());
}
+ // Suppliers (i.e. remote contexts)
+ //
+ private Set<String> suppliers = new HashSet<String>();
+ protected void addSupplier(String cxn) {
+ suppliers.add(cxn);
+ }
+
+ /**
+ * Return the set of remote contexts (read-only). This includes
+ * contexts supplying remote classes as well as any suppliers
+ * re-exporting remote classes.
+ *
+ * @return this context's remote-context set
+ */
+ public final Set<String> remoteContexts() {
+ return Collections.unmodifiableSet(suppliers);
+ }
+
+
public boolean equals(Object ob) {
if (!(ob instanceof Context))
return false;
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/Launcher.java b/jdk/src/share/classes/org/openjdk/jigsaw/Launcher.java
index 20f7797..5fe1d2d 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/Launcher.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/Launcher.java
@@ -65,7 +65,6 @@ public final class Launcher {
LoaderPool lp = new LoaderPool(lb, cf, cn);
return lp.findLoader(cx);
-
}
public static ClassLoader launch(String midqs) {
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/Linker.java b/jdk/src/share/classes/org/openjdk/jigsaw/Linker.java
index bed109e..4a56cc0 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/Linker.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/Linker.java
@@ -213,6 +213,11 @@ final class Linker {
assert d.modifiers().contains(Modifier.OPTIONAL);
continue;
}
+ if (scx == cx) {
+ // Same context
+ continue;
+ }
+
if (!d.modifiers().contains(Modifier.LOCAL)) {
// Dependence upon some other context
cx.suppliers.add(scx);
@@ -238,8 +243,11 @@ final class Linker {
resolveLocalSuppliers();
resolveRemoteSuppliers();
- // Synchronize the context-for-package maps
+ // Synchronize the supplier-name maps and context-for-package maps
for (Context cx : cxs.contexts) {
+ for (Context scx : cx.suppliers) {
+ cx.addSupplier(scx.name());
+ }
for (Map.Entry<String,Context> me
: cx.contextForPackage.entrySet())
{
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/Loader.java b/jdk/src/share/classes/org/openjdk/jigsaw/Loader.java
index 2ff87c0..33e929b 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/Loader.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/Loader.java
@@ -48,7 +48,7 @@ public class Loader
{
protected final LoaderPool pool;
- private final Context context;
+ protected final Context context;
private final Map<String,Module> moduleForName = new HashMap<>();
@@ -128,10 +128,8 @@ public class Loader
return m;
}
- private ClassNotFoundException cnf(Module m, String cn, IOException x) {
- return m != null
- ? new ClassNotFoundException(m.getName() + ":" + cn, x)
- : new ClassNotFoundException(cn, x);
+ private ClassNotFoundException cnf(String mn, String cn, IOException x) {
+ return new ClassNotFoundException(mn + ":" + cn, x);
}
Class<?> findClass(ModuleId mid, String cn)
@@ -154,51 +152,18 @@ public class Loader
return c;
}
- // Have we defined this class's module yet?
- //
- Module m = moduleForName.get(mid.name());
- if (m != null) {
- if (!m.getModuleId().equals(mid))
- throw new AssertionError("Duplicate module in loader");
- }
-
- // Find the library from which we'll load the class
- //
+ Module m = null;
Library lib = null;
try {
+ // Find the library from which we'll load the class
+ //
lib = pool.library(context, mid);
- } catch (IOException x) {
- ClassNotFoundException cnfx
- = new ClassNotFoundException(mid.name() + ":" + cn);
- cnfx.initCause(x);
- throw cnfx;
- }
- // Define the module
- //
- if (m == null) {
- try {
- final ModuleId modid = mid;
- final Library l = lib;
- m = AccessController.doPrivileged(
- new PrivilegedExceptionAction<Module>() {
- public Module run()
- throws IOException
- {
- byte[] bs = l.readLocalModuleInfoBytes(modid);
- if (bs == null)
- throw new AssertionError();
- CodeSigner[] cs = l.readLocalCodeSigners(modid);
- return defineModule(modid, bs,
- new CodeSource(null, cs));
- }
- }
- );
- if (tracing)
- trace(0, "%s: define %s [%s]", this, mid, lib.name());
- } catch (PrivilegedActionException x) {
- throw cnf(m, cn, (IOException) x.getException());
- }
+ // Find this class's module
+ //
+ m = findModule(lib, mid);
+ } catch (IOException x) {
+ throw cnf(mid.name(), cn, x);
}
// Define the package
@@ -214,12 +179,49 @@ public class Loader
}
// The last step, of actually locating the class, is in a
- // separate method so that the kernel loader can override it
+ // separate method so that the boot loader can override it
//
return finishFindingClass(lib, mid, m, cn);
}
+ Module findModule(Library lib, ModuleId mid) throws IOException {
+ // Have we defined this module yet?
+ //
+ Module m = moduleForName.get(mid.name());
+ if (m != null) {
+ if (!m.getModuleId().equals(mid))
+ throw new AssertionError("Duplicate module in loader");
+ return m;
+ }
+
+ // Define the module
+ //
+ try {
+ final ModuleId modid = mid;
+ final Library l = lib;
+ m = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Module>() {
+ public Module run()
+ throws IOException
+ {
+ byte[] bs = l.readLocalModuleInfoBytes(modid);
+ if (bs == null)
+ throw new AssertionError();
+ CodeSigner[] cs = l.readLocalCodeSigners(modid);
+ return defineModule(modid, bs,
+ new CodeSource(null, cs));
+ }
+ }
+ );
+ if (tracing)
+ trace(0, "%s: define %s [%s]", this, mid, lib.name());
+ } catch (PrivilegedActionException x) {
+ throw (IOException) x.getException();
+ }
+ return m;
+ }
+
Class<?> finishFindingClass(final Library lib, final ModuleId mid,
Module m, final String cn)
throws ClassNotFoundException
@@ -240,11 +242,19 @@ public class Loader
trace(0, "%s: define %s:%s [%s]", this, mid, cn, lib.name());
return c;
} catch (PrivilegedActionException x) {
- throw cnf(m, cn, (IOException) x.getException());
+ throw cnf(m.getName(), cn, (IOException) x.getException());
}
}
+ public boolean isModulePresent(String mn) {
+ Context cx = pool.config().findContextForModuleName(mn);
+ if (cx == null) return false;
+
+ return cx == context ||
+ context.remoteContexts().contains(cx.name());
+ }
+
public String toString() {
return context.name();
}
@@ -371,7 +381,6 @@ public class Loader
return Collections.enumeration(us);
}
-
// -- Stubs for methods not yet re-implemented --
/* ## Can't do this -- CL.getParent is final
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/LoaderPool.java b/jdk/src/share/classes/org/openjdk/jigsaw/LoaderPool.java
index dd0ff4d..2ab4f33 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/LoaderPool.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/LoaderPool.java
@@ -94,7 +94,7 @@ public final class LoaderPool {
ld = AccessController.doPrivileged(new PrivilegedAction<Loader>() {
public Loader run() {
if (Platform.isBootContext(cx)) {
- return new BootLoader(LoaderPool.this, cx);
+ return BootLoader.newLoader(LoaderPool.this, cx);
} else {
return new Loader(LoaderPool.this, cx);
}
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/PathLinker.java b/jdk/src/share/classes/org/openjdk/jigsaw/PathLinker.java
index 8d2dc73..9cd9c7a 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/PathLinker.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/PathLinker.java
@@ -153,6 +153,10 @@ final class PathLinker {
assert d.modifiers().contains(Modifier.OPTIONAL);
continue;
}
+ if (scx == cx) {
+ // Same context
+ continue;
+ }
if (!d.modifiers().contains(Modifier.LOCAL)) {
// Dependence upon some other context
if (tracing)
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java b/jdk/src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java
index 31fba65..b31878e 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java
@@ -382,6 +382,11 @@ public final class SimpleLibrary
out.writeUTF(me.getKey());
out.writeUTF(me.getValue());
}
+ // Suppliers
+ out.writeInt(cx.remoteContexts().size());
+ for (String cxn : cx.remoteContexts()) {
+ out.writeUTF(cxn);
+ }
}
}
@@ -418,6 +423,11 @@ public final class SimpleLibrary
int nPackages = in.readInt();
for (int j = 0; j < nPackages; j++)
cx.putContextForRemotePackage(in.readUTF(), in.readUTF());
+
+ // Suppliers
+ int nSuppliers = in.readInt();
+ for (int j = 0; j < nSuppliers; j++)
+ cx.addSupplier(in.readUTF());
}
}
@@ -947,34 +957,15 @@ public final class SimpleLibrary
}
}
- private byte[] readModuleInfoBytes(JarFile jf)
- throws IOException
- {
- JarEntry je = jf.getJarEntry("META-INF/module-info.class");
- if (je == null)
- return null;
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try (InputStream is = jf.getInputStream(je)) {
- byte[] bs = new byte[1024];
- int cc = 0;
- while ((cc = is.read(bs)) > 0) {
- baos.write(bs, 0, cc);
- }
- }
- return baos.toByteArray();
- }
-
private ModuleId installFromJarFile(File mf, boolean verifySignature)
throws ConfigurationException, IOException, SignatureException
{
File md = null;
try (JarFile jf = new JarFile(mf, verifySignature)) {
- byte[] mib = readModuleInfoBytes(jf);
- if (mib == null)
+ ModuleInfo mi = jf.getModuleInfo();
+ if (mi == null)
throw new ConfigurationException(mf + ": not a modular JAR file");
- ModuleInfo mi = jms.parseModuleInfo(mib);
md = moduleDir(mi.id());
ModuleId mid = mi.id();
if (md.exists())
@@ -982,8 +973,6 @@ public final class SimpleLibrary
if (!md.mkdirs())
throw new IOException(md + ": Cannot create");
- Files.store(mib, new File(md, "info"));
-
boolean signed = false;
// copy the jar file to the module library in STORED compression
@@ -997,7 +986,11 @@ public final class SimpleLibrary
while (entries.hasMoreElements()) {
JarEntry je = entries.nextElement();
try (InputStream is = jf.getInputStream(je)) {
- writeJarEntry(is, je, jos);
+ if (je.getName().equals(JarFile.MODULEINFO_NAME)) {
+ java.nio.file.Files.copy(is, md.toPath().resolve("info"));
+ } else {
+ writeJarEntry(is, je, jos);
+ }
}
if (!signed) {
String name = je.getName().toUpperCase(Locale.ENGLISH);
diff --git a/jdk/src/share/classes/sun/tools/jar/Main.java b/jdk/src/share/classes/sun/tools/jar/Main.java
index 486b193..a1c88ec 100644
--- a/jdk/src/share/classes/sun/tools/jar/Main.java
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java
@@ -25,6 +25,7 @@
package sun.tools.jar;
+import java.lang.module.ModuleId;
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Files;
@@ -36,6 +37,7 @@ import java.text.MessageFormat;
import sun.misc.JarIndex;
import static sun.misc.JarIndex.INDEX_NAME;
import static java.util.jar.JarFile.MANIFEST_NAME;
+import static java.util.jar.JarFile.MODULEINFO_NAME;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
@@ -49,6 +51,7 @@ class Main {
PrintStream out, err;
String fname, mname, ename;
String zname = "";
+ String moduleid;
String[] files;
String rootjar = null;
@@ -107,18 +110,8 @@ class Main {
}
}
- private String formatMsg(String key, String arg) {
+ private String formatMsg(String key, String... args) {
String msg = getMsg(key);
- String[] args = new String[1];
- args[0] = arg;
- return MessageFormat.format(msg, (Object[]) args);
- }
-
- private String formatMsg2(String key, String arg, String arg1) {
- String msg = getMsg(key);
- String[] args = new String[2];
- args[0] = arg;
- args[1] = arg1;
return MessageFormat.format(msg, (Object[]) args);
}
@@ -164,6 +157,7 @@ class Main {
}
if (cflag) {
Manifest manifest = null;
+ ModuleInfo minfo = null;
InputStream in = null;
if (!Mflag) {
@@ -198,7 +192,25 @@ class Main {
}
}
expand(null, files, false);
- create(new BufferedOutputStream(out, 4096), manifest);
+
+ if (moduleid != null) {
+ // check if module-info.class exists
+ for (File f : entries) {
+ if (f.getName().equals(MODULEINFO_NAME)) {
+ error(getMsg("error.bad.moduleid"));
+ if (in != null) {
+ in.close();
+ }
+ out.close();
+ return false;
+ }
+ }
+ minfo = new ModuleInfo(moduleid, getMainClass(manifest));
+ if (manifest != null) {
+ addModuleRequires(minfo, getClassPath(manifest));
+ }
+ }
+ create(new BufferedOutputStream(out, 4096), manifest, minfo);
if (in != null) {
in.close();
}
@@ -217,6 +229,7 @@ class Main {
out = new FileOutputStream(FileDescriptor.out);
vflag = false;
}
+
InputStream manifest = (!Mflag && (mname != null)) ?
(new FileInputStream(mname)) : null;
expand(null, files, true);
@@ -231,11 +244,13 @@ class Main {
manifest.close();
}
if (fname != null) {
- // on Win32, we need this delete
- inputFile.delete();
- if (!tmpFile.renameTo(inputFile)) {
- tmpFile.delete();
- throw new IOException(getMsg("error.write.file"));
+ if (ok) {
+ // on Win32, we need this delete
+ inputFile.delete();
+ if (!tmpFile.renameTo(inputFile)) {
+ tmpFile.delete();
+ throw new IOException(getMsg("error.write.file"));
+ }
}
tmpFile.delete();
}
@@ -359,8 +374,11 @@ class Main {
iflag = true;
break;
case 'e':
- ename = args[count++];
- break;
+ ename = args[count++];
+ break;
+ case 'I':
+ moduleid = args[count++];
+ break;
default:
error(formatMsg("error.illegal.option",
String.valueOf(flags.charAt(i))));
@@ -410,7 +428,7 @@ class Main {
usageError();
return false;
} else if (uflag) {
- if ((mname != null) || (ename != null)) {
+ if ((mname != null) || (ename != null) || (moduleid != null)) {
/* just want to update the manifest */
return true;
} else {
@@ -462,7 +480,7 @@ class Main {
/**
* Creates a new JAR file.
*/
- void create(OutputStream out, Manifest manifest)
+ void create(OutputStream out, Manifest manifest, ModuleInfo minfo)
throws IOException
{
ZipOutputStream zos = new JarOutputStream(out);
@@ -470,29 +488,69 @@ class Main {
zos.setMethod(ZipOutputStream.STORED);
}
if (manifest != null) {
- if (vflag) {
- output(getMsg("out.added.manifest"));
- }
ZipEntry e = new ZipEntry(MANIFEST_DIR);
e.setTime(System.currentTimeMillis());
e.setSize(0);
e.setCrc(0);
zos.putNextEntry(e);
- e = new ZipEntry(MANIFEST_NAME);
- e.setTime(System.currentTimeMillis());
- if (flag0) {
- crc32Manifest(e, manifest);
- }
- zos.putNextEntry(e);
- manifest.write(zos);
zos.closeEntry();
}
+ if (manifest != null) {
+ if (vflag) {
+ output(getMsg("out.added.manifest"));
+ }
+ writeManifest(manifest, zos, System.currentTimeMillis());
+ }
+ if (minfo != null) {
+ if (vflag) {
+ output(getMsg("out.added.moduleinfo"));
+ }
+ writeModuleInfo(minfo, zos, System.currentTimeMillis());
+ }
for (File file: entries) {
addFile(zos, file);
}
zos.close();
}
+ /*
+ * Infers ModuleRequires from the specified Class-Path attribute.
+ * If it is a modular jar file and presents on the system, adds
+ * it to the required module list of the given ModuleInfo.
+ *
+ * @return true if it successfully infers all ModuleRequires
+ * from the given Class-Path attribute; otherwise false.
+ */
+ private boolean addModuleRequires(ModuleInfo minfo, String cpath)
+ throws IOException
+ {
+ boolean succeed = true;
+ if (cpath != null) {
+ String path = "";
+ if (fname != null) {
+ path = fname.substring(0, Math.max(0, fname.lastIndexOf('/') + 1));
+ }
+ String[] jars = cpath.split("\\s++");
+ List<ModuleId> mids = new ArrayList<>();
+ for (String fn : jars) {
+ File f = new File(path.concat(fn));
+ if (!fn.endsWith("/") && f.exists()) { // it is a jar file
+ JarFile jf = new JarFile(f);
+ java.lang.module.ModuleInfo mi = jf.getModuleInfo();
+ if (mi != null) {
+ minfo.addRequire(mi.id());
+ continue;
+ }
+ }
+
+ // not a modular jar
+ output(formatMsg("warning.ignore.classpath", fn));
+ succeed = false;
+ }
+ }
+ return succeed;
+ }
+
private char toUpperCaseASCII(char c) {
return (c < 'a' || c > 'z') ? c : (char) (c + 'A' - 'a');
}
@@ -517,6 +575,22 @@ class Main {
return true;
}
+ void copyZipEntry(ZipEntry e, ZipOutputStream zos)
+ throws IOException
+ {
+ // do our own compression
+ ZipEntry e2 = new ZipEntry(e.getName());
+ e2.setMethod(e.getMethod());
+ e2.setTime(e.getTime());
+ e2.setComment(e.getComment());
+ e2.setExtra(e.getExtra());
+ if (e.getMethod() == ZipEntry.STORED) {
+ e2.setSize(e.getSize());
+ e2.setCrc(e.getCrc());
+ }
+ zos.putNextEntry(e2);
+ }
+
/**
* Updates an existing jar file.
*/
@@ -524,60 +598,70 @@ class Main {
InputStream newManifest,
JarIndex jarIndex) throws IOException
{
- ZipInputStream zis = new ZipInputStream(in);
- ZipOutputStream zos = new JarOutputStream(out);
- ZipEntry e = null;
- boolean foundManifest = false;
- boolean updateOk = true;
+ try (ZipInputStream zis = new ZipInputStream(in);
+ ZipOutputStream zos = new JarOutputStream(out)) {
+ ZipEntry e = null;
+ Manifest mf = null;
- if (jarIndex != null) {
- addIndex(jarIndex, zos);
- }
+ if (entryMap.containsKey(MODULEINFO_NAME) && moduleid != null) {
+ error(getMsg("error.bad.moduleid"));
+ return false;
+ }
- // put the old entries first, replace if necessary
- while ((e = zis.getNextEntry()) != null) {
- String name = e.getName();
+ if (jarIndex != null) {
+ addIndex(jarIndex, zos);
+ }
- boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME);
+ // put the old entries first, replace if necessary
+ while ((e = zis.getNextEntry()) != null) {
+ String name = e.getName();
- if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME))
- || (Mflag && isManifestEntry)) {
- continue;
- } else if (isManifestEntry && ((newManifest != null) ||
- (ename != null))) {
- foundManifest = true;
- if (newManifest != null) {
- // Don't read from the newManifest InputStream, as we
- // might need it below, and we can't re-read the same data
- // twice.
- FileInputStream fis = new FileInputStream(mname);
- boolean ambiguous = isAmbiguousMainClass(new Manifest(fis));
- fis.close();
- if (ambiguous) {
- return false;
- }
+ boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME);
+
+ if (jarIndex != null && equalsIgnoreCase(name, INDEX_NAME)) {
+ continue;
}
- // Update the manifest.
- Manifest old = new Manifest(zis);
- if (newManifest != null) {
- old.read(newManifest);
+ if (isManifestEntry) {
+ mf = new Manifest(zis);
+ if (Mflag) {
+ continue;
+ }
+
+ if (newManifest != null) {
+ // Don't read from the newManifest InputStream, as we
+ // might need it below, and we can't re-read the same data
+ // twice.
+ try (FileInputStream fis = new FileInputStream(mname)) {
+ if (isAmbiguousMainClass(new Manifest(fis))) {
+ return false;
+ }
+ }
+ mf.read(newManifest);
+ }
+
+ if (ename != null) {
+ addMainClass(mf, ename);
+ }
+
+ // retain the manifest in the same location as
+ // the existing manifest entry. JarInputStream
+ // only creates a Manifest if it's the first entry;
+ // otherwise, it treats it as an ordinary ZipEntry.
+ if (newManifest != null || ename != null) {
+ updateManifest(mf, zos);
+ } else {
+ writeManifest(mf, zos, e.getTime());
+ }
+ continue;
}
- updateManifest(old, zos);
- } else {
+
if (!entryMap.containsKey(name)) { // copy the old stuff
- // do our own compression
- ZipEntry e2 = new ZipEntry(name);
- e2.setMethod(e.getMethod());
- e2.setTime(e.getTime());
- e2.setComment(e.getComment());
- e2.setExtra(e.getExtra());
- if (e.getMethod() == ZipEntry.STORED) {
- e2.setSize(e.getSize());
- e2.setCrc(e.getCrc());
- }
- zos.putNextEntry(e2);
- copy(zis, zos);
+ if (!name.equals(MODULEINFO_NAME) || moduleid == null) {
+ copyZipEntry(e, zos);
+ copy(zis, zos); // copy the content
+ zos.closeEntry();
+ }
} else { // replace with the new files
File f = entryMap.get(name);
addFile(zos, f);
@@ -585,29 +669,38 @@ class Main {
entries.remove(f);
}
}
- }
- // add the remaining new files
- for (File f: entries) {
- addFile(zos, f);
- }
- if (!foundManifest) {
- if (newManifest != null) {
- Manifest m = new Manifest(newManifest);
- updateOk = !isAmbiguousMainClass(m);
- if (updateOk) {
- updateManifest(m, zos);
+ // add the remaining new files
+ for (File f : entries) {
+ addFile(zos, f);
+ }
+
+ if (mf == null) {
+ // META-INF/MANIFEST.MF not exist
+ if (newManifest != null) {
+ mf = new Manifest(newManifest);
+ if (isAmbiguousMainClass(mf))
+ return false;
+ } else if (ename != null) {
+ mf = new Manifest();
}
- } else if (ename != null) {
- updateManifest(new Manifest(), zos);
}
+
+ if (moduleid != null) {
+ // -I is specified
+ ModuleInfo minfo = new ModuleInfo(moduleid, getMainClass(mf));
+ if (mf != null) {
+ addModuleRequires(minfo, getClassPath(mf));
+ }
+ writeModuleInfo(minfo, zos, System.currentTimeMillis());
+ if (vflag) {
+ output(getMsg("out.update.moduleinfo"));
+ }
+ }
+ return true;
}
- zis.close();
- zos.close();
- return updateOk;
}
-
private void addIndex(JarIndex index, ZipOutputStream zos)
throws IOException
{
@@ -623,6 +716,21 @@ class Main {
zos.closeEntry();
}
+ private void writeManifest(Manifest m, ZipOutputStream zos, long ts)
+ throws IOException
+ {
+ ZipEntry e = new ZipEntry(MANIFEST_NAME);
+ e.setTime(ts);
+ if (flag0) {
+ CRC32OutputStream cos = new CRC32OutputStream();
+ m.write(cos);
+ cos.updateEntry(e);
+ }
+ zos.putNextEntry(e);
+ m.write(zos);
+ zos.closeEntry();
+ }
+
private void updateManifest(Manifest m, ZipOutputStream zos)
throws IOException
{
@@ -631,18 +739,26 @@ class Main {
if (ename != null) {
addMainClass(m, ename);
}
- ZipEntry e = new ZipEntry(MANIFEST_NAME);
- e.setTime(System.currentTimeMillis());
- if (flag0) {
- crc32Manifest(e, m);
- }
- zos.putNextEntry(e);
- m.write(zos);
+ writeManifest(m, zos, System.currentTimeMillis());
if (vflag) {
output(getMsg("out.update.manifest"));
}
}
+ private void writeModuleInfo(ModuleInfo minfo, ZipOutputStream zos, long ts)
+ throws IOException
+ {
+ ZipEntry e = new ZipEntry(MODULEINFO_NAME);
+ e.setTime(ts);
+ if (flag0) {
+ CRC32OutputStream cos = new CRC32OutputStream();
+ minfo.write(cos);
+ cos.updateEntry(e);
+ }
+ zos.putNextEntry(e);
+ minfo.write(zos);
+ zos.closeEntry();
+ }
private String entryName(String name) {
name = name.replace(File.separatorChar, '/');
@@ -687,10 +803,21 @@ class Main {
global.put(Attributes.Name.MAIN_CLASS, mainApp);
}
+ // Returns the entry point if set; otherwise the Main-Class
+ // attribute in the given manifest
+ private String getMainClass(Manifest m) {
+ String mainClass = ename;
+ if (ename == null && m != null) {
+ Attributes global = m.getMainAttributes();
+ mainClass = global.getValue(Attributes.Name.MAIN_CLASS);
+ }
+ return mainClass;
+ }
+
private boolean isAmbiguousMainClass(Manifest m) {
if (ename != null) {
Attributes global = m.getMainAttributes();
- if ((global.get(Attributes.Name.MAIN_CLASS) != null)) {
+ if (global.getValue(Attributes.Name.MAIN_CLASS) != null) {
error(getMsg("error.bad.eflag"));
usageError();
return true;
@@ -744,7 +871,7 @@ class Main {
if (vflag) {
size = e.getSize();
long csize = e.getCompressedSize();
- out.print(formatMsg2("out.size", String.valueOf(size),
+ out.print(formatMsg("out.size", String.valueOf(size),
String.valueOf(csize)));
if (e.getMethod() == ZipEntry.DEFLATED) {
long ratio = 0;
@@ -814,16 +941,6 @@ class Main {
}
/**
- * Computes the crc32 of a Manifest. This is necessary when the
- * ZipOutputStream is in STORED mode.
- */
- private void crc32Manifest(ZipEntry e, Manifest m) throws IOException {
- CRC32OutputStream os = new CRC32OutputStream();
- m.write(os);
- os.updateEntry(e);
- }
-
- /**
* Computes the crc32 of a File. This is necessary when the
* ZipOutputStream is in STORED mode.
*/
@@ -1034,6 +1151,14 @@ class Main {
private HashSet<String> jarPaths = new HashSet<String>();
+ String getClassPath(Manifest m) {
+ Attributes attr = m.getMainAttributes();
+ if (attr != null) {
+ return attr.getValue(Attributes.Name.CLASS_PATH);
+ } else {
+ return null;
+ }
+ }
/**
* Generates the transitive closure of the Class-Path attribute for
* the specified jar file.
@@ -1049,31 +1174,23 @@ class Main {
// class path attribute will give us jar file name with
// '/' as separators, so we need to change them to the
// appropriate one before we open the jar file.
- JarFile rf = new JarFile(jar.replace('/', File.separatorChar));
-
- if (rf != null) {
+ try (JarFile rf = new JarFile(jar.replace('/', File.separatorChar))) {
Manifest man = rf.getManifest();
- if (man != null) {
- Attributes attr = man.getMainAttributes();
- if (attr != null) {
- String value = attr.getValue(Attributes.Name.CLASS_PATH);
- if (value != null) {
- StringTokenizer st = new StringTokenizer(value);
- while (st.hasMoreTokens()) {
- String ajar = st.nextToken();
- if (!ajar.endsWith("/")) { // it is a jar file
- ajar = path.concat(ajar);
- /* check on cyclic dependency */
- if (! jarPaths.contains(ajar)) {
- files.addAll(getJarPath(ajar));
- }
- }
+ String value = man != null ? getClassPath(man) : null;
+ if (value != null) {
+ StringTokenizer st = new StringTokenizer(value);
+ while (st.hasMoreTokens()) {
+ String ajar = st.nextToken();
+ if (!ajar.endsWith("/")) { // it is a jar file
+ ajar = path.concat(ajar);
+ /* check on cyclic dependency */
+ if (!jarPaths.contains(ajar)) {
+ files.addAll(getJarPath(ajar));
}
}
}
}
- }
- rf.close();
+ };
return files;
}
diff --git a/jdk/src/share/classes/sun/tools/jar/ModuleInfo.java b/jdk/src/share/classes/sun/tools/jar/ModuleInfo.java
new file mode 100644
index 0000000..82ef400
--- /dev/null
+++ b/jdk/src/share/classes/sun/tools/jar/ModuleInfo.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2011, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 sun.tools.jar;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.lang.module.*;
+import java.lang.module.Dependence.Modifier;
+import java.util.*;
+import com.sun.tools.classfile.*;
+import static com.sun.tools.classfile.ConstantPool.*;
+
+/**
+ * Helper class to generate a module-info.class for a modular JAR.
+ */
+class ModuleInfo {
+ private static ModuleSystem ms = ModuleSystem.base();
+ private final ModuleId moduleId;
+ private final String mainClass;
+ private final Set<Dependence> requires;
+ private final ModuleInfoWriter writer;
+ private byte[] bytes;
+
+ ModuleInfo(String mid, String mainclass) {
+ this.moduleId = ms.parseModuleId(mid);
+ this.mainClass = mainclass;
+ this.requires = new HashSet<>();
+ this.writer = new ModuleInfoWriter();
+ addRequire(org.openjdk.jigsaw.Platform.defaultPlatformModule(),
+ EnumSet.of(Modifier.SYNTHETIC));
+ }
+
+ ModuleId id() {
+ return moduleId;
+ }
+
+ String mainClass() {
+ return mainClass;
+ }
+
+ void addRequire(ModuleId mid) {
+ addRequire(mid, Collections.EMPTY_SET);
+ }
+
+ void addRequire(ModuleId mid, Set<Modifier> mods) {
+ ModuleIdQuery midq = ms.parseModuleIdQuery(mid.name() + "@" + mid.version());
+ requires.add(new Dependence(mods, midq));
+ }
+
+ void addRequire(Dependence d) {
+ requires.add(d);
+ }
+
+ void write(OutputStream os) throws IOException {
+ if (bytes == null) {
+ // cache the bytes as this method may be called
+ // twice for a compressed entry to calculate CRC
+ // and then write it to the jar file.
+ bytes = writer.getModuleInfoBytes();
+ }
+ os.write(bytes);
+ }
+
+ class ModuleInfoWriter {
+ final List<CPInfo> cpinfos = new ArrayList<>();
+ final List<Attribute> attrs = new ArrayList<>();
+ int cpidx = 1;
+ int this_class_idx;
+
+ ModuleInfoWriter() {
+ cpinfos.add(0, new CONSTANT_Utf8_info("dummy"));
+ }
+
+ void addModuleAttribute() {
+ String mname = moduleId.name();
+ this_class_idx = cpidx;
+ cpinfos.add(cpidx, new CONSTANT_Class_info(null, cpidx+3));
+ cpinfos.add(cpidx+1, new CONSTANT_Utf8_info(mname));
+ cpinfos.add(cpidx+2, new CONSTANT_Utf8_info(moduleId.version().toString()));
+ cpinfos.add(cpidx+3, new CONSTANT_Utf8_info(mname + "/module-info"));
+ cpinfos.add(cpidx+4, new CONSTANT_ModuleId_info(null, cpidx+1, cpidx+2));
+ cpinfos.add(cpidx+5, new CONSTANT_Utf8_info(Attribute.Module));
+ Attribute attr = new Module_attribute(cpidx+5, cpidx+4);
+ attrs.add(attr);
+ cpidx += 6;
+ }
+
+ void addModuleRequireAttribute() {
+ // add constant pool entries for the modifiers
+ List<Modifier> modifiers = new ArrayList<>();
+ int modifierIdx = cpidx;
+ for (Dependence d: requires) {
+ for (Modifier m : d.modifiers()) {
+ int i = modifiers.indexOf(m);
+ if (i >= 0)
+ continue;
+
+ modifiers.add(m);
+ String s = m.name().toLowerCase(Locale.ENGLISH);
+ cpinfos.add(cpidx++, new CONSTANT_Utf8_info(s));
+ }
+ }
+
+ ModuleRequires_attribute.Entry[] reqs =
+ new ModuleRequires_attribute.Entry[requires.size()];
+ int i = 0, j = 0;
+ for (Dependence d: requires) {
+ // ## specify a version range in CONSTANT_ModuleId_info?
+ String version = d.query().versionQuery().toString();
+ cpinfos.add(cpidx, new CONSTANT_Utf8_info(d.query().name()));
+ cpinfos.add(cpidx+1, new CONSTANT_Utf8_info(version));
+ cpinfos.add(cpidx+2, new CONSTANT_ModuleId_info(null, cpidx, cpidx+1));
+ int[] attrs = new int[d.modifiers().size()];
+ j = 0;
+ for (Modifier m : d.modifiers()) {
+ attrs[j++] = modifierIdx + modifiers.indexOf(m);
+ }
+ reqs[i++] = new ModuleRequires_attribute.Entry(cpidx+2, attrs);
+ cpidx += 3;
+ }
+ cpinfos.add(cpidx, new CONSTANT_Utf8_info(Attribute.ModuleRequires));
+ Attribute attr = new ModuleRequires_attribute(cpidx, reqs);
+ attrs.add(attr);
+ cpidx++;
+ }
+
+ void addModuleClassAttribute() {
+ String cname = mainClass.replace('.', '/');
+ cpinfos.add(cpidx, new CONSTANT_Utf8_info(Attribute.ModuleClass));
+ cpinfos.add(cpidx+1, new CONSTANT_Utf8_info(cname));
+ cpinfos.add(cpidx+2, new CONSTANT_Class_info(null, cpidx+1));
+ Attribute attr = new ModuleClass_attribute(cpidx, cpidx+2, new int[0]);
+ attrs.add(attr);
+ cpidx += 3;
+ }
+
+ void addModuleExportAttribute() {
+ cpinfos.add(cpidx, new CONSTANT_Utf8_info(Attribute.ModuleExport));
+ cpinfos.add(cpidx+1, new CONSTANT_Utf8_info("**"));
+ cpinfos.add(cpidx+2, new CONSTANT_Class_info(null, cpidx+1));
+ ModuleExport_attribute.Entry[] entry =
+ new ModuleExport_attribute.Entry[] {
+ new ModuleExport_attribute.Entry(cpidx+2, 0)
+ };
+ Attribute attr = new ModuleExport_attribute(cpidx, entry);
+ attrs.add(attr);
+ cpidx += 3;
+ }
+
+ byte[] getModuleInfoBytes() throws IOException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ ClassWriter cw = new ClassWriter();
+ addModuleAttribute();
+ addModuleRequireAttribute();
+ addModuleExportAttribute();
+
+ if (mainClass != null)
+ addModuleClassAttribute();
+
+ ConstantPool cpool = new ConstantPool(cpinfos.toArray(new CPInfo[0]));
+ Attributes attributes = new Attributes(cpool, attrs.toArray(new Attribute[0]));
+ ClassFile cf = new ClassFile(0xCAFEBABE, 0, 51, cpool,
+ new AccessFlags(AccessFlags.ACC_MODULE),
+ this_class_idx, 0, new int[0], new Field[0], new Method[0],
+ attributes);
+ cw.write(cf, os);
+ return os.toByteArray();
+ }
+ }
+}
diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar.properties
index 852cac2..a5025c6 100644
--- a/jdk/src/share/classes/sun/tools/jar/resources/jar.properties
+++ b/jdk/src/share/classes/sun/tools/jar/resources/jar.properties
@@ -32,10 +32,12 @@ error.bad.option=\
error.bad.cflag=\
'c' flag requires manifest or input files to be specified!
error.bad.uflag=\
- 'u' flag requires manifest, 'e' flag or input files to be specified!
+ 'u' flag requires manifest, 'e' flag, 'I' flag or input files to be specified!
error.bad.eflag=\
'e' flag and manifest with the 'Main-Class' attribute cannot be specified \n\
together!
+error.bad.moduleid=\
+ module-info.class exists in the input file; cannot specify 'I' flag
error.nosuch.fileordir=\
{0} : no such file or directory
error.write.file=\
@@ -44,10 +46,16 @@ error.create.dir=\
{0} : could not create directory
error.incorrect.length=\
incorrect length while processing: {0}
+warning.ignore.classpath=\
+ ignoring {0} in Class-Path attribute: not a modular JAR
out.added.manifest=\
added manifest
+out.added.moduleinfo=\
+ added module-info.class
out.update.manifest=\
updated manifest
+out.update.moduleinfo =\
+ updated module-info.class
out.ignore.entry=\
ignoring entry {0}
out.adding=\
@@ -66,7 +74,7 @@ out.size=\
(in = {0}) (out= {1})
usage=\
-Usage: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\
+Usage: jar {ctxui}[vfm0MeI] [jar-file] [manifest-file] [entry-point] [module-id] [-C dir] files ...\n\
Options:\n\
\ \ -c create new archive\n\
\ \ -t list table of contents for archive\n\
@@ -81,6 +89,8 @@ Options:\n\
\ \ -M do not create a manifest file for the entries\n\
\ \ -i generate index information for the specified jar files\n\
\ \ -C change to the specified directory and include the following file\n\
+\ \ -I specify the module id for this modular JAR.\n\
+\ \ It must match the id declared in module-info.class if exists.\n\n\
If any file is a directory then it is processed recursively.\n\
The manifest file name, the archive file name and the entry point name are\n\
specified in the same order as the 'm', 'f' and 'e' flags.\n\n\
@@ -88,4 +98,8 @@ Example 1: to archive two class files into an archive called classes.jar: \n\
\ \ jar cvf classes.jar Foo.class Bar.class \n\
Example 2: use an existing manifest file 'mymanifest' and archive all the\n\
\ \ files in the foo/ directory into 'classes.jar': \n\
-\ \ jar cvfm classes.jar mymanifest -C foo/ .\n
+\ \ jar cvfm classes.jar mymanifest -C foo/ .\n\
+Example 3: update an existing jar to a modular JAR\n\
+\ \ jar uvfI classes.jar acme.foo at 1.0\n\
+\ \ or \n\
+\ \ jar uvf classes.jar module-info.class\n
diff --git a/jdk/test/org/openjdk/jigsaw/_Configurator.java b/jdk/test/org/openjdk/jigsaw/_Configurator.java
index 0218d65..9044f7e 100644
--- a/jdk/test/org/openjdk/jigsaw/_Configurator.java
+++ b/jdk/test/org/openjdk/jigsaw/_Configurator.java
@@ -226,6 +226,7 @@ public class _Configurator {
}
};
+
new Test("diamond", true, "x at 1") {
void init(MockLibrary mlib) {
mlib.add(module("x at 1").requires("y at 2").requires("w at 4"))
@@ -376,6 +377,26 @@ public class _Configurator {
}
};
+ new Test("local-same-context", true, "x at 1") {
+ void init(MockLibrary mlib) {
+ mlib.add(module("ll at 1").requiresLocal("lc at 1"))
+ .add(module("lr at 1").requiresLocal("lc at 1").requiresLocal("x"))
+ .add(module("lc at 1").permits("ll").permits("lr"))
+ .add(module("x at 1").requires("ll at 1").requires("lr at 1").permits("lr"))
+ .addPublic("x at 1", "x.X")
+ .addPublic("ll at 1", "p.L")
+ .addPublic("lc at 1", "p.C")
+ .addPublic("lr at 1", "p.R");
+ }
+ void ref(ConfigurationBuilder cfbd) {
+ cfbd.add(context("lc at 1", "ll at 1", "lr at 1", "x at 1")
+ .localClass("x.X", "x")
+ .localClass("p.L", "ll")
+ .localClass("p.C", "lc")
+ .localClass("p.R", "lr"));
+ }
+ };
+
/* ## Not yet
new Test("cycle", true, "x at 1") {
diff --git a/jdk/test/org/openjdk/jigsaw/_RemoteRepositoryList.java b/jdk/test/org/openjdk/jigsaw/_RemoteRepositoryList.java
index a4410bc..f646781 100644
--- a/jdk/test/org/openjdk/jigsaw/_RemoteRepositoryList.java
+++ b/jdk/test/org/openjdk/jigsaw/_RemoteRepositoryList.java
@@ -54,6 +54,7 @@ public class _RemoteRepositoryList {
assert equals(c1, c2) : String.format("%s : %s", c1, c2);
}
+ @SuppressWarnings("unchecked")
private static <T> void assertEquals(Collection<T> c1, T ... xs) {
Collection<T> c2 = Arrays.asList(xs);
assertEquals(c1, c2);
@@ -114,6 +115,14 @@ public class _RemoteRepositoryList {
return us;
}
+ static String localHost;
+
+ static URI local(int port, String path) throws Exception {
+ if (localHost == null)
+ localHost = InetAddress.getLocalHost().getHostName();
+ return URI.create("http://" + localHost + ":" + port + path);
+ }
+
static void testAddRemove(int port) throws Exception {
File LIB = new File("z.lib.addrem");
@@ -121,7 +130,7 @@ public class _RemoteRepositoryList {
RemoteRepositoryList rl = lib.repositoryList();
assert rl.repositories().isEmpty();
- URI u1 = URI.create("http://localhost:" + port + "/foo");
+ URI u1 = local(port, "/foo");
RemoteRepository rr = rl.add(u1, 0);
assert rr != null;
u1 = URI.create(u1.toString() + "/");
@@ -137,17 +146,17 @@ public class _RemoteRepositoryList {
RemoteRepository rr_ = rrs.get(0);
assert rr_.location().equals(rr.location());
- URI u2 = URI.create("http://localhost:" + port + "/bar/");
+ URI u2 = local(port, "/bar/");
RemoteRepository rr2 = rl.add(u2, Integer.MAX_VALUE);
assertEquals(locations(rl), u1, u2);
assertEquals(rl.repositories(), rr_, rr2);
- URI u3 = URI.create("http://localhost:" + port + "/baz/");
+ URI u3 = local(port, "/baz/");
RemoteRepository rr3 = rl.add(u3, 0);
assertEquals(locations(rl), u3, u1, u2);
assertEquals(rl.repositories(), rr3, rr_, rr2);
- URI u4 = URI.create("http://localhost:" + port + "/qux/");
+ URI u4 = local(port, "/qux/");
RemoteRepository rr4 = rl.add(u4, 1);
assertEquals(locations(rl), u3, u4, u1, u2);
assertEquals(rl.repositories(), rr3, rr4, rr_, rr2);
diff --git a/jdk/test/org/openjdk/jigsaw/cli/signed-modular-jar.sh b/jdk/test/org/openjdk/jigsaw/cli/signed-modular-jar.sh
index 5365738..5215eaa 100755
--- a/jdk/test/org/openjdk/jigsaw/cli/signed-modular-jar.sh
+++ b/jdk/test/org/openjdk/jigsaw/cli/signed-modular-jar.sh
@@ -83,11 +83,8 @@ grant signedBy "expired-signer" {
EOF
mkdir z.modules z.jarfiles
-$BIN/javac -source 7 -d z.modules -modulepath z.modules `find z.src -name '*.java'`
+$BIN/javac -d z.modules -modulepath z.modules `find z.src -name '*.java'`
-mkdir z.modules/test.security/META-INF
-mv z.modules/test.security/module-info.class \
- z.modules/test.security/META-INF
$BIN/jar cf z.jarfiles/GetProperty.jar -C z.modules/test.security .
$BIN/jarsigner -keystore keystore.jks z.jarfiles/GetProperty.jar signer < ${SRC}/keystore.pw
diff --git a/jdk/test/org/openjdk/jigsaw/hello-jar.sh b/jdk/test/org/openjdk/jigsaw/hello-jar.sh
index 6c9dddd..2162e34 100644
--- a/jdk/test/org/openjdk/jigsaw/hello-jar.sh
+++ b/jdk/test/org/openjdk/jigsaw/hello-jar.sh
@@ -40,6 +40,7 @@ rm -rf z.*
mk z.src/com.greetings/module-info.java <<EOF
module com.greetings @ 0.1 {
requires org.astro @ 1.2;
+ requires test @ 1.0;
class com.greetings.Hello;
}
EOF
@@ -67,29 +68,95 @@ public class World {
}
EOF
+mk z.src/test/module-info.java <<EOF
+module test @ 1.0 {
+ class test.Test;
+}
+EOF
+
+mk z.src/test/test/Test.java <<EOF
+package test;
+import java.lang.module.*;
+import java.util.jar.*;
+public class Test {
+ public static void main(String[] argv) throws Exception {
+ Test t = new Test(argv[0]);
+ t.run();
+ }
+ String jfname;
+ public Test(String name) {
+ this.jfname = name;
+ }
+ public void run() throws Exception {
+ JarFile jf = new JarFile(jfname);
+ ModuleInfo mi = jf.getModuleInfo();
+ if (mi == null)
+ throw new RuntimeException("null ModuleInfo in " + jfname);
+ if (!mi.mainClass().equals("com.greetings.Hello")) {
+ throw new RuntimeException("Unexpected main class " + mi);
+ }
+ if (mi.requires().size() != 3)
+ throw new RuntimeException("requires.length != 3");
+ Dependence[] ds = mi.requires().toArray(new Dependence[0]);
+ for (Dependence d : mi.requires()) {
+ String n = d.query().name();
+ if (n.startsWith("jdk")) continue;
+ if (!n.equals("org.astro") && !n.equals("test"))
+ throw new RuntimeException("Unexpected requires " + d);
+ }
+ }
+}
+EOF
+
mk z.src/manifest <<EOF
-Class-Path: world.jar
-Main-Class: com.greetings/Hello
+Class-Path: world.jar test.jar
+Main-Class: com.greetings.Hello
EOF
mkdir z.modules z.jarfiles
-$BIN/javac -source 7 -d z.modules -modulepath z.modules \
+$BIN/javac -d z.modules -modulepath z.modules \
`find z.src -name '*.java'`
-mkdir z.modules/com.greetings/META-INF
-mkdir z.modules/org.astro/META-INF
-mv z.modules/com.greetings/module-info.class \
- z.modules/com.greetings/META-INF
-mv z.modules/org.astro/module-info.class \
- z.modules/org.astro/META-INF
+run() {
+ rm -rf z.lib
+ DIR=$1
+ # launch in legacy mode
+ $BIN/java -jar $DIR/hello.jar
+
+ # launch in module mode
+ $BIN/jmod -L z.lib create
+ $BIN/jmod -L z.lib install $DIR/test.jar $DIR/world.jar $DIR/hello.jar
+ $BIN/java -L z.lib -m com.greetings
+ # validate module-info.class in hello.jar
+ $BIN/java -L z.lib -m test $DIR/hello.jar
+}
# Test jar file in both store-only mode and compressed mode
-$BIN/jar c0f z.jarfiles/world.jar -C z.modules/org.astro .
-$BIN/jar cfm z.jarfiles/hello.jar z.src/manifest -C z.modules/com.greetings .
-
-# launch in legacy mode
-$BIN/java -jar z.jarfiles/hello.jar
-
-$BIN/jmod -L z.lib create
-$BIN/jmod -L z.lib install z.jarfiles/world.jar z.jarfiles/hello.jar
-$BIN/java -L z.lib -m com.greetings
+$BIN/jar c0fe z.modules/test.jar test.Test -C z.modules/test .
+$BIN/jar c0f z.modules/world.jar -C z.modules/org.astro .
+$BIN/jar cfm z.modules/hello.jar z.src/manifest -C z.modules/com.greetings .
+
+# modular jars with module-info.class entry
+run z.modules
+
+
+# modular jars without module-info.class entry but use -I option
+$BIN/jar c0fIe z.jarfiles/test.jar test at 1.0 test.Test \
+ -C z.modules/test test
+$BIN/jar cfI z.jarfiles/world.jar org.astro at 1.2 \
+ -C z.modules/org.astro org
+$BIN/jar c0fmI z.jarfiles/hello.jar z.src/manifest com.greetings at 0.1 \
+ -C z.modules/com.greetings com
+
+# Run in legacy mode and module mode
+run z.jarfiles
+
+# Update z.jarfiles
+$BIN/jar ufI z.jarfiles/test.jar test at 1.0
+$BIN/jar u0f z.jarfiles/world.jar \
+ -C z.modules/org.astro module-info.class
+$BIN/jar u0fm z.jarfiles/hello.jar z.src/manifest \
+ -C z.modules/com.greetings com
+
+# Run in legacy mode and module mode
+run z.jarfiles
diff --git a/jdk/test/org/openjdk/jigsaw/hello-optional.sh b/jdk/test/org/openjdk/jigsaw/hello-optional.sh
new file mode 100644
index 0000000..fdbb045
--- /dev/null
+++ b/jdk/test/org/openjdk/jigsaw/hello-optional.sh
@@ -0,0 +1,160 @@
+#! /bin/sh
+
+# Copyright (c) 2011, 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.
+
+# @test
+# @summary Hello module with optional dependency
+
+exec sh ${TESTSRC:-.}/tester.sh $0
+
+: optional-resolved pass
+
+module com.greetings @ 0.1 {
+ requires org.astro @ 1.2;
+ requires optional com.foo;
+ class com.greetings.Hello;
+}
+
+package com.greetings;
+import org.astro.World;
+import java.lang.reflect.Module;
+public class Hello {
+ public static void main(String[] args) {
+ System.out.println("Hello, " + World.name() + "!");
+ testOptionalMethod();
+ }
+ public static void testOptionalMethod() {
+ if (Hello.class.isModulePresent("com.foo")) {
+ com.foo.Foo.findit();
+ } else {
+ throw new RuntimeException("com.foo module not present");
+ }
+ }
+}
+
+module org.astro @ 1.2 { }
+
+package org.astro;
+public class World {
+ public static String name() {
+ return "world";
+ }
+}
+
+module com.foo @ 2.0 { }
+
+package com.foo;
+public class Foo {
+ public static void findit() {
+ System.out.println("com.foo is present");
+ }
+ public static String name() {
+ return "world from Foo";
+ }
+}
+
+: foo-not-present pass
+
+module com.greetings @ 0.2 {
+ requires org.astro @ 1.2;
+ requires optional com.foo;
+ class com.greetings.Hello;
+}
+
+package com.greetings;
+import org.astro.World;
+import java.lang.reflect.Module;
+public class Hello {
+ public static void main(String[] args) {
+ System.out.println("Hello, " + World.name() + "!");
+ testOptionalMethod();
+ }
+ public static void testOptionalMethod() {
+ if (Hello.class.isModulePresent("com.foo")) {
+ throw new RuntimeException("com.foo is present");
+ }
+ boolean cnfe = false;
+ try {
+ Class.forName("com.foo.Foo");
+ } catch (ClassNotFoundException e) {
+ cnfe = true;
+ }
+ if (!cnfe) {
+ throw new RuntimeException("com.foo.Foo found");
+ }
+ }
+}
+
+module org.astro @ 1.2 { }
+
+package org.astro;
+import java.lang.reflect.Module;
+public class World {
+ public static String name() {
+ return "world";
+ }
+}
+
+: hello-foo pass
+
+module com.greetings @ 1.0 {
+ requires org.astro @ 2.0;
+ requires optional com.foo;
+ class com.greetings.Hello;
+}
+
+package com.greetings;
+import org.astro.World;
+import java.lang.reflect.Module;
+public class Hello {
+ public static void main(String[] args) {
+ System.out.println("Hello, " + World.name() + "!");
+ com.foo.Foo.findit();
+ }
+}
+
+module org.astro @ 2.0 {
+ requires optional com.foo;
+}
+
+package org.astro;
+import java.lang.reflect.Module;
+public class World {
+ public static String name() {
+ if (!World.class.isModulePresent("com.foo"))
+ throw new RuntimeException("com.foo is present");
+ return com.foo.Foo.name();
+ }
+}
+
+module com.foo @ 2.0 { }
+
+package com.foo;
+public class Foo {
+ public static void findit() {
+ System.out.println("com.foo is present");
+ }
+ public static String name() {
+ return "world from Foo";
+ }
+}
+
diff --git a/jdk/test/org/openjdk/jigsaw/optional-base.sh b/jdk/test/org/openjdk/jigsaw/optional-base.sh
new file mode 100644
index 0000000..3e4126e
--- /dev/null
+++ b/jdk/test/org/openjdk/jigsaw/optional-base.sh
@@ -0,0 +1,89 @@
+#! /bin/sh
+
+# Copyright (c) 2011, 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
+# FITNES 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.
+
+# @test
+# @summary Basic test for optional dependency.
+#
+
+exec sh ${TESTSRC:-.}/tester.sh $0
+
+: hello pass
+
+module com.greetings @ 1.0 {
+ requires org.astro @ 2.0;
+ requires optional com.foo @ 3.0;
+ class com.greetings.Hello;
+}
+
+package com.greetings;
+import java.lang.reflect.*;
+import org.astro.World;
+public class Hello {
+ public static void main(String[] args) throws Throwable {
+ boolean expected = args.length == 0 || Boolean.parseBoolean(args[0]);
+ boolean present = Hello.class.isModulePresent("com.foo");
+ if (present != expected)
+ throw new RuntimeException("com.foo is expected to be " +
+ (present ? "present" : " not present"));
+ String s = null;
+ if (present) {
+ WorldWrapper ww = new WorldWrapper();
+ s = ww.getName();
+ } else {
+ s = World.name();
+ }
+ System.out.println("Hello, " + s + "!");
+ }
+}
+
+package com.greetings;
+import com.foo.Foo;
+import org.astro.World;
+public class WorldWrapper {
+ public String getName() {
+ Foo f = new Foo();
+ return f.name();
+ }
+}
+
+module org.astro @ 2.0 { }
+
+package org.astro;
+import java.lang.reflect.Module;
+public class World {
+ public static String name() {
+ if (World.class.isModulePresent("com.foo")) {
+ throw new RuntimeException("com.foo is not expected to be present");
+ }
+ return "world";
+ }
+}
+
+module com.foo @ 3.0 { }
+
+package com.foo;
+public class Foo {
+ public String name() {
+ return "world from Foo";
+ }
+}
diff --git a/jdk/test/org/openjdk/jigsaw/optional-deps.sh b/jdk/test/org/openjdk/jigsaw/optional-deps.sh
index 924f714..3563924 100644
--- a/jdk/test/org/openjdk/jigsaw/optional-deps.sh
+++ b/jdk/test/org/openjdk/jigsaw/optional-deps.sh
@@ -161,7 +161,7 @@ EOF
mkdir z.modules z.classes
-$BIN/javac -source 7 -d z.modules -modulepath z.modules \
+$BIN/javac -d z.modules -modulepath z.modules \
`find z.src -name '*.java'`
# optional module is not installed
diff --git a/jdk/test/org/openjdk/jigsaw/optional-jaxp.sh b/jdk/test/org/openjdk/jigsaw/optional-jaxp.sh
new file mode 100644
index 0000000..399f5cf
--- /dev/null
+++ b/jdk/test/org/openjdk/jigsaw/optional-jaxp.sh
@@ -0,0 +1,62 @@
+#! /bin/sh
+
+# Copyright (c) 2011, 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
+# FITNES 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.
+
+# @test
+# @summary Basic test for the optional dependency from jdk.base module
+# to JAXP.
+#
+
+exec sh ${TESTSRC:-.}/tester.sh $0
+
+: hello pass
+
+module com.greetings @ 1.0 {
+ requires org.astro @ 2.0;
+ class com.greetings.Hello;
+}
+
+package com.greetings;
+import org.astro.World;
+public class Hello {
+ public static void main(String[] args) throws Throwable {
+ System.out.println("Hello, " + World.name() + "!");
+ }
+}
+
+module org.astro @ 2.0 { }
+
+package org.astro;
+import java.io.*;
+import java.util.Properties;
+public class World {
+ public static String name() throws IOException {
+ Properties properties = new Properties();
+ System.out.println(System.getProperty("test.src"));
+ File xmlfile = new File(System.getProperty("test.src", "."),
+ "properties.xml");
+ try (InputStream is = new FileInputStream(xmlfile)) {
+ properties.loadFromXML(is);
+ return properties.getProperty("hello.world.name");
+ }
+ }
+}
diff --git a/jdk/test/org/openjdk/jigsaw/optional-reexport.sh b/jdk/test/org/openjdk/jigsaw/optional-reexport.sh
new file mode 100644
index 0000000..0b1b266
--- /dev/null
+++ b/jdk/test/org/openjdk/jigsaw/optional-reexport.sh
@@ -0,0 +1,94 @@
+#! /bin/sh
+
+# Copyright (c) 2011, 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
+# FITNES 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.
+
+# @test
+# @summary Basic test for optional module that reexports another
+# module with no local class
+#
+exec sh ${TESTSRC:-.}/tester.sh $0
+
+: hello pass
+
+module com.greetings @ 1.0 {
+ requires org.astro @ 2.0;
+ requires optional com.foobar @ 1.0;
+ class com.greetings.Hello;
+}
+
+package com.greetings;
+import java.lang.reflect.*;
+import org.astro.World;
+public class Hello {
+ public static void main(String[] args) throws Throwable {
+ boolean expected = args.length == 0 || Boolean.parseBoolean(args[0]);
+ boolean present = Hello.class.isModulePresent("com.foobar");
+ if (present != expected)
+ throw new RuntimeException("com.foobar is expected to be " +
+ (present ? "present" : " not present"));
+ String s = null;
+ if (present) {
+ s = new WorldWrapper().getName();
+ } else {
+ s = World.name();
+ }
+ System.out.println("Hello, " + s + "!");
+ }
+}
+
+package com.greetings;
+import com.foo.Foo;
+import org.astro.World;
+public class WorldWrapper {
+ public String getName() {
+ Foo f = new Foo();
+ return f.name();
+ }
+}
+
+module org.astro @ 2.0 { }
+
+package org.astro;
+import java.lang.reflect.Module;
+public class World {
+ public static String name() {
+ if (World.class.isModulePresent("com.foo") ||
+ World.class.isModulePresent("com.foobar")) {
+ throw new RuntimeException("com.foo and com.foobar should not be present");
+ }
+ return "world";
+ }
+}
+
+module com.foo @ 3.0 {}
+
+package com.foo;
+import java.lang.reflect.*;
+public class Foo {
+ public String name() {
+ return "world from Foo";
+ }
+}
+
+module com.foobar @ 1.0 {
+ requires public com.foo @ 3.0;
+}
diff --git a/jdk/test/org/openjdk/jigsaw/properties.xml b/jdk/test/org/openjdk/jigsaw/properties.xml
new file mode 100644
index 0000000..d1868f9
--- /dev/null
+++ b/jdk/test/org/openjdk/jigsaw/properties.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <entry key="hello.world.name">World</entry>
+</properties>
diff --git a/jdk/test/org/openjdk/jigsaw/tester.sh b/jdk/test/org/openjdk/jigsaw/tester.sh
index c3a34bd..025c864 100644
--- a/jdk/test/org/openjdk/jigsaw/tester.sh
+++ b/jdk/test/org/openjdk/jigsaw/tester.sh
@@ -100,6 +100,7 @@ $AWK -v sep="$FS" -v dash_p="$DASH_P" '
if (NF == 3) e = $3; else e = $3 " " $4;
efile = toPath(tdir, "expected");
print e >efile;
+ close(efile);
msdir = toPath(tdir, "src");
mkdir(msdir);
}
@@ -109,6 +110,7 @@ $AWK -v sep="$FS" -v dash_p="$DASH_P" '
mname = module;
mdir = toPath(msdir, mname);
mkdir(mdir);
+ if (mfile != "") close(mfile);
mfile = toPath(mdir, "module-info.java");
print $0 >mfile;
next;
@@ -134,6 +136,7 @@ $AWK -v sep="$FS" -v dash_p="$DASH_P" '
class = $0;
sub(" +\{ *\}? *", "", class);
sub(".*class +", "", class);
+ if (cfile != "") close(cfile);
cfile = toPath(pdir, class ".java");
print pkgpre >>cfile;
print $0 >>cfile;
@@ -170,7 +173,7 @@ fail() {
}
compile() {
- $BIN/javac -source 7 -d modules -modulepath modules \
+ $BIN/javac -d modules -modulepath modules \
`find src -name '*.java'`
}
@@ -188,7 +191,9 @@ catfile() {
invoke() {
if [ -f main ] ; then
modulename=`catfile main`
- $BIN/java $VM_FLAGS -ea -L z.mlib -m $modulename
+ $BIN/java $VM_FLAGS \
+ -Dtest.src=${TESTSRC} -Dtest.classes=${TESTCLASSES} \
+ -ea -L z.mlib -m $modulename
else
true
fi
diff --git a/langtools/.hg/branchheads.cache b/langtools/.hg/branchheads.cache
index 0865f5a..2fcb8b3 100644
--- a/langtools/.hg/branchheads.cache
+++ b/langtools/.hg/branchheads.cache
@@ -1,2 +1,2 @@
-66bca27502f1ee64d5afd4266528df493770f473 1113
-66bca27502f1ee64d5afd4266528df493770f473 default
+e4648740bad5b1f0f350fd4fe103b9cec2a47469 1114
+e4648740bad5b1f0f350fd4fe103b9cec2a47469 default
diff --git a/langtools/.hg/dirstate b/langtools/.hg/dirstate
index 24e346c..06631af 100644
Binary files a/langtools/.hg/dirstate and b/langtools/.hg/dirstate differ
diff --git a/langtools/.hg/store/00changelog.d b/langtools/.hg/store/00changelog.d
index 84e312e..552630c 100644
Binary files a/langtools/.hg/store/00changelog.d and b/langtools/.hg/store/00changelog.d differ
diff --git a/langtools/.hg/store/00changelog.i b/langtools/.hg/store/00changelog.i
index e937c66..0ddf6f7 100644
Binary files a/langtools/.hg/store/00changelog.i and b/langtools/.hg/store/00changelog.i differ
diff --git a/langtools/.hg/store/00manifest.d b/langtools/.hg/store/00manifest.d
index 5c7d69f..36c10aa 100644
Binary files a/langtools/.hg/store/00manifest.d and b/langtools/.hg/store/00manifest.d differ
diff --git a/langtools/.hg/store/00manifest.i b/langtools/.hg/store/00manifest.i
index 656d9e6..beeff42 100644
Binary files a/langtools/.hg/store/00manifest.i and b/langtools/.hg/store/00manifest.i differ
diff --git a/langtools/.hg/store/data/src/share/classes/com/sun/tools/classfile/_module_export__attribute.java.i b/langtools/.hg/store/data/src/share/classes/com/sun/tools/classfile/_module_export__attribute.java.i
index 68ab4ce..acdcaa8 100644
Binary files a/langtools/.hg/store/data/src/share/classes/com/sun/tools/classfile/_module_export__attribute.java.i and b/langtools/.hg/store/data/src/share/classes/com/sun/tools/classfile/_module_export__attribute.java.i differ
diff --git a/langtools/.hg/store/data/src/share/classes/com/sun/tools/classfile/_module_requires__attribute.java.i b/langtools/.hg/store/data/src/share/classes/com/sun/tools/classfile/_module_requires__attribute.java.i
index 0ccf371..1c0cb37 100644
Binary files a/langtools/.hg/store/data/src/share/classes/com/sun/tools/classfile/_module_requires__attribute.java.i and b/langtools/.hg/store/data/src/share/classes/com/sun/tools/classfile/_module_requires__attribute.java.i differ
diff --git a/langtools/.hg/store/undo b/langtools/.hg/store/undo
index a71291d..e8c5582 100644
Binary files a/langtools/.hg/store/undo and b/langtools/.hg/store/undo differ
diff --git a/langtools/.hg/undo.desc b/langtools/.hg/undo.desc
index 201a346..ce7ee1e 100644
--- a/langtools/.hg/undo.desc
+++ b/langtools/.hg/undo.desc
@@ -1,3 +1,3 @@
-1076
+1114
pull
http://hg.openjdk.java.net/jigsaw/jigsaw/langtools
diff --git a/langtools/.hg/undo.dirstate b/langtools/.hg/undo.dirstate
index cd560e2..24e346c 100644
Binary files a/langtools/.hg/undo.dirstate and b/langtools/.hg/undo.dirstate differ
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ModuleExport_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/ModuleExport_attribute.java
index 8db6cc0..978957f 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/ModuleExport_attribute.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ModuleExport_attribute.java
@@ -72,6 +72,11 @@ public class ModuleExport_attribute extends Attribute {
flags = cr.readUnsignedByte();
}
+ public Entry(int e, int f) {
+ export_index = e;
+ flags = f;
+ }
+
public static int length() {
return 3;
}
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ModuleRequires_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/ModuleRequires_attribute.java
index f7f14a0..232eda7 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/ModuleRequires_attribute.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ModuleRequires_attribute.java
@@ -78,6 +78,12 @@ public class ModuleRequires_attribute extends Attribute {
attributes[i] = cr.readUnsignedShort();
}
+ public Entry(int index, int[] attrs) {
+ requires_index = index;
+ attributes_length = attrs.length;
+ attributes = attrs;
+ }
+
public int length() {
return 4 + attributes_length * 2;
}
hooks/post-receive
--
jigsaw packaging
More information about the pkg-java-commits
mailing list