diff --git a/jdk/make/Makefile b/jdk/make/Makefile index c78e4c27e01bde63bb50a6b6f2d17c257cc9e754..04c5a563ee719a83627d57de500d5a41debc648d 100644 --- a/jdk/make/Makefile +++ b/jdk/make/Makefile @@ -74,6 +74,7 @@ import -- copy in the pre-built components (e.g. VM) \n\ import_product -- copy in the product components \n\ import_fastdebug -- copy in the fastdebug components \n\ import_debug -- copy in the debug components \n\ +modules -- build the jdk and jre module images (experimental) \n\ sccs_get -- make sure all SCCS files are up-to-date (need SCCS) \n\ create_links -- create softlinks in Solaris 32bit build to 64bit dirs \n\ " @@ -257,6 +258,7 @@ docs:: sanity-docs post-sanity-docs # Release engineering targets. # include $(BUILDDIR)/common/Release.gmk +include $(BUILDDIR)/common/Modules.gmk # # Cscope targets. diff --git a/jdk/make/common/Modules.gmk b/jdk/make/common/Modules.gmk new file mode 100644 index 0000000000000000000000000000000000000000..d277a11920a0f7033d1e3c75820afa17bd8df776 --- /dev/null +++ b/jdk/make/common/Modules.gmk @@ -0,0 +1,442 @@ +# +# Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +JDK_MODULE_IMAGE_DIR = $(ABS_OUTPUTDIR)/jdk-module-image +JRE_MODULE_IMAGE_DIR = $(ABS_OUTPUTDIR)/jre-module-image + +# +# modules Target to build jdk and jre module image +# +# There is one jar file per module containing classes only. +# All module jars are currently placed under jre/lib directory. +# +# Open issues that need further investigation: +# 1. Classes in jre/lib/ext/dnsns.jar are currently put in jre/lib/jndi-dns +# module. +# 2. Signed jars +# For JDK build, signed jars are copied to the build. +# All jars in the module image are unsigned. +# 3. jre/lib/security/US_export_policy.jar and local_policy.jar +# are not included in the module image yet. + +MODULE_IMAGEBINDIR = bin + +# +# Targets. +# +INITIAL_MODULE_IMAGE_JRE=initial-module-image-jre +INITIAL_MODULE_IMAGE_JDK=initial-module-image-jdk +ifeq ($(PLATFORM), solaris) + ifeq ($(ARCH_DATA_MODEL), 64) + INITIAL_MODULE_IMAGE_JRE=initial-module-image-jre-sol64 + INITIAL_MODULE_IMAGE_JDK=initial-module-image-jdk-sol64 + endif +endif + +modules modules-clobber \ +initial-module-image-jre initial-module-image-jdk \ +initial-module-image-jre-sol64 initial-module-image-jdk-sol64 \ +trim-module-image-jre trim-module-image-jdk \ +process-module-image-jre process-module-image-jdk :: + @$(ECHO) ">>>Making "$@" @ `$(DATE)` ..." + +# Order is important here, trim jre after jdk image is created +modules:: sanity-module-images post-sanity-module-images \ + $(INITIAL_MODULE_IMAGE_JRE) $(INITIAL_MODULE_IMAGE_JDK) \ + trim-module-image-jre trim-module-image-jdk \ + process-module-image-jre process-module-image-jdk + +# Don't use these +module-image-jre:: initial-module-image-jre trim-module-image-jre process-module-image-jre +module-image-jdk:: initial-module-image-jdk trim-module-image-jdk process-module-image-jdk + +# +# Paths to these files we need +JDK_MODULE_LICENSES = $(LICENSE_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%) +JDK_MODULE_64_LICENSES = $(LICENSE_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%64) +JDK_MODULE_DOCFILES = $(OTHER_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%) + +JRE_MODULE_LICENSES = $(LICENSE_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%) +JRE_MODULE_64_LICENSES = $(LICENSE_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%64) +JRE_MODULE_DOCFILES = $(OTHER_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%) +JRE_MODULE_DOCFILES += $(JRE_NAMECHANGE_DOCLIST:%=$(JRE_MODULE_IMAGE_DIR)/%$(TEXT_SUFFIX)) + +###### RULES + +# JDK files +$(JDK_MODULE_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/% + $(process-doc-file) +# Removes LICENSE_VERSION or not +ifdef LICENSE_VERSION +$(JDK_MODULE_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%$(LICENSE_VERSION) + $(process-doc-file) +$(JDK_MODULE_IMAGE_DIR)/%64: $(SHARE_JDK_DOC_SRC)/%$(LICENSE_VERSION) + $(process-doc-file) +else +$(JDK_MODULE_IMAGE_DIR)/%64: $(SHARE_JDK_DOC_SRC)/% + $(process-doc-file) +endif + +# JRE files +$(JRE_MODULE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/% + $(process-doc-file) +# Add $(TEXT_SUFFIX) suffix +ifdef TEXT_SUFFIX +$(JRE_MODULE_IMAGE_DIR)/%$(TEXT_SUFFIX): $(SHARE_JRE_DOC_SRC)/% + $(process-doc-file) +endif +# Removes LICENSE_VERSION or not +ifdef LICENSE_VERSION +$(JRE_MODULE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%$(LICENSE_VERSION) + $(process-doc-file) +$(JRE_MODULE_IMAGE_DIR)/%64: $(SHARE_JRE_DOC_SRC)/%$(LICENSE_VERSION) + $(process-doc-file) +else +$(JRE_MODULE_IMAGE_DIR)/%64: $(SHARE_JRE_DOC_SRC)/% + $(process-doc-file) +endif + +###################################################### +# JRE Image +###################################################### + +MODULES_TEMPDIR=$(ABS_TEMPDIR)/modules +MODULES_LIB = $(ABS_OUTPUTDIR)/modules + +gen-modules: + $(CD) modules; $(MAKE) all + +initial-module-image-jre-setup: + $(RM) -r $(JRE_MODULE_IMAGE_DIR) + $(MKDIR) -p $(JRE_MODULE_IMAGE_DIR) + +# 64-bit solaris jre image contains only the 64-bit add-on files. +initial-module-image-jre-sol64:: initial-module-image-jre-setup \ + $(JRE_MODULE_LICENSES) $(JRE_MODULE_64_LICENSES) + @# Use tar instead of cp to preserve the symbolic links + for dir in bin lib ; do \ + ( $(CD) $(OUTPUTDIR) && \ + $(TAR) cf - `$(FIND) $$dir -name '$(ARCH)' -print` | \ + ($(CD) $(JRE_MODULE_IMAGE_DIR) && $(TAR) xf -) ) ; \ + done + @# Remove some files from the jre area + for t in $(NOTJRETOOLS) ; do \ + $(RM) $(JRE_MODULE_IMAGE_DIR)/bin$(ISA_DIR)/$$t ; \ + done + $(RM) `$(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -name 'orb.idl'` + $(RM) `$(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -name 'ir.idl'` + +# Construct an initial jre image (initial jdk jre) no trimming or stripping +initial-module-image-jre:: initial-module-image-jre-setup \ + $(JRE_LICENSES) $(JRE_MODULE_DOCFILES) \ + gen-modules \ + $(BUILDMETAINDEX_JARFILE) + @# Copy in bin directory + $(CD) $(OUTPUTDIR) && $(FIND) bin -depth | $(CPIO) -pdum $(JRE_MODULE_IMAGE_DIR) + @# CTE plugin security change require new empty directory lib/applet + $(MKDIR) -p $(JRE_MODULE_IMAGE_DIR)/lib/applet + @# Copy files but not .jar in lib directory + $(CD) $(OUTPUTDIR) && $(FIND) lib -depth | $(EGREP) -v ".jar$$" | $(CPIO) -pdum $(JRE_MODULE_IMAGE_DIR) + @# + @# copy modules to jre/lib + @# + $(CP) -rf $(MODULES_LIB)/jre/lib/* $(JRE_MODULE_IMAGE_DIR)/lib + @# Make sure all directories are read/execute for everyone + $(CHMOD) a+rx `$(FIND) $(JRE_MODULE_IMAGE_DIR) -type d` + @# Remove some files from the jre area + for t in $(NOTJRETOOLS) ; do \ + $(RM) $(JRE_MODULE_IMAGE_DIR)/bin$(ISA_DIR)/$$t ; \ + done + @# Remove orb.idl and ir.idl from jre + $(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -name 'orb.idl' -exec $(RM) \{} \; + $(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -name 'ir.idl' -exec $(RM) \{} \; + @# Generate meta-index to make boot and extension class loaders lazier + $(CD) $(JRE_MODULE_IMAGE_DIR)/lib && \ + $(BOOT_JAVA_CMD) -jar $(BUILDMETAINDEX_JARFILE) \ + -o meta-index *.jar + @$(CD) $(JRE_MODULE_IMAGE_DIR)/lib && $(java-vm-cleanup) + $(CD) $(JRE_MODULE_IMAGE_DIR)/lib/ext && \ + $(BOOT_JAVA_CMD) -jar $(BUILDMETAINDEX_JARFILE) \ + -o meta-index *.jar + @$(CD) $(JRE_MODULE_IMAGE_DIR)/lib/ext && $(java-vm-cleanup) +ifeq ($(PLATFORM), windows) + @# Remove certain *.lib files + $(CD) $(JRE_MODULE_IMAGE_DIR)/lib && \ + $(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \ + hpi.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX) + ifeq ($(ARCH_DATA_MODEL), 32) + @# The Java Kernel JRE image ships with a special VM. It is not included + @# in the full JRE image, so remove it. Also, is it only for 32-bit windows. + $(CD) $(JRE_MODULE_IMAGE_DIR)/bin && $(RM) -r kernel + endif +endif # Windows +ifneq ($(PLATFORM), windows) + $(call copy-man-pages,$(JRE_MODULE_IMAGE_DIR),$(JRE_MAN_PAGES)) +endif # !windows + +# Trim out any extra files not for the jre shipment but wanted in the jdk jre. +# (Note the jdk WILL want the jre image before this trimming) +# Removes server VM on Windows 32bit. +# Remove certain shared libraries that should not be in the jre image +# but should be in the jdk jre image. +trim-module-image-jre:: +ifeq ($(PLATFORM), windows) + ifeq ($(ARCH_DATA_MODEL), 32) + $(RM) -r $(JRE_MODULE_IMAGE_DIR)/bin/server + endif + ifdef NOTJRE_SHARED_LIBS + for l in $(NOTJRE_SHARED_LIBS) ; do \ + $(RM) $(JRE_MODULE_IMAGE_DIR)/bin/$$l ; \ + done ; + endif +else # PLATFORM + ifdef NOTJRE_SHARED_LIBS + for l in $(NOTJRE_SHARED_LIBS) ; do \ + $(RM) $(JRE_MODULE_IMAGE_DIR)/lib/$(LIBARCH)/$$l ; \ + done ; + endif +endif # PLATFORM + +# Get list of all Elf files in the jre +JRE_MODULE_ELF_LIST=$(MODULES_TEMPDIR)/jre-elf-files.list +$(JRE_MODULE_ELF_LIST): + @$(prep-target) +ifneq ($(PLATFORM), windows) + $(RM) $@ + $(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -type f -name \*.$(LIB_SUFFIX) >> $@ + $(FILE) `$(FIND) $(JRE_MODULE_IMAGE_DIR)/bin -type f -name \*$(EXE_SUFFIX)` \ + | $(EGREP) 'ELF' | $(CUT) -d':' -f1 >> $@ +endif + +# Post process the image (strips and mcs on Elf files we are shipping) +# (Note the jdk WILL want the jre image before this processing) +process-module-image-jre:: $(JRE_MODULE_ELF_LIST) +ifneq ($(POST_STRIP_PROCESS), ) + for f in `$(CAT) $(JRE_MODULE_ELF_LIST)`; do \ + $(CHMOD) u+w $${f}; \ + $(ECHO) $(POST_STRIP_PROCESS) $${f}; \ + $(POST_STRIP_PROCESS) $${f}; \ + $(CHMOD) go-w $${f}; \ + done +endif +ifneq ($(POST_MCS_PROCESS), ) + for f in `$(CAT) $(JRE_MODULE_ELF_LIST)`; do \ + $(CHMOD) u+w $${f}; \ + $(ECHO) $(POST_MCS_PROCESS) $${f}; \ + $(POST_MCS_PROCESS) $${f}; \ + $(CHMOD) go-w $${f}; \ + done +endif + $(RM) $(JRE_MODULE_ELF_LIST) + +###################################################### +# JDK Image +###################################################### +# Note: cpio ($(CPIO)) sometimes leaves directories without rx access. + +initial-module-image-jdk-setup: + $(RM) -r $(JDK_MODULE_IMAGE_DIR) + $(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/jre + ($(CD) $(JRE_MODULE_IMAGE_DIR) && $(FIND) . -depth -print \ + | $(CPIO) -pdum $(JDK_MODULE_IMAGE_DIR)/jre ) + $(RM) -rf $(JDK_MODULE_IMAGE_DIR)/jre/man + $(CHMOD) a+rx `$(FIND) $(JDK_MODULE_IMAGE_DIR) -type d` + +initial-module-image-jdk64-bindemos: + for dir in bin demo ; do \ + ( $(CD) $(OUTPUTDIR) && \ + $(TAR) cf - `$(FIND) $$dir -name '$(LIBARCH)' -print` | \ + ($(CD) $(JDK_MODULE_IMAGE_DIR) && $(TAR) xf -) ) ; \ + done + +# Solaris 64 bit image is special +initial-module-image-jdk-sol64:: initial-module-image-jdk-setup \ + initial-module-image-jdk64-bindemos \ + $(JDK_MODULE_LICENSES) $(JDK_MODULARLIZED_64_LICENSES) + +# DB files to add +ifeq ($(OPENJDK),true) + +initial-module-image-jdk-db: + +else + +# Create the list of db *.zip files to bundle with jdk +ABS_DB_PATH :=$(call FullPath,$(CLOSED_SHARE_SRC)/db) +DB_ZIP_LIST = $(shell $(LS) $(ABS_DB_PATH)/*.zip 2>/dev/null) + +initial-module-image-jdk-db: $(DB_ZIP_LIST) + $(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/db + for d in $(DB_ZIP_LIST); do \ + ($(CD) $(JDK_MODULE_IMAGE_DIR)/db && $(UNZIP) -o $$d); \ + done + +endif + +# Standard jdk image +initial-module-image-jdk:: initial-module-image-jdk-setup \ + initial-module-image-jdk-db \ + $(JDK_MODULE_LICENSES) $(JDK_MODULE_DOCFILES) + $(MKDIR) $(JDK_MODULE_IMAGE_DIR)/lib + @# + @# copy jdk modules to jdk/lib + @# + $(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/lib + $(CP) -rf $(MODULES_LIB)/lib/* $(JDK_MODULE_IMAGE_DIR)/lib + ifeq ($(PLATFORM), windows) + @# + @# lib/ + @# + $(CP) $(LIBDIR)/$(LIB_PREFIX)jvm.$(LIB_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/lib + $(CP) $(LIBDIR)/$(LIB_PREFIX)jawt.$(LIB_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/lib + @# + @# bin/ + @# + @# copy all EXE files and only certain DLL files from BINDIR + $(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/bin + $(CP) $(BINDIR)/*$(EXE_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/bin + $(CP) $(BINDIR)/jli.$(LIBRARY_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/bin + ifeq ($(ARCH_DATA_MODEL), 32) + ifeq ($(COMPILER_VERSION), VS2003) + $(CP) $(BINDIR)/msvc*71.$(LIBRARY_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/bin + endif + endif + else # PLATFORM + @# + @# bin/ + @# + ($(CD) $(BINDIR)/.. && $(TAR) cf - \ + `$(FIND) bin \( -type f -o -type l \) -print `) | \ + ($(CD) $(JDK_MODULE_IMAGE_DIR) && $(TAR) xf -) + endif # PLATFORM + @# + @# lib/ct.sym + @# + $(MKDIR) -p $(OUTPUTDIR)/symbols/META-INF/sym + $(JAVAC_CMD) -XDprocess.packages -proc:only \ + -processor com.sun.tools.javac.sym.CreateSymbols \ + -Acom.sun.tools.javac.sym.Jar=$(RT_JAR) \ + -Acom.sun.tools.javac.sym.Dest=$(OUTPUTDIR)/symbols/META-INF/sym/rt.jar \ + $(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS) + $(BOOT_JAR_CMD) c0f $(LIBDIR)/ct.sym \ + -C $(OUTPUTDIR)/symbols META-INF $(BOOT_JAR_JFLAGS) + @$(java-vm-cleanup) + $(CP) $(LIBDIR)/ct.sym $(JDK_MODULE_IMAGE_DIR)/lib/ct.sym + @# + @# CORBA supported orb.idl and ir.idl should be copied to lib + @# + $(CP) $(LIBDIR)/orb.idl $(JDK_MODULE_IMAGE_DIR)/lib/orb.idl + $(CP) $(LIBDIR)/ir.idl $(JDK_MODULE_IMAGE_DIR)/lib/ir.idl + ifeq ($(PLATFORM), linux) + @# + @# on Linux copy jexec from jre/lib to /lib + @# + $(CP) $(LIBDIR)/jexec $(JDK_MODULE_IMAGE_DIR)/lib/jexec + endif # PLATFORM + @# + @# demo, include + @# + $(CP) -r -f $(DEMODIR) $(JDK_MODULE_IMAGE_DIR) + $(CP) -r -f $(SAMPLEDIR) $(JDK_MODULE_IMAGE_DIR) + $(CP) -r $(INCLUDEDIR) $(JDK_MODULE_IMAGE_DIR) + @# + @# Swing BeanInfo generation + @# + $(CD) javax/swing/beaninfo && $(MAKE) JDK_IMAGE_DIR=$(JDK_MODULE_IMAGE_DIR) swing-1.2-beans +ifneq ($(PLATFORM), windows) + $(call copy-man-pages,$(JDK_MODULE_IMAGE_DIR),$(JDK_MAN_PAGES)) +endif # !windows + +# Trim out files we don't want to ship +trim-module-image-jdk:: + @# Remove tools that should not be part of SDK. + for t in $(NOTJDKTOOLS); do \ + $(RM) $(JDK_MODULE_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX) \ + $(JDK_MODULE_IMAGE_DIR)/bin/*/native_threads/$${t}$(EXE_SUFFIX); \ + done + +# Get list of Elf files in the jdk +JDK_MODULE_ELF_LIST=$(MODULES_TEMPDIR)/jdk-elf-files.list +$(JDK_MODULE_ELF_LIST): + @$(prep-target) +ifneq ($(PLATFORM), windows) + $(RM) $@ + $(FIND) $(JDK_MODULE_IMAGE_DIR)/jre/lib -type f -name \*.$(LIB_SUFFIX) >> $@ + $(FILE) `$(FIND) $(JDK_MODULE_IMAGE_DIR)/jre/bin -type f -name \*$(EXE_SUFFIX)` \ + | $(EGREP) 'ELF' | $(CUT) -d':' -f1 >> $@ + file `$(FIND) $(JDK_MODULE_IMAGE_DIR)/bin -type f -name \*$(EXE_SUFFIX)` \ + | $(EGREP) 'ELF' | $(CUT) -d':' -f1 >> $@ +endif + +# Post process the image (strips and mcs on files we are shipping) +process-module-image-jdk:: $(JDK_MODULE_ELF_LIST) +ifneq ($(POST_STRIP_PROCESS), ) + for f in `$(CAT) $(JDK_MODULE_ELF_LIST)`; do \ + $(CHMOD) u+w $${f}; \ + $(ECHO) $(POST_STRIP_PROCESS) $${f}; \ + $(POST_STRIP_PROCESS) $${f}; \ + $(CHMOD) go-w $${f}; \ + done +endif +ifneq ($(POST_MCS_PROCESS), ) + for f in `$(CAT) $(JDK_MODULE_ELF_LIST)`; do \ + $(CHMOD) u+w $${f}; \ + $(ECHO) $(POST_MCS_PROCESS) $${f}; \ + $(POST_MCS_PROCESS) $${f}; \ + $(CHMOD) go-w $${f}; \ + done +endif + $(RM) $(JDK_MODULE_ELF_LIST) + +###################################################### +# clobber +###################################################### +modules-clobber:: + $(RM) -r $(JDK_MODULE_IMAGE_DIR) + $(RM) -r $(JRE_MODULE_IMAGE_DIR) + +# +# TODO - nop for now +sanity-module-images post-sanity-module-images: + +modules modules-clobber:: + @$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..." + @$(java-vm-cleanup) + +.PHONY: modules module-image-jre module-image-jdk \ + initial-module-image-jre initial-module-image-jdk \ + initial-module-image-jre-sol64 initial-module-image-jdk-sol64 \ + initial-module-image-jdk-setup \ + initial-module-image-jdk-db \ + initial-module-image-jdk64-bindemos \ + initial-module-image-jre-setup \ + trim-module-image-jre trim-module-image-jdk \ + process-module-image-jre process-module-image-jdk \ + install-previous-jre install-previous-jdk \ + modules-clobber + +# Force rule +FRC: + diff --git a/jdk/make/java/java/mapfile-vers b/jdk/make/java/java/mapfile-vers index 661db2f463c44b0663a8fad8981c22313bfc659a..24c8d21a7898424d7f73ee28f5d012585ed6483b 100644 --- a/jdk/make/java/java/mapfile-vers +++ b/jdk/make/java/java/mapfile-vers @@ -150,10 +150,8 @@ SUNWprivate_1.1 { Java_java_lang_StrictMath_asin; Java_java_lang_StrictMath_atan; Java_java_lang_StrictMath_atan2; - Java_java_lang_StrictMath_ceil; Java_java_lang_StrictMath_cos; Java_java_lang_StrictMath_exp; - Java_java_lang_StrictMath_floor; Java_java_lang_StrictMath_log; Java_java_lang_StrictMath_log10; Java_java_lang_StrictMath_pow; diff --git a/jdk/make/java/java/reorder-i586 b/jdk/make/java/java/reorder-i586 index 6489abcdc2c3107b08c27eac89a3a3b3fc542b4a..fc3202a8439e0af4b31940130880d4e611f40da6 100644 --- a/jdk/make/java/java/reorder-i586 +++ b/jdk/make/java/java/reorder-i586 @@ -107,4 +107,3 @@ text: .text%Java_java_lang_Class_isInstance; text: .text%Java_java_util_TimeZone_getSystemTimeZoneID; text: .text%findJavaTZ_md; text: .text%Java_java_lang_StrictMath_log; -text: .text%Java_java_lang_StrictMath_floor; diff --git a/jdk/make/java/java/reorder-sparc b/jdk/make/java/java/reorder-sparc index 22a178b649842c6aa9476da13cd18581783fc526..090f0001da2a01222f5eade924a44c71f5d5992b 100644 --- a/jdk/make/java/java/reorder-sparc +++ b/jdk/make/java/java/reorder-sparc @@ -105,4 +105,3 @@ text: .text%Java_java_util_TimeZone_getSystemTimeZoneID; text: .text%findJavaTZ_md; text: .text%Java_java_lang_StrictMath_log; text: .text%Java_java_lang_StrictMath_sqrt; -text: .text%Java_java_lang_StrictMath_floor; diff --git a/jdk/make/java/java/reorder-sparcv9 b/jdk/make/java/java/reorder-sparcv9 index d5f49f21ac6d26a6ae569102bd3741a92cde425c..b20b45ab960380dbe4034ff1711dffcdf32f3069 100644 --- a/jdk/make/java/java/reorder-sparcv9 +++ b/jdk/make/java/java/reorder-sparcv9 @@ -101,4 +101,3 @@ text: .text%Java_java_util_TimeZone_getSystemTimeZoneID; text: .text%findJavaTZ_md; text: .text%Java_java_lang_StrictMath_log; text: .text%Java_java_lang_StrictMath_sqrt; -text: .text%Java_java_lang_StrictMath_floor; diff --git a/jdk/make/java/jli/Makefile b/jdk/make/java/jli/Makefile index eeb64ca6e3413cc1c3d450feca0ea7a0dec084d5..7aad6e9892d56ba981f12100456e65a2e07a4562 100644 --- a/jdk/make/java/jli/Makefile +++ b/jdk/make/java/jli/Makefile @@ -152,7 +152,6 @@ STATIC_LIBRARY_NAME = $(LIBPREFIX)$(LIBRARY).lib STATIC_LIBRARY = $(STATIC_LIBRARY_DIR)/$(STATIC_LIBRARY_NAME) $(STATIC_LIBRARY_DIR): $(OBJDIR) - @$(prep-target) @$(MKDIR) $(STATIC_LIBRARY_DIR) $(STATIC_LIBRARY): $(STATIC_LIBRARY_DIR) diff --git a/jdk/make/java/nio/genBuffer.sh b/jdk/make/java/nio/genBuffer.sh index 27e3f82f0fd138a876c05ccd15ca63e955684c0a..69e86238baa9a07b22e0bc1b7f82a5a3cf1f1bb9 100644 --- a/jdk/make/java/nio/genBuffer.sh +++ b/jdk/make/java/nio/genBuffer.sh @@ -44,6 +44,7 @@ rwkey=XX case $type in char) fulltype=character;; + int) fulltype=integer;; *) fulltype=$type;; esac @@ -54,6 +55,11 @@ case $type in long | double) LBPV=3;; esac +case $type in + float|double) floatingPointOrIntegralType=floatingPointType;; + *) floatingPointOrIntegralType=integralType;; +esac + typesAndBits() { type="$1"; BO="$2" @@ -101,6 +107,7 @@ set -e $SPP <$SRC >$DST \ -K$type \ + -K$floatingPointOrIntegralType \ -Dtype=$type \ -DType=$Type \ -Dfulltype=$fulltype \ diff --git a/jdk/make/modules/Makefile b/jdk/make/modules/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..039682e871a2f6f037171424440cb26eb25b0bd7 --- /dev/null +++ b/jdk/make/modules/Makefile @@ -0,0 +1,145 @@ +# +# Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# +# Modularizing the JDK +# + +BUILDDIR = .. +include $(BUILDDIR)/common/Defs.gmk + +CLASSANALYZER_JAR=$(BUILDTOOLJARDIR)/classanalyzer.jar +JAVA_FLAGS=$(JAVA_TOOLS_FLAGS) -Xbootclasspath:$(CLASSBINDIR) + +MODULE_LIB = $(ABS_OUTPUTDIR)/modules +MAINMANIFEST=$(JDK_TOPDIR)/make/tools/manifest.mf +MODULE_JAR_MANIFEST_FILE=$(ABS_TEMPDIR)/manifest.tmp + +TMP=$(ABS_TEMPDIR)/modules +MODULE_CLASSLIST = $(TMP)/classlist +MODULE_CLASSES = $(TMP)/classes +MODULE_LIST = $(MODULE_CLASSLIST)/modules.list + +# Modules in the modules/ext directory +EXT_MODULES = localedata security-sunec security-sunjce + +# Build PKCS#11 on all platforms except 64-bit Windows. +# We exclude windows-amd64 because we don't have any +# 64-bit PKCS#11 implementations to test with on that platform. +PKCS11 = security-sunpkcs11 +ifeq ($(ARCH_DATA_MODEL), 64) + ifeq ($(PLATFORM), windows) + PKCS11 = + endif +endif + +EXT_MODULES += $(PKCS11) + +# Build Microsoft CryptoAPI provider only on (non-64-bit) Windows platform. +ifeq ($(PLATFORM), windows) + ifneq ($(ARCH_DATA_MODEL), 64) + EXT_MODULES += security-sunmscapi + endif +endif + + +JDK_MODULES = tools + +SUBDIRS = tools +all build clean clobber:: + $(SUBDIRS-loop) + +all:: unpack-jars gen-classlist modularize + +$(CLASSANALYZER_JAR): + $(CD) tools && $(MAKE) all + +JAR_LIST := $(shell $(FIND) $(ABS_OUTPUTDIR)/lib -name \*.jar -depth) +unpack-jars: + $(RM) -rf $(MODULE_CLASSES) + $(MKDIR) -p $(MODULE_CLASSES) + $(CP) -rf $(CLASSBINDIR)/* $(MODULE_CLASSES) + for jf in $(JAR_LIST) ; do \ + $(CD) $(MODULE_CLASSES) && $(BOOT_JAR_CMD) xf $$jf $(BOOT_JAR_JFLAGS);\ + done + +gen-classlist: $(CLASSANALYZER_JAR) + @$(ECHO) ">>>Making "$@" @ `$(DATE)` ..." + @$(RM) -rf $(MODULE_CLASSLIST) + @$(MKDIR) -p $(MODULE_CLASSLIST) + + @# Use java in the default tool directory. + @# OUTPUTDIR for solaris 64-bit doesn't have the tools. + $(JAVA_TOOLS_DIR)/java $(JAVA_FLAGS) \ + -Dclassanalyzer.debug \ + -jar $(CLASSANALYZER_JAR) \ + -jdkhome $(OUTPUTDIR) \ + -config modules.config \ + -config modules.group \ + -depconfig jdk7.depconfig \ + -depconfig optional.depconfig \ + -showdynamic \ + -output $(MODULE_CLASSLIST) + @$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..." + +modularize: $(MODULE_JAR_MANIFEST_FILE) + @$(ECHO) ">>>Making "$@" @ `$(DATE)` ..." + @$(RM) -rf $(MODULE_LIB) + @$(MKDIR) -p $(MODULE_LIB)/lib + @$(MKDIR) -p $(MODULE_LIB)/jre/lib/ext + + @# create modules + for m in `$(NAWK) '{print $$1}' $(MODULE_LIST)` ; do \ + $(ECHO) "Creating module $$m" ; \ + $(SED) -e 's%\\%\/%g' < $(MODULE_CLASSLIST)/$$m.classlist > $(TMP)/tmp.cf ; \ + if [ -f $(MODULE_CLASSLIST)/$$m.resources ] ; then \ + $(SED) -e 's%\\%\/%g' < $(MODULE_CLASSLIST)/$$m.resources >> $(TMP)/tmp.cf ; \ + fi ; \ + $(CD) $(MODULE_CLASSES) && \ + $(BOOT_JAR_CMD) c0mf $(MODULE_JAR_MANIFEST_FILE) \ + $(MODULE_LIB)/$$m.jar \ + @$(TMP)/tmp.cf \ + $(BOOT_JAR_JFLAGS) ; \ + done + @$(CD) $(MODULE_CLASSES) && $(java-vm-cleanup) + @# move modules to lib, jre/lib, or jre/lib/ext + for m in $(EXT_MODULES) ; do \ + $(MV) $(MODULE_LIB)/$$m.jar $(MODULE_LIB)/jre/lib/ext ; \ + done + for m in $(JDK_MODULES) ; do \ + $(MV) $(MODULE_LIB)/$$m.jar $(MODULE_LIB)/lib ; \ + done + $(MV) $(MODULE_LIB)/*.jar $(MODULE_LIB)/jre/lib + @$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..." + +$(MODULE_JAR_MANIFEST_FILE): + $(SED) -e "s/@@RELEASE@@/$(RELEASE)/" $(MAINMANIFEST) > $@ + +clean clobber:: + $(RM) -rf $(MODULE_CLASSLIST) + $(RM) -rf $(MODULE_LIB) + $(RM) -f $(MODULE_JAR_MANIFEST_FILE) + $(RM) -f $(CLASSANALYZER_JAR) + diff --git a/jdk/make/modules/bootmodule.roots b/jdk/make/modules/bootmodule.roots new file mode 100644 index 0000000000000000000000000000000000000000..cd0b264b2549006d6043f2c2cfd8e4d9e1bbbba5 --- /dev/null +++ b/jdk/make/modules/bootmodule.roots @@ -0,0 +1,199 @@ +# +# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# +# List of root classes/methods, each line of the following syntax: +# +# |* +# exclude | + +# The boot module generated based on this rootset does not support +# - security permission check +# - non-standard charset +# - logging output +# - resource bundles +# including error output from the launcher + +# VM preloaded classes +java.lang.Object +java.lang.String +java.lang.Class +java.lang.Cloneable +java.lang.ClassLoader +java.lang.System +java.lang.Throwable +java.lang.Error +java.lang.ThreadDeath +java.lang.Exception +java.lang.RuntimeException +java.security.ProtectionDomain +java.security.AccessControlContext +java.lang.ClassNotFoundException +java.lang.NoClassDefFoundError +java.lang.ClassCastException +java.lang.ArrayStoreException +java.lang.VirtualMachineError +java.lang.OutOfMemoryError +java.lang.StackOverflowError +java.lang.IllegalMonitorStateException +java.lang.ref.Reference +java.lang.ref.SoftReference +java.lang.ref.WeakReference +java.lang.ref.FinalReference +java.lang.ref.PhantomReference +java.lang.ref.Finalizer +java.lang.Runnable +java.lang.Thread +java.lang.ThreadGroup +java.util.Properties +java.lang.reflect.AccessibleObject +java.lang.reflect.Member +java.lang.reflect.Field +java.lang.reflect.Method +java.lang.reflect.Constructor +java.lang.reflect.Type +sun.reflect.MagicAccessorImpl +sun.reflect.MethodAccessorImpl +sun.reflect.ConstructorAccessorImpl +sun.reflect.DelegatingClassLoader +sun.reflect.ConstantPool +sun.reflect.UnsafeStaticFieldAccessorImpl +java.util.Vector +java.lang.StringBuffer +java.lang.StackTraceElement +java.nio.Buffer +java.lang.Boolean +java.lang.Character +java.lang.Float +java.lang.Double +java.lang.Byte +java.lang.Short +java.lang.Integer +java.lang.Long +java.lang.NullPointerException +java.lang.ArithmeticException +java.lang.Compiler + + +# Root methods +java.lang.ClassLoader.getSystemClassLoader ()Ljava/lang/ClassLoader; +java.lang.System.initializeSystemClass ()V +sun.launcher.LauncherHelper.checkAndLoadMain (ZZLjava/lang/String;)Ljava/lang/Object; + +# The tool doesn't automatically find superclasses and parse the method +# if overridden as it tries to reduce unnecessary classes being pulled in. +# The following forces the dependency to be included the result. +sun.net.www.protocol.file.Handler. ()V +sun.net.www.protocol.jar.Handler. ()V +sun.net.www.protocol.file.Handler.openConnection * +sun.net.www.protocol.jar.Handler.openConnection * +sun.misc.URLClassPath$JarLoader. (Ljava/net/URL;Ljava/net/URLStreamHandler;Ljava/util/HashMap;)V +sun.misc.URLClassPath$FileLoader. (Ljava/net/URL;)V +sun.misc.URLClassPath$FileLoader.getClassPath * +sun.misc.URLClassPath$FileLoader.getResource * +sun.misc.URLClassPath$JarLoader.getResource * +sun.misc.URLClassPath$JarLoader.getClassPath * + +# permission collections +java.io.FilePermission.newPermissionCollection ()Ljava/security/PermissionCollection; +java.security.BasicPermission.newPermissionCollection ()Ljava/security/PermissionCollection; + +# native +java.io.UnixFileSystem +java.io.UnixFileSystem. ()V +java.io.UnixFileSystem.canonicalize * +java.io.Win32FileSystem +java.io.Win32FileSystem. ()V +java.io.Win32FileSystem.canonicalize * +java.io.WinNTFileSystem +java.io.WinNTFileSystem. ()V +java.io.WinNTFileSystem.canonicalize * + +# missing +java.util.HashMap. ()V +java.util.HashMap$EntrySet.iterator * + +# Called from native GetStringPlatformChars (jni_util.c) +java.lang.String.getBytes * + +# charset +sun.nio.cs.US_ASCII.newEncoder ()Ljava/nio/charset/CharsetEncoder; +sun.nio.cs.UTF_8.newEncoder ()Ljava/nio/charset/CharsetEncoder; +sun.nio.cs.UTF_8.newDecoder * +sun.nio.cs.UTF_16.newEncoder ()Ljava/nio/charset/CharsetEncoder; +sun.nio.cs.UTF_16.newDecoder * +sun.nio.cs.UTF_32.newEncoder ()Ljava/nio/charset/CharsetEncoder; +sun.nio.cs.UTF_32.newDecoder * + +# hashcode +java.util.jar.Attributes$Name.hashCode * + +# nio +sun.nio.ByteBuffered +sun.nio.ch.DirectBuffer +java.nio.DirectByteBuffer +java.nio.MappedByteBuffer +java.nio.DirectLongBufferU + +# resource files +sun.launcher.resources.launcher + +sun.misc.Launcher$AppClassLoader.getPermissions * +sun.misc.Launcher$AppClassLoader.loadClass (Ljava/lang/String;)Ljava/lang/Class; +sun.misc.Launcher$AppClassLoader.findClass (Ljava/lang/String;)Ljava/lang/Class; +sun.misc.Launcher$ExtClassLoader.getPermissions * +sun.misc.Launcher$ExtClassLoader.loadClass (Ljava/lang/String;)Ljava/lang/Class; +sun.misc.Launcher$ExtClassLoader.findClass (Ljava/lang/String;)Ljava/lang/Class; +java.lang.ClassLoader.checkPackageAccess * +java.lang.ClassLoader.findClass * +java.lang.ClassLoader.defineClass * +java.net.URLClassLoader.getPermissions * +java.net.URLClassLoader.findClass * +java.net.URLClassLoader.defineClass * +java.security.SecureClassLoader.defineClass * +# need to parse superclasses +java.security.SecureClassLoader. ()V + +exclude sun.security.provider.PolicyFile. +exclude java.lang.ClassLoader.compareCerts +exclude java.security.cert.Certificate.equals +# unsigned jars - no verifier +exclude java.util.jar.JarFile.initializeVerifier +exclude java.util.jar.JarVerifier +exclude sun.security.util.SignatureFileVerifier. + + +# what about other charset +exclude sun.misc.Service +exclude java.util.ServiceLoader + +# exclude support for localized messages +exclude java.util.ResourceBundle.getBundle +exclude java.text.MessageFormat +exclude sun.util.logging.PlatformLogger$LoggerProxy.format * + +# exclude nio and miscellaneous classes +exclude java.nio.channels.** +exclude sun.misc.FloatingDecimal +exclude sun.misc.FormattedFloatingDecimal +exclude sun.misc.FDBigInt diff --git a/jdk/make/modules/jdk7.depconfig b/jdk/make/modules/jdk7.depconfig new file mode 100644 index 0000000000000000000000000000000000000000..286b19e3ad0bf099a0cc917768e655c97f351e9d --- /dev/null +++ b/jdk/make/modules/jdk7.depconfig @@ -0,0 +1,473 @@ +# +# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# private java.lang.Object createInetSocketAddress(java.lang.String, int) +@ClassForName + com.sun.jndi.ldap.Connection -> java.net.InetSocketAddress + com.sun.jndi.ldap.Connection -> java.net.SocketAddress + +# com.sun.jndi.ldap.VersionHelper +@ClassForName(optional) + com.sun.jndi.ldap.VersionHelper -> com.sun.jndi.ldap.VersionHelper* + +# private static void initMethodHandles() +@ClassForName + com.sun.jndi.toolkit.corba.CorbaUtils -> javax.rmi.CORBA.Stub + com.sun.jndi.toolkit.corba.CorbaUtils -> javax.rmi.PortableRemoteObject + +# com.sun.naming.internal.ResourceManager$AppletParameter +@ClassForName(optional) + com.sun.naming.internal.ResourceManager$AppletParameter -> java.applet.Applet + +# private static boolean loadProviderAsService() +@Provider + com.sun.net.httpserver.spi.HttpServerProvider -> META-INF/services/com.sun.net.httpserver.spi.HttpServerProvider + +# com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT +@ClassForName + com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT -> javax.xml.XMLConstants + +# public static java.beans.PersistenceDelegate getPersistenceDelegate(java.lang.Class) +@ClassForName + java.beans.MetaData -> java.beans.*_PersistenceDelegate + +# private static java.lang.reflect.Method getNanosMethod() +@ClassForName(optional) + java.beans.java_sql_Timestamp_PersistenceDelegate -> java.sql.Timestamp + +# java.beans.java_util_Collections$CheckedCollection_PersistenceDelegate +@ClassForName + java.beans.java_util_Collections$CheckedCollection_PersistenceDelegate -> java.util.Collections$CheckedCollection + +# java.beans.java_util_Collections$CheckedMap_PersistenceDelegate +@ClassForName + java.beans.java_util_Collections$CheckedMap_PersistenceDelegate -> java.util.Collections$CheckedMap + +# private static java.lang.Object getType(java.lang.Object) +@ClassForName + java.beans.java_util_EnumMap_PersistenceDelegate -> java.util.EnumMap + +# private java.lang.Integer getAxis(java.lang.Object) +@ClassForName + java.beans.javax_swing_Box_PersistenceDelegate -> javax.swing.BoxLayout + +# java.lang.Double +@Inline + java.lang.Double -> sun.misc.FloatConsts + java.lang.Double -> sun.misc.DoubleConsts + +# java.lang.Float +@Inline + java.lang.Float -> sun.misc.FloatConsts + java.lang.Float -> sun.misc.DoubleConsts + +# java.net.DefaultDatagramSocketImplFactory +@ClassForName(optional) + java.net.DefaultDatagramSocketImplFactory -> java.net.*DatagramSocketImpl + +# private static sun.net.spi.nameservice.NameService createNSProvider(java.lang.String) +@Provider + java.net.InetAddress -> META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor + +# static java.net.InetAddressImpl create() +@ClassForName + java.net.InetAddressImplFactory -> java.net.*Inet[46]AddressImpl + +# private static void init() +@NativeFindClass + java.net.PlainDatagramSocketImpl -> java.io.FileDescriptor + +# java.net.ProxySelector +@ClassForName + java.net.ProxySelector -> sun.net.spi.DefaultProxySelector + +# static java.net.URLStreamHandler getURLStreamHandler(java.lang.String) +@ClassForName(optional) + java.net.URL -> sun.net.www.protocol.*.Handler + +# private java.net.ContentHandler lookupContentHandlerClassFor(java.lang.String) +@ClassForName + java.net.URLConnection -> sun.net.www.content.* + +# private static java.nio.channels.spi.AsynchronousChannelProvider loadProviderAsService() +@Provider + java.nio.channels.spi.AsynchronousChannelProvider$ProviderHolder -> META-INF/services/java.nio.channels.spi.AsynchronousChannelProvider + +# private static boolean loadProviderFromProperty() +@ClassForName + java.nio.channels.spi.SelectorProvider -> sun.nio.ch.DefaultSelectorProvider + +# private static boolean loadProviderAsService() +@Provider + java.nio.channels.spi.SelectorProvider -> META-INF/services/java.nio.channels.spi.SelectorProvider + +# private static java.util.Iterator providers() +@Provider + java.nio.charset.Charset -> META-INF/services/java.nio.charset.spi.CharsetProvider + +# private static void probeExtendedProvider() +@ClassForName(optional) + java.nio.charset.Charset -> sun.nio.cs.ext.ExtendedCharsets + +# public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map, java.lang.ClassLoader) +@Provider + java.nio.file.FileSystems -> META-INF/services/java.nio.file.FileSystemProvider + +# private static java.util.List loadInstalledDetectors() +@Provider + java.nio.file.Files$DefaultFileTypeDetectorHolder -> META-INF/services/java.nio.file.spi.FileTypeDetector + +# public static java.util.List installedProviders() +@Provider + java.nio.file.spi.FileSystemProvider -> META-INF/services/java.nio.file.FileSystemProvider + +# private static java.rmi.server.RMIClassLoaderSpi initializeProvider() +@Provider + java.rmi.server.RMIClassLoader -> META-INF/services/java.rmi.server.RMIClassLoaderSpi + +# private static void initializeSystemScope() +@ClassForName(optional) + java.security.IdentityScope -> sun.security.provider.IdentityDatabase + +# static java.security.Policy getPolicyNoCheck() +@ClassForName + java.security.Policy -> sun.security.provider.PolicyFile + +# private static java.lang.Class getSpiClass(java.lang.String) +@ClassForName + java.security.Security -> java.security.*Spi + +# private static void invalidateSMCache(java.lang.String) +@ClassForName + java.security.Security -> java.lang.SecurityManager + +# private static void loadInitialDrivers() +@Provider + java.sql.DriverManager -> META-INF/services/java.sql.Driver + +# private static java.text.BreakIterator createBreakInstance(java.util.Locale, int, java.lang.String, java.lang.String) +@Provider + java.text.BreakIterator -> META-INF/services/java.util.spi.BreakIteratorProvider + +# public static java.text.Collator getInstance(java.util.Locale) +@Provider + java.text.Collator -> META-INF/services/java.util.spi.CollatorProvider + +# private static java.text.DateFormat get(int, int, int, java.util.Locale) +@Provider + java.text.DateFormat -> META-INF/services/java.util.spi.DateNameProvider + +# public static java.util.Locale[] getAvailableLocales() +@Provider + java.text.DateFormatSymbols -> META-INF/services/java.util.spi.DateFormatSymbolsProvider + +# public static java.util.Locale[] getAvailableLocales() +@Provider + java.text.DecimalFormatSymbols -> META-INF/services/java.util.spi.DecimalFormatSymbolsProvider + +# public static java.util.Locale[] getAvailableLocales() +@Provider + java.text.NumberFormat -> META-INF/services/java.util.spi.NumberFormatProvider + +# public java.lang.String getDisplayName(java.util.Locale) +@Provider + java.util.Currency -> META-INF/services/java.util.spi.CurrencyNameProvider + +# java.util.Formatter +@Inline + java.util.Formatter -> sun.misc.DoubleConsts + +# java.util.Locale +@Inline + java.util.Locale -> java.util.LocaleISOData + +# private java.lang.String getDisplayString(java.lang.String, java.util.Locale, int) +@Provider + java.util.Locale -> META-INF/services/java.util.spi.LocaleNameProvider + +# private static java.util.prefs.PreferencesFactory factory1() +@ClassForName + java.util.prefs.Preferences -> java.util.prefs.WindowsPreferencesFactory + java.util.prefs.Preferences -> java.util.prefs.FileSystemPreferencesFactory + +# private static java.util.prefs.PreferencesFactory factory1() +@Provider + java.util.prefs.Preferences -> META-INF/services/java.util.prefs.PreferencesFactory + +# public void registerApplicationClasspathSpis() +@Provider + javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.IIOServiceProvider + +# private void registerInstalledProviders() +@Provider + javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageReaderSpi + javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageWriterSpi + javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageReaderWriterSpi + javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageTranscoderSpi + javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageInputStreamSpi + javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageOutputStreamSpi + +# public javax.naming.ldap.ExtendedResponse createExtendedResponse(java.lang.String, byte[], int, int) +@Provider + javax.naming.ldap.StartTlsRequest -> META-INF/services/javax.naming.ldap.StartTlsResponse + +# private static java.util.ArrayList getAllLookupServices() +@Provider + javax.print.PrintServiceLookup -> META-INF/services/javax.print.PrintServiceLookup + +# private static java.util.ArrayList getAllFactories() +@Provider + javax.print.StreamPrintServiceFactory -> META-INF/services/javax.print.StreamPrintServiceFactory + +# private void initEngines(java.lang.ClassLoader) +@Provider + javax.script.ScriptEngineManager -> META-INF/services/javax.script.ScriptEngineFactory + +# private void initializeInputMethodLocatorList() +@Provider + sun.awt.im.ExecutableInputMethodManager -> META-INF/services/java.awt.im.spi.InputMethodDescriptor + +# private static java.lang.Class getConverterClass(int, java.lang.String) +@ClassForName(optional) + sun.io.Converters -> sun.io.* + +# public static sun.java2d.cmm.PCMM getModule() +@Provider + sun.java2d.cmm.CMSManager -> META-INF/services/sun.java2d.cmm.PCMM + +# public static sun.java2d.pipe.RenderingEngine getInstance() +@Provider + sun.java2d.pipe.RenderingEngine -> META-INF/services/sun.java2d.pipe.RenderingEngine + +# public static sun.java2d.pipe.RenderingEngine getInstance() +@ClassForName(optional) + sun.java2d.pipe.RenderingEngine -> sun.dc.DuctusRenderingEngine + +# sun.misc.FloatingDecimal +@Inline + sun.misc.FloatingDecimal -> sun.misc.FloatConsts + sun.misc.FloatingDecimal -> sun.misc.DoubleConsts + +# sun.misc.FormattedFloatingDecimal +@Inline + sun.misc.FormattedFloatingDecimal -> sun.misc.FloatConsts + sun.misc.FormattedFloatingDecimal -> sun.misc.DoubleConsts + +# sun.misc.FpUtils +@Inline + sun.misc.FpUtils -> sun.misc.FloatConsts + sun.misc.FpUtils -> sun.misc.DoubleConsts + +# public java.net.URLStreamHandler createURLStreamHandler(java.lang.String) +@ClassForName(optional) + sun.misc.Launcher$Factory -> sun.net.www.protocol.*.Handler + +# private static sun.net.NetHooks$Provider loadProvider(java.lang.String) +@ClassForName(optional) + sun.net.NetHooks -> sun.net.spi.SdpProvider + +# sun.net.idn.StringPrep +@Inline + sun.net.idn.StringPrep -> sun.net.idn.UCharacterDirection + +# private static boolean init() +@NativeFindClass + sun.net.spi.DefaultProxySelector -> java.net.Proxy + sun.net.spi.DefaultProxySelector -> java.net.Proxy$Type + sun.net.spi.DefaultProxySelector -> java.net.InetSocketAddress + +# private static java.nio.channels.Channel createChannel() +@ClassForName + sun.nio.ch.InheritedChannel -> java.io.FileDescriptor + +# private static void initDBBConstructor() +@ClassForName + sun.nio.ch.Util -> java.nio.DirectByteBuffer + +# private static void initDBBRConstructor() +@ClassForName + sun.nio.ch.Util -> java.nio.DirectByteBufferR + +# private java.nio.charset.Charset lookup(java.lang.String) +@ClassForName(optional) + sun.nio.cs.FastCharsetProvider -> sun.nio.cs.* + +# sun.nio.cs.ext.ExtendedCharsets +@ClassForName(optional) + sun.nio.cs.ext.ExtendedCharsets -> sun.nio.cs.ext.* + +# sun.nio.cs.ext.ExtendedCharsets +@ClassForName(optional) + sun.nio.cs.ext.ExtendedCharsets -> sun.nio.cs.ext.* + +# public static java.nio.file.spi.FileSystemProvider create() +@ClassForName + sun.nio.fs.DefaultFileSystemProvider -> sun.nio.fs.SolarisFileSystemProvider + sun.nio.fs.DefaultFileSystemProvider -> sun.nio.fs.LinuxFileSystemProvider + +# sun.rmi.server.MarshalInputStream +@ClassForName + sun.rmi.server.MarshalInputStream -> sun.rmi.server.Activation$ActivationSystemImpl_Stub + sun.rmi.server.MarshalInputStream -> sun.rmi.registry.RegistryImpl_Stub + +# private java.security.Provider doLoadProvider() +@ClassForName(optional) + sun.security.jca.ProviderConfig -> sun.security.pkcs11.SunPKCS11 + sun.security.jca.ProviderConfig -> sun.security.provider.Sun + sun.security.jca.ProviderConfig -> sun.security.rsa.SunRsaSign + sun.security.jca.ProviderConfig -> sun.security.ec.SunEC + sun.security.jca.ProviderConfig -> com.sun.net.ssl.internal.ssl.Provider + sun.security.jca.ProviderConfig -> com.sun.crypto.provider.SunJCE + sun.security.jca.ProviderConfig -> sun.security.jgss.SunProvider + sun.security.jca.ProviderConfig -> com.sun.security.sasl.Provider + sun.security.jca.ProviderConfig -> org.jcp.xml.dsig.internal.dom.XMLDSigRI + sun.security.jca.ProviderConfig -> sun.security.smartcardio.SunPCSC + sun.security.jca.ProviderConfig -> sun.security.mscapi.SunMSCAPI + +# public static java.security.Provider getSunProvider() +@ClassForName + sun.security.jca.Providers -> sun.security.provider.Sun + sun.security.jca.Providers -> sun.security.provider.VerificationProvider + +# private static sun.security.jgss.spi.MechanismFactory getMechFactoryImpl(java.security.Provider, java.lang.String, org.ietf.jgss.Oid, sun.security.jgss.GSSCaller) +@ClassForName + sun.security.jgss.ProviderList -> sun.security.jgss.spi.MechanismFactory + +# sun.security.jgss.wrapper.SunNativeProvider +@NativeFindClass + sun.security.jgss.wrapper.SunNativeProvider -> org.ietf.jgss.Oid + sun.security.jgss.wrapper.SunNativeProvider -> org.ietf.jgss.GSSException + sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.GSSNameElement + sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.GSSCredElement + sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.NativeGSSContext + sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.SunNativeProvider + sun.security.jgss.wrapper.SunNativeProvider -> org.ietf.jgss.MessageProp + sun.security.jgss.wrapper.SunNativeProvider -> org.ietf.jgss.ChannelBinding + sun.security.jgss.wrapper.SunNativeProvider -> java.net.InetAddress + sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.GSSLibStub + +# static void ensureLoaded() +@NativeFindClass + sun.security.krb5.Credentials -> sun.security.krb5.internal.Krb5 + sun.security.krb5.Credentials -> sun.security.krb5.internal.Ticket + sun.security.krb5.Credentials -> sun.security.krb5.PrincipalName + sun.security.krb5.Credentials -> sun.security.util.DerValue + sun.security.krb5.Credentials -> sun.security.krb5.EncryptionKey + sun.security.krb5.Credentials -> sun.security.krb5.internal.TicketFlags + sun.security.krb5.Credentials -> sun.security.krb5.internal.KerberosTime + +# public static java.lang.String getDefaultCacheName() +@ClassForName(optional) + sun.security.krb5.internal.ccache.FileCredentialsCache -> com.sun.security.auth.module.UnixSystem + +# sun.security.pkcs.PKCS9Attribute +@ClassForName + sun.security.pkcs.PKCS9Attribute -> sun.security.util.ObjectIdentifier + sun.security.pkcs.PKCS9Attribute -> java.util.Date + sun.security.pkcs.PKCS9Attribute -> sun.security.pkcs.SignerInfo + sun.security.pkcs.PKCS9Attribute -> sun.security.x509.CertificateExtensions + +# protected T engineGetKeySpec(java.security.Key, java.lang.Class) +@ClassForName + sun.security.provider.DSAKeyFactory -> java.security.spec.DSAPublicKeySpec + sun.security.provider.DSAKeyFactory -> java.security.spec.X509EncodedKeySpec + sun.security.provider.DSAKeyFactory -> java.security.spec.DSAPrivateKeySpec + sun.security.provider.DSAKeyFactory -> java.security.spec.PKCS8EncodedKeySpec + +# protected T engineGetParameterSpec(java.lang.Class) +@ClassForName + sun.security.provider.DSAParameters -> java.security.spec.DSAParameterSpec + +# sun.security.provider.VerificationProvider +@ClassForName(optional) + sun.security.provider.VerificationProvider -> sun.security.provider.Sun + sun.security.provider.VerificationProvider -> sun.security.rsa.SunRsaSign + +# sun.security.provider.certpath.URICertStore$LDAP +@ClassForName(optional) + sun.security.provider.certpath.URICertStore$LDAP -> sun.security.provider.certpath.ldap.LDAPCertStoreHelper + +# sun.security.smartcardio.PCSC +@NativeFindClass + sun.security.smartcardio.PCSC -> sun.security.smartcardio.PCSCException + +# sun.security.ssl.HandshakeMessage +@ClassForName + sun.security.ssl.HandshakeMessage -> java.security.MessageDigest$Delegate + +# sun.security.ssl.JsseJce +@ClassForName(optional) + sun.security.ssl.JsseJce -> sun.security.krb5.PrincipalName + +# sun.security.x509.OIDMap$OIDInfo +@ClassForName + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.SubjectKeyIdentifierExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.KeyUsageExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.PrivateKeyUsageExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.SubjectAlternativeNameExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.IssuerAlternativeNameExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.BasicConstraintsExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CRLNumberExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CRLReasonCodeExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.NameConstraintsExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.PolicyMappingsExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.AuthorityKeyIdentifierExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.PolicyConstraintsExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.NetscapeCertTypeExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CertificatePoliciesExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.ExtendedKeyUsageExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.InhibitAnyPolicyExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CRLDistributionPointsExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CertificateIssuerExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.SubjectInfoAccessExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.AuthorityInfoAccessExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.IssuingDistributionPointExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.DeltaCRLIndicatorExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.FreshestCRLExtension + sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.OCSPNoCheckExtension + +# sun.util.LocaleServiceProviderPool$AllAvailableLocales +@Provider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.BreakIteratorProvider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.CollatorProvider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.DateFormatProvider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.DateFormatSymbolsProvider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.DecimalFormatSymbolsProvider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.NumberFormatProvider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.util.spi.CurrencyNameProvider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.util.spi.LocaleNameProvider + sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.util.spi.TimeZoneNameProvider + +# private static final java.lang.String[] retrieveDisplayNames(sun.util.resources.OpenListResourceBundle, java.lang.String, java.util.Locale) +@Provider + sun.util.TimeZoneNameUtility -> META-INF/services/java.util.spi.TimeZoneNamePProvider + +# public static sun.util.calendar.CalendarSystem forName(java.lang.String) +@ClassForName + sun.util.calendar.CalendarSystem -> sun.util.calendar.Gregorian + sun.util.calendar.CalendarSystem -> sun.util.calendar.LocalGregorianCalendar + sun.util.calendar.CalendarSystem -> sun.util.calendar.JulianCalendar + +# sun.util.logging.LoggingSupport +@ClassForName(optional) + sun.util.logging.LoggingSupport -> java.util.logging.LoggingProxyImpl diff --git a/jdk/make/modules/modules.config b/jdk/make/modules/modules.config new file mode 100644 index 0000000000000000000000000000000000000000..04b71ea6a51a8da00606c6b03f4a48ba91609e60 --- /dev/null +++ b/jdk/make/modules/modules.config @@ -0,0 +1,858 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +// These classes are not referenced in the JDK but we can't +// remove them for compatibility reason. Define this module +// first so that other modules don't need to exclude these clases +module private-legacy { + include sun.misc.Cache*, + sun.misc.ClassLoaderUtil, + sun.misc.Compare, + sun.misc.ConditionLock, + sun.misc.CRC16, + sun.misc.Lock, + sun.misc.Regexp, + sun.misc.RequestProcessor, + sun.misc.Sort, + sun.misc.Request, + sun.misc.Timeable, + sun.misc.Timer, + sun.misc.TimerThread, + sun.misc.TimerTickThread, + sun.misc.UCDecoder, + sun.misc.UCEncoder, + sun.misc.UUDecoder, + sun.misc.UUEncoder, + com.sun.net.ssl.SSLContext, + sun.net.NetworkServer, + sun.net.URLCanonicalizer, + sun.reflect.misc.ConstructorUtil, + sun.reflect.FieldInfo, + sun.reflect.SignatureIterator, + sun.reflect.generics.reflectiveObjects.NotImplementedException, + sunw.io.Serializable, + sunw.util.EventListener, + sunw.util.EventObject; +} + +// Deprecated classes that aren't referenced/used go here. +module deprecated { + // add deprecated security classes once b78 is promoted +} + +/**************************************************************************/ + +module base { + // core classes + include java.lang.*, + java.lang.annotation.*, + java.lang.ref.*, + java.lang.reflect.*, + java.math.*, + java.net.*, + java.util.*, + java.util.concurrent.**, + java.util.jar.*, + java.util.regex.*, + java.util.spi.*, + java.util.zip.*, + java.text.**; + + exclude java.util.jar.Pack200*, + java.util.XMLUtils, + java.text.Bidi; + + include java.io.*, java.nio.*, java.nio.charset.**; + exclude java.io.TempFileHelper, java.nio.BufferPoolMXBean; + + // security APIs + // javax.crypto and javax.security.auth are included to avoid inconsistent + // spliting of JCA and JAAS. This adds about 85k. Also note that some deprecated + // classes must be included for now (see 6876158, 6876170) + include java.security.*, + java.security.cert.*, + java.security.interfaces.*, + java.security.spec.*, + javax.security.auth.**, + javax.crypto.**; + + // Sun and RSA security providers (except LDAP CertStore) + // roots sun.security.provider.* sun.security.provider.certpath.* sun.security.rsa.* + include com.sun.security.auth.PrincipalComparator, + com.sun.security.auth.SubjectCodeSource, + com.sun.security.auth.login.**, + com.sun.security.auth.Policy*, + sun.security.action.*, + sun.security.ec.*, + sun.security.jca.*, + sun.security.pkcs.*, + sun.security.provider.*, + sun.security.provider.certpath.*, + sun.security.rsa.*, + sun.security.util.*, + sun.security.validator.*, + sun.security.x509.*, + sun.security.timestamp.*; + + // this list is based on the classlist generated from the rootset + // need investigation + exclude sun.security.ec.ECD*, + sun.security.ec.ECKeyPairGenerator, + sun.security.ec.SunEC*, + sun.security.pkcs.PKCS10*, + sun.security.pkcs.EncodingException, + sun.security.util.AuthResources_*, + sun.security.util.Resources_*, + sun.security.util.BigInt, + sun.security.util.HostnameChecker, + sun.security.x509.CertAndKeyGen, + sun.security.util.PathList; + + // Kerberos not needed + exclude javax.security.auth.kerberos.**, + sun.security.jgss.**, + sun.security.krb5.**, + sun.security.ssl.Kerberos*, + org.ietf.jgss.**; + + // property events and annotations + include java.beans.ChangeListenerMap, + java.beans.IndexedPropertyChangeEvent, + java.beans.PropertyChange*, + java.beans.PropertyVetoException, + java.beans.VetoableChange*, + java.beans.ConstructorProperties; + + // mandatory charsets + include sun.nio.cs.*; + + exclude sun.nio.cs.AbstractCharsetProvider, + sun.nio.cs.CharsetMapping, + sun.nio.cs.IBM*, + sun.nio.cs.ISO*, + sun.nio.cs.KOI8_*, + sun.nio.cs.MS125*, + sun.nio.cs.UTF_32*, + sun.nio.cs.SingleByteDecoder, + sun.nio.cs.SingleByteEncoder; + + allow sun.nio.cs.ISO_8859_1, + sun.nio.cs.ISO_8859_15, + sun.nio.cs.MS1252; + + include sun.text.*, + sun.text.normalizer.*; + + // resource files + include sun/text/resources/*.icu; + + exclude sun.text.bidi.*, + sun.text.CharArrayCodePointIterator, + sun.text.CharSequenceCodePointIterator, + sun.text.CharacterIteratorCodePointIterator, + sun.text.CodePointIterator; + + include sun.util.*, + sun.util.calendar.*, + sun.util.logging.*, + sun.util.resources.LocaleData, + sun.util.resources.LocaleNamesBundle, + sun.util.resources.OpenListResourceBundle; + + // US_en locale + include sun.text.resources.BreakIteratorInfo, + sun.text.resources.FormatData, + sun.text.resources.FormatData_en_US, + sun.util.resources.CalendarData, + sun.util.resources.CalendarData_en, + sun.util.resources.TimeZoneNames, + sun.util.resources.TimeZoneNames_en, + sun.util.resources.TimeZoneNamesBundle, + sun.util.resources.LocaleNames, + sun.util.resources.LocaleNames_en, + sun.util.resources.LocalenamesBundles, + sun.util.resources.CurrencyNames, + sun.util.resources.CurrencyNames_en_US, + sun.util.EmptyListResourceBundle; + + // resources file needed by + // - sun.misc.ExtensionInfo + // - sun.security.provider.PolicyFile + // - com.sun.security.auth.PolicyFile + include sun.misc.resources.Messages, + sun.security.util.Resources, + sun.security.util.AuthResources; + + // java.nio.channels and java.nio.file not in base + include sun.nio.ch.Interruptible, + sun.nio.ch.DirectBuffer, + sun.nio.ByteBuffered; + + include sun.reflect.**; + + // protocol handlers + include sun.net.www.protocol.file.*, + sun.net.www.protocol.jar.*, + sun.net.www.protocol.http.*; + + include sun.net.*, + sun.net.spi.*, + sun.net.idn.*, + sun.net.util.*, + sun.net.www.*, + sun.net.www.http.*, + sun.net.spi.nameservice.*; + + // resource file for sun.net.idn + include sun/net/idn/*; + + // classes in net-compat + exclude sun.net.Telnet*, sun.net.TransferProtocolClient; + + // classes in deploy + exclude sun.net.www.protocol.http.AuthCacheBridge; + + // classes in security-jsse + exclude java.net.SecureCacheResponse; + + // launcher + include sun.launcher.LauncherHelper, sun.launcher.resources.launcher; + + include sun.misc.*; + exclude sun.misc.FIFOQueueEnumerator, + sun.misc.LIFOQueueEnumerator, + sun.misc.GC, + sun.misc.PerformanceLogger, + sun.misc.Queue, + sun.misc.QueueElement, + sun.misc.Ref, + sun.misc.VMSupport; + + // On Windows, OSEnvironment dependency + include sun.io.Win32ErrorMode; +} + +/**************************************************************************/ + +module charsets { + include sun.nio.cs.ext.**; + + include sun.nio.cs.AbstractCharsetProvider, + sun.nio.cs.CharsetMapping, + sun.nio.cs.IBM*, + sun.nio.cs.ISO*, + sun.nio.cs.KOI8_*, + sun.nio.cs.MS125*, + sun.nio.cs.SingleByte*, + sun.nio.cs.UTF_32*; + + exclude sun.nio.cs.ISO_8859_1, + sun.nio.cs.MS1252; + + // legacy sun.io converters + include sun.io.*; +} + +/**************************************************************************/ + +// For now, retains the current JRE extensions where localedata.jar in jre/lib/ext +module localedata { + include sun.util.resources.*_ar, + sun.util.resources.*_ar_*, + sun.util.resources.*_hi, + sun.util.resources.*_hi_*, + sun.util.resources.*_iw, + sun.util.resources.*_iw_*, + sun.util.resources.*_ja, + sun.util.resources.*_ja_*, + sun.util.resources.*_ko, + sun.util.resources.*_ko_*, + sun.util.resources.*_th, + sun.util.resources.*_th_*, + sun.util.resources.*_vi, + sun.util.resources.*_vi_*, + sun.util.resources.*_zh, + sun.util.resources.*_zh_*; + include sun.text.resources.*_ar, + sun.text.resources.*_ar_*, + sun.text.resources.*_hi, + sun.text.resources.*_hi_*, + sun.text.resources.*_iw, + sun.text.resources.*_iw_*, + sun.text.resources.*_ja, + sun.text.resources.*_ja_*, + sun.text.resources.*_ko, + sun.text.resources.*_ko_*, + sun.text.resources.*_th, + sun.text.resources.*_th_*, + sun.text.resources.*_vi, + sun.text.resources.*_vi_*, + sun.text.resources.*_zh, + sun.text.resources.*_zh_*; +} + +module resources { + include sun.text.resources.*, sun.util.resources.*, sun.misc.resources.*; +} + +/**************************************************************************/ + +module nio { + include java.nio.channels.**, java.nio.file.**, com.sun.nio.file.**; + + // this is excluded from base + include java.io.TempFileHelper; + + // provider implementations and their dependencies + include sun.nio.ch.*, sun.nio.fs.**; + exclude sun.nio.ch.Sctp*; +} + +/**************************************************************************/ + +module pack200 { + include java.util.jar.Pack200*, com.sun.java.util.jar.pack.**; +} + +/**************************************************************************/ + +module logging { + include java.util.logging.*, sun.util.logging.**; + exclude java.util.logging.PlatformLoggingMXBean; + + // Formatter for HTTP messages + include sun.net.www.protocol.http.logging.*; +} + +/**************************************************************************/ + +module management-snmp { + include com.sun.jmx.snmp.**, sun.management.snmp.**; +} + +module management-iiop { + include com.sun.jmx.remote.protocol.iiop.*; + + // stubs and ties + include javax.management.remote.rmi._*, + org.omg.stub.javax.management.remote.rmi.**; +} + +module management { + include java.lang.management.*, com.sun.management.**, sun.management.**; + include javax.management.**, com.sun.jmx.**; + + // other management interfaces + include java.nio.BufferPoolMXBean; + include java.util.logging.PlatformLoggingMXBean; + + // supporting classes in sun.misc + include sun.misc.VMSupport; +} + +/**************************************************************************/ + +module instrument { + // java.lang.instrument + include java.lang.instrument.*, sun.instrument.*; + + // tracing + include com.sun.tracing.**, sun.tracing.**; + + // HPROF support + include com.sun.demo.jvmti.hprof.*; +} + +/**************************************************************************/ + +module rmi-activation { + include java.rmi.activation.**, + sun.rmi.server.Act*, + sun.rmi.server.InactiveGroupException; +} + +module rmi { + include java.rmi.**, sun.rmi.**, com.sun.rmi.**; + + // SSL factories are in rmi + include javax.rmi.ssl.**; + + // rmic is in tools + exclude sun.rmi.rmic.**; + + // supporting classes in sun.misc and dependencies + include sun.misc.GC; +} + +/**************************************************************************/ + +module prefs { + include java.util.prefs.*; +} + +/**************************************************************************/ + +module security-jsse { + include javax.net.**, + javax.security.cert.*, + java.net.SecureCacheResponse, + com.sun.net.ssl.**, + com.sun.security.cert.internal.x509.*, + sun.security.ssl.*, + sun.net.www.protocol.https.**, + sun.security.internal.interfaces.Tls*, + sun.security.internal.spec.Tls*, + sun.security.util.HostnameChecker; +} + +module security-sunpkcs11 { + include sun.security.pkcs11.**; +} + +module security-sunjce { + include com.sun.crypto.provider.*; +} + +module security-sunec { + include sun.security.ec.*; +} + +module security-sunmscapi { + include sun.security.mscapi.*; +} + +module security-kerberos { + include javax.security.auth.kerberos.*, + com.sun.security.jgss.**, + com.sun.security.auth.module.Krb5LoginModule, + com.sun.security.sasl.gsskerb.**, // GSSAPI SASL mechanism + sun.security.jgss.**, + sun.security.ssl.krb5.**, + sun.security.krb5.**, + org.ietf.jgss.**, + sun.net.www.protocol.http.spnego.*; +} + +module security-sasl { + include javax.security.sasl.**, + com.sun.security.sasl.**; +} + +module security-xmldsig { + include javax.xml.crypto.**, + org.jcp.xml.dsig.**, + com.sun.org.apache.xml.internal.security.**; +} + +module security-smartcardio { + include javax.smartcardio.**, sun.security.smartcardio.**; +} + +module security-misc { + include com.sun.security.auth.**, sun.security.util.AuthResources_*, + sun.security.pkcs.*, + sun.security.pkcs12.*; + + // this class is a candidate to be removed. + include sun.security.util.BigInt; +} + +module security-resources { + include sun.security.util.Resources_*; +} + +module security-compat { + include java.security.acl.*, sun.security.acl.*; +} + +/**************************************************************************/ + +module jndi-ldap { + include javax.naming.ldap.**, + com.sun.jndi.ldap.**, + com.sun.jndi.url.ldap.*, + com.sun.jndi.url.ldaps.*, + sun.security.provider.certpath.ldap.**; +} + +module jndi-rmiregistry { + include com.sun.jndi.rmi.**, com.sun.jndi.url.rmi.**; +} + +module jndi-dns { + include com.sun.jndi.dns.**, com.sun.jndi.url.dns.**; + include sun.net.dns.**; // to access DNS config. + include sun.net.spi.nameservice.dns.**; // for DNS-only name service. +} + +module jndi-cosnaming { + include com.sun.jndi.cosnaming.**, + com.sun.jndi.toolkit.corba.**, + com.sun.jndi.url.corbaname.**, + com.sun.jndi.url.iiop.**, + com.sun.jndi.url.iiopname.**; +} + +// framework/API and classes used by providers +module jndi { + include javax.naming.**, + com.sun.naming.**, + com.sun.jndi.toolkit.ctx.**, + com.sun.jndi.toolkit.dir.**, + com.sun.jndi.toolkit.url.**; +} + +/**************************************************************************/ + +module jdbc-base { + include java.sql.**, javax.sql.*; + exclude javax.sql.XA*; +} + +module jdbc-enterprise { + include javax.sql.**, com.sun.rowset.**; +} + +module jdbc-odbc { + include sun.jdbc.odbc.**; +} + +/**************************************************************************/ + +module scripting { + include javax.script.**; + + // supporting classes for scripting engines + include com.sun.script.util.**; +} + +module scripting-rhino { + include com.sun.script.javascript.**, sun.org.mozilla.javascript.**; +} + +/**************************************************************************/ + +module httpserver { + include com.sun.net.httpserver.**, sun.net.httpserver.**; +} + +/**************************************************************************/ + +module sctp { + // API and dependencies + include com.sun.nio.sctp.**, sun.nio.ch.Sctp*; +} + +/**************************************************************************/ + +module langtools { + include javax.tools.**, javax.lang.model.**, javax.annotation.processing.**; + + // include mirror API for now + include com.sun.mirror.**; + + // include the JSR292 APIs for now + include java.dyn.**, sun.dyn.**; +} + +/**************************************************************************/ + +module beans { + include java.beans.**, com.sun.beans.**, sun.beans.**; +} + +/**************************************************************************/ + +module jaxp-parsers-api { + include javax.xml.*, javax.xml.parsers.**, + org.w3c.dom.**, org.w3c.sax.**, org.xml.sax.**; +} + +module jaxp-api { + include javax.xml.**; + exclude javax.xml.crypto.**, // XML-DSIG + javax.xml.bind.**, // JAX-WS + javax.xml.soap.**, + javax.xml.ws.**; +} + +module jaxp-xerces-impl { + include com.sun.org.apache.xerces.internal.**; + + // include in xerces-impl due to circular dependencies + include com.sun.org.apache.xml.internal.serialize.**, + com.sun.xml.internal.stream.**; + exclude com.sun.xml.internal.stream.buffer.**; // JAX-WS +} + +// required by Xerces and JAX-WS +module jaxp-xerces-resolver { + include com.sun.org.apache.xml.internal.resolver.**; +} + +module jaxp-xalan { + include com.sun.org.apache.xalan.internal.**, + com.sun.org.apache.xpath.internal.**, + com.sun.org.apache.xml.internal.dtm.**, + com.sun.org.apache.xml.internal.res.**, + com.sun.org.apache.xml.internal.serializer.**, + com.sun.org.apache.xml.internal.utils.**, + com.sun.org.apache.bcel.internal.**, + com.sun.org.apache.regexp.internal.**, + com.sun.java_cup.internal.**; +} + +/**************************************************************************/ + +module jaxws-tools { + include com.sun.codemodel.**, + com.sun.xml.internal.dtdparser.**, + com.sun.xml.internal.rngom.**, + com.sun.xml.internal.xsom.**, + com.sun.istack.internal.tools.**, + com.sun.istack.internal.ws.**, + com.sun.tools.internal.xjc.**, + com.sun.tools.internal.ws.**, + com.sun.tools.internal.jxc.**, + org.relaxng.datatype.**; +} + +module jaxws { + include javax.jws.**, + javax.xml.bind.**, + javax.xml.soap.**, + javax.xml.ws.**, + org.relaxng.**, + com.sun.istack.internal.*, + com.sun.istack.internal.localization.*, + com.sun.xml.internal.**; + + // include JAF in this module + include javax.activation.**, com.sun.activation.**; + + include META-INF/mailcap.default, + META-INF/mimetypes.default; +} + +/**************************************************************************/ +module enterprise-base { + include javax.transaction.**, // JTA + javax.annotation.*; // Common annotations (JSR-250) +} + +/**************************************************************************/ +module corba { + include javax.activity.**, + javax.rmi.*, + javax.rmi.CORBA.*, + javax.transaction.**, + com.sun.corba.**, + com.sun.org.omg.**, + org.omg.**, + sun.corba.**; + + // JMX remote API + exclude org.omg.stub.javax.management.**; +} + +/**************************************************************************/ + +module client { + include java.applet.**, + java.awt.**, + javax.accessibility.*, + javax.imageio.**, + javax.print.**, + javax.sound.**, + javax.swing.**, + sun.applet.**, + sun.audio.**, + sun.awt.**, + sun.dc.**, + sun.font.**, + sun.java2d.**, + sun.print.**, + sun.swing.**, + com.sun.accessibility.**, + com.sun.awt.**, + com.sun.image.**, + com.sun.imageio.**, + com.sun.java.swing.*, // sajdi also contains classes in a subpackage; + // so use '*' instead of '**' + com.sun.java.swing.plaf.**, + com.sun.media.**, + com.sun.swing.**; + + // Bidi class in client module for now + include java.text.Bidi, sun.text.bidi.*; + + // PerformanceLogger and dependencies + include sun.misc.Ref, sun.misc.PerformanceLogger; + + // misc. dependencies that we need to examine + include sun.text.CodePointIterator, + sun.text.Char*, + sun.misc.Queue*, + sun.misc.FIFOQueueEnumerator, + sun.misc.LIFOQueueEnumerator; + + // content handlers + include sun.net.www.content.audio.**, + sun.net.www.content.image.**; +} + +/**************************************************************************/ + +module deploy { + // For now, all plugin and JNLP + include com.sun.java.browser.**, + netscape.**, + sun.plugin.**, + sun.plugin2.**,, + com.sun.deploy.**, + com.sun.javaws.**, + javax.jnlp.*, + com.sun.jnlp.*, + sun.jkernel.*; + + // Hook for http authentication + include sun.net.www.protocol.http.AuthCacheBridge; +} + +/**************************************************************************/ + +module net-compat { + // NTLM authentication support + include sun.net.www.protocol.http.ntlm.*; + + // ftp and mail clients + include sun.net.ftp.**, sun.net.smtp.**; + + // Legacy protocol handlers + include sun.net.www.protocol.**; + + // Legacy content handlers + include sun.net.www.content.**; + + include sun.net.Telnet*, + sun.net.TransferProtocolClient; +} + +/**************************************************************************/ + +// jar-tool and security-tools are JRE tools +module jar-tool { + include sun.tools.jar.**; +} + +module security-tools { + include sun.security.tools.**; + + // Used by security tools + include sun.security.util.PathList, sun.security.x509.CertAndKeyGen; + + exclude sun.security.tools.JarBASE64Encoder, + sun.security.tools.JarSigner, + sun.security.tools.JarSignerParameters, + sun.security.tools.JarSignerResources*, + sun.security.tools.SignatureFile, + sun.security.tools.TimestampedSigner; +} + +module jconsole { + include sun.tools.jconsole.**, + com.sun.tools.jconsole.*; +} + +module serialver { + include sun.tools.serialver.**; +} + +module gui-tools { + include jconsole, + serialver; + + include com.sun.tools.example.debug.bdi.**, + com.sun.tools.example.debug.gui.**, + com.sun.tools.internal.xjc.**; +} + +module attach { + include com.sun.tools.attach.**, + sun.tools.attach.**; +} + +module debugging { + include com.sun.jdi.**, com.sun.tools.jdi.**; +} + +module jdb { + include com.sun.tools.example.debug.**; +} + +module sajdi { + include sun.jvm.hotspot.**, + com.sun.java.swing.ui.**, + com.sun.java.swing.action.**; + + include toolbarButtonGraphics/**; + include sa.properties; +} + +module tools { + include attach, + debugging, + jaxws-tools, + jdb, + sajdi; + + // include gui-tools in tools module unless the tool binaries + // are modified to load the new gui-tools.jar + include gui-tools; + + include com.sun.tools.**, sun.tools.**, sun.security.tools.**, + com.sun.jarsigner.**, + com.sun.javac.**, + com.sun.javadoc.**, com.sun.source.**, + sun.jvmstat.**, + sun.rmi.rmic.**; +} + +/**************************************************************************/ + +module servicetag { + include com.sun.servicetag.**; +} + +/**************************************************************************/ + +// these classes will be removed from JRE - see 6909002 +module inputmethods-ext { + include com.sun.inputmethods.internal.**; +} + +/**************************************************************************/ + +module other { + include **; +} diff --git a/jdk/make/modules/modules.group b/jdk/make/modules/modules.group new file mode 100644 index 0000000000000000000000000000000000000000..64abd180718f7ecff8f22d8e37571b73dd9bcc6f --- /dev/null +++ b/jdk/make/modules/modules.group @@ -0,0 +1,29 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * Example: + * module jdbc { + * include jdbc-base, jdbc-enterprise, jdbc-odbc; + * } + */ diff --git a/jdk/make/modules/optional.depconfig b/jdk/make/modules/optional.depconfig new file mode 100644 index 0000000000000000000000000000000000000000..0811163e7150013ee9937cdf733b19909e71e09b --- /dev/null +++ b/jdk/make/modules/optional.depconfig @@ -0,0 +1,124 @@ +# public final java.nio.channels.SocketChannel getChannel() +@Optional + sun.security.ssl.BaseSSLSocketImpl -> java.nio.channels.SocketChannel + +# public XMLDecoder(java.io.InputStream) +# public XMLDecoder(java.io.InputStream, java.lang.Object) +# public XMLDecoder(java.io.InputStream, java.lang.Object, java.beans.ExceptionListener) +# public XMLDecoder(java.io.InputStream, java.lang.Object, java.beans.ExceptionListener, java.lang.ClassLoader) +# public XMLDecoder(org.xml.sax.InputSource) +@Optional + java.beans.XMLDecoder -> com.sun.beans.decoder.DocumentHandler + java.beans.XMLDecoder -> org.xml.sax.InputSource + +# public static org.xml.sax.helpers.DefaultHandler createHandler(java.lang.Object, java.beans.ExceptionListener, java.lang.ClassLoader) +@Optional + java.beans.XMLDecoder -> com.sun.beans.decoder.DocumentHandler + java.beans.XMLDecoder -> org.xml.sax.helpers.DefaultHandler + +# public final java.nio.channels.FileChannel getChannel() +@Optional + java.net.SocketInputStream -> java.nio.channels.FileChannel + +# public final java.nio.channels.FileChannel getChannel() +@Optional + java.net.SocketOutputStream -> java.nio.channels.FileChannel + +# public Scanner(java.io.File) +# public Scanner(java.io.File, java.lang.String) +@Optional + java.util.Scanner -> java.nio.channels.ReadableByteChannel + java.util.Scanner -> java.nio.channels.Channels + +# public Scanner(java.nio.file.FileRef) +# public Scanner(java.nio.file.FileRef, java.lang.String) +@Optional + java.util.Scanner -> java.nio.file.FileRef + java.util.Scanner -> java.nio.file.OpenOption + +# public Scanner(java.nio.channels.ReadableByteChannel) +# public Scanner(java.nio.channels.ReadableByteChannel, java.lang.String) +@Optional + java.util.Scanner -> java.nio.channels.ReadableByteChannel + java.util.Scanner -> java.nio.channels.Channels + +# private static void loadSnmpAgent(java.lang.String, java.util.Properties) +@Optional + sun.management.Agent -> sun.management.snmp.AdaptorBootstrap + +# public void connect() +@Optional + sun.net.www.protocol.http.HttpURLConnection -> java.net.SecureCacheResponse + +# private static sun.security.util.PermissionFactory permissionFactory() +@Optional + sun.security.util.SecurityConstants$AWT -> sun.awt.AWTPermissionFactory + +# sun.util.logging.LoggingSupport +@Optional + sun.util.logging.LoggingSupport -> java.util.logging.LoggingProxyImpl + +# public java.nio.channels.DatagramChannel getChannel() +@Optional + java.net.DatagramSocket -> java.nio.channels.DatagramChannel + +# public java.nio.channels.SocketChannel getChannel() +@Optional + java.net.Socket -> java.nio.channels.SocketChannel + +# public java.nio.channels.ServerSocketChannel getChannel() +@Optional + java.net.ServerSocket -> java.nio.channels.ServerSocketChannel + +# public final java.nio.channels.FileChannel getChannel() +@Optional + java.io.RandomAccessFile -> java.nio.channels.FileChannel + java.io.RandomAccessFile -> sun.nio.ch.FileChannelImpl + +# public static sun.nio.cs.StreamDecoder forDecoder(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int) +@Optional + sun.nio.cs.StreamDecoder -> java.nio.channels.ReadableByteChannel + +# private static java.nio.channels.FileChannel getChannel(java.io.FileInputStream) +# StreamDecoder(java.io.InputStream, java.lang.Object, java.nio.charset.CharsetDecoder) +@Optional + sun.nio.cs.StreamDecoder -> java.nio.channels.FileChannel + +# StreamDecoder(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int) +@Optional + sun.nio.cs.StreamDecoder -> java.nio.channels.ReadableByteChannel + +# public static java.io.File createTemporaryFile(java.lang.String, java.lang.String, java.nio.file.attribute.FileAttribute[]) +@Optional + java.io.File -> java.io.TempFileHelper + java.io.File -> java.nio.file.attribute.FileAttribute + +# public java.nio.file.Path toPath() +@Optional + java.io.File -> java.nio.file.Paths + java.io.File -> java.nio.file.Path + +# public static sun.nio.cs.StreamEncoder forEncoder(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int) +# private StreamEncoder(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int) +@Optional + sun.nio.cs.StreamEncoder -> java.nio.channels.WritableByteChannel + +# public java.nio.channels.FileChannel getChannel() +@Optional + java.io.FileOutputStream -> java.nio.channels.FileChannel + java.io.FileOutputStream -> sun.nio.ch.FileChannelImpl + +# public java.nio.channels.FileChannel getChannel() +@Optional + java.io.FileInputStream -> java.nio.channels.FileChannel + java.io.FileInputStream -> sun.nio.ch.FileChannelImpl + +# public void loadFromXML(java.io.InputStream) +# public void storeToXML(java.io.OutputStream, java.lang.String, java.lang.String) +@Optional + java.util.Properties -> java.util.XMLUtils + +# public static java.nio.channels.Channel inheritedChannel() +@Optional + java.lang.System -> java.nio.channels.Channel + java.lang.System -> java.nio.channels.spi.SelectorProvider diff --git a/jdk/make/modules/tools/Makefile b/jdk/make/modules/tools/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..fcf514bec888bfe33a431fb79b40c7c119dc8c2e --- /dev/null +++ b/jdk/make/modules/tools/Makefile @@ -0,0 +1,85 @@ +# +# Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# +# Makefile for building the classanalyzer tool +# + +BUILDDIR = ../.. +PACKAGE = com.sun.classanalyzer +PRODUCT = tools +PROGRAM = classanalyzer +include $(BUILDDIR)/common/Defs.gmk + +BUILDTOOL_SOURCE_ROOT = src +BUILDTOOL_MAIN = $(PKGDIR)/ClassAnalyzer.java +BUILTTOOL_MAINCLASS = $(subst /,.,$(BUILDTOOL_MAIN:%.java=%)) + +BUILDTOOL_MAIN_SOURCE_FILE = $(BUILDTOOL_SOURCE_ROOT)/$(BUILDTOOL_MAIN) +BUILDTOOL_MANIFEST_FILE = $(BUILDTOOLCLASSDIR)/$(PROGRAM)_manifest.mf +BUILDTOOL_JAR_FILE = $(BUILDTOOLJARDIR)/$(PROGRAM).jar + +FILES_java := $(shell $(CD) $(BUILDTOOL_SOURCE_ROOT) \ + && $(FIND) $(PKGDIR) $(SCM_DIRS_prune) -o -type f -print) +FILES_class = $(FILES_java:%.java=$(BUILDTOOLCLASSDIR)/%.class) + +all build: $(BUILDTOOL_JAR_FILE) tool_info + +$(BUILDTOOL_MANIFEST_FILE): $(BUILDTOOL_MAIN_SOURCE_FILE) + @$(prep-target) + $(ECHO) "Main-Class: $(BUILTTOOL_MAINCLASS)" > $@ + +$(BUILDTOOLCLASSDIR)/%.class : $(BUILDTOOL_SOURCE_ROOT)/%.java + @$(prep-target) + $(JAVAC_CMD) \ + -sourcepath $(BUILDTOOL_SOURCE_ROOT) \ + -d $(BUILDTOOLCLASSDIR) $< + +$(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) $(FILES_class) + @$(prep-target) + $(BOOT_JAR_CMD) cfm $@ $(BUILDTOOL_MANIFEST_FILE) \ + -C $(BUILDTOOLCLASSDIR) $(PKGDIR) \ + $(BOOT_JAR_JFLAGS) || $(RM) $@ + $(java-vm-cleanup) + +# Printing out a build tool information line +define printBuildToolSetting +if [ "$2" != "" ] ; then $(PRINTF) "%-25s %s\n" "$1:" "$2"; fi +endef + +# Print out the build tool information +tool_info: + @$(ECHO) "=========================================================" + @$(call printBuildToolSetting,BUILDTOOL,$(PROGRAM)) + @$(call printBuildToolSetting,PACKAGE,$(PACKAGE)) + @$(call printBuildToolSetting,BUILDTOOL_SOURCE_ROOT,$(BUILDTOOL_SOURCE_ROOT)) + @$(call printBuildToolSetting,BUILTTOOL_MAINCLASS,$(BUILTTOOL_MAINCLASS)) + @$(call printBuildToolSetting,BUILDTOOL_JAR_FILE,$(BUILDTOOL_JAR_FILE)) + @$(ECHO) "=========================================================" + +clean clobber:: + @$(RM) -rf $(BUILDTOOLCLASSDIR)/$(PKGDIR) + @$(RM) $(BUILDTOOL_MANIFEST_FILE) + @$(RM) $(BUILDTOOL_JAR_FILE) diff --git a/jdk/make/modules/tools/build.xml b/jdk/make/modules/tools/build.xml new file mode 100644 index 0000000000000000000000000000000000000000..993ccb8de071689b5a1d1ab8efd412e49d5b1e5d --- /dev/null +++ b/jdk/make/modules/tools/build.xml @@ -0,0 +1,33 @@ + + + + diff --git a/jdk/make/modules/tools/nbproject/project.properties b/jdk/make/modules/tools/nbproject/project.properties new file mode 100644 index 0000000000000000000000000000000000000000..00b74962d973502055d61fcf241710b42bc6b05f --- /dev/null +++ b/jdk/make/modules/tools/nbproject/project.properties @@ -0,0 +1,92 @@ +# +# Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Sun Microsystems nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +application.title=classanalyzer +application.vendor=mchung +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form + +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources + +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results + +cp.extra=${tools.jar} + +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} + +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/classanalyzer.jar +dist.javadoc.dir=${dist.dir}/javadoc + +excludes= + +file.reference.tools.jar=${jdk.home}/lib/tools.jar +file.reference.tools-src=src +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.tools.jar} +javac.deprecation=false +javac.source=1.5 +javac.target=1.5 +javac.test.classpath= +javadoc.author=false +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=false +javadoc.use=false +javadoc.version=false +main.class=com.sun.classanalyzer.ClassAnalyzer +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +platform.active=JDK_1.6 +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs=-Xmx256m +run.test.classpath= +source.encoding=UTF-8 +src.dir=${file.reference.tools-src} diff --git a/jdk/make/modules/tools/nbproject/project.xml b/jdk/make/modules/tools/nbproject/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..b8b0aeafe0703952e50a43be116f5178d9f9377e --- /dev/null +++ b/jdk/make/modules/tools/nbproject/project.xml @@ -0,0 +1,45 @@ + + + + + org.netbeans.modules.java.j2seproject + + + classanalyzer + + + + + + + + diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/AnnotatedDependency.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/AnnotatedDependency.java new file mode 100644 index 0000000000000000000000000000000000000000..72b21d9949eb362158a19e485906813b35d9c4c1 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/AnnotatedDependency.java @@ -0,0 +1,627 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ +package com.sun.classanalyzer; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.Map; + +import com.sun.classanalyzer.Module.Reference; +import java.util.LinkedList; +import java.util.TreeMap; + +/** + * + * @author Mandy Chung + */ +public abstract class AnnotatedDependency implements Comparable { + + final Klass from; + final List classes; + protected boolean optional; + String description; + Klass.Method method; + private List filters = null; + + public AnnotatedDependency(Klass klass) { + this(klass, false); + } + + public AnnotatedDependency(Klass klass, boolean optional) { + this.from = klass; + this.classes = new ArrayList(); + this.optional = optional; + } + + abstract String getTag(); + + abstract boolean isDynamic(); + + void setMethod(Klass.Method m) { + this.method = m; + } + + void addElement(String element, List value) { + if (element.equals("value")) { + addValue(value); + } else if (element.equals("description")) { + description = value.get(0); + } else if (element.equals("optional")) { + optional = value.get(0).equals("1") || Boolean.parseBoolean(value.get(0)); + } + } + + void addValue(List value) { + for (String s : value) { + if ((s = s.trim()).length() > 0) { + classes.add(s); + } + } + } + + List getValue() { + return classes; + } + + boolean isOptional() { + return optional; + } + + boolean isEmpty() { + return classes.isEmpty(); + } + + boolean matches(String classname) { + synchronized (this) { + // initialize filters + if (filters == null) { + filters = new ArrayList(); + for (String pattern : classes) { + filters.add(new Filter(pattern)); + } + + } + } + + for (Filter f : filters) { + if (f.matches(classname)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (String v : getValue()) { + if (sb.length() == 0) { + sb.append(getTag()); + sb.append("\n"); + } else { + sb.append("\n"); + } + sb.append(" "); + sb.append(from.getClassName()).append(" -> "); + sb.append(v); + } + return sb.toString(); + } + + @Override + public int compareTo(AnnotatedDependency o) { + if (from == o.from) { + if (this.getClass().getName().equals(o.getClass().getName())) { + String s1 = classes.isEmpty() ? "" : classes.get(0); + String s2 = o.classes.isEmpty() ? "" : o.classes.get(0); + return s1.compareTo(s2); + } else { + return this.getClass().getName().compareTo(o.getClass().getName()); + } + + } else { + return from.compareTo(o.from); + } + } + + @Override + public int hashCode() { + int hashcode = 7 + 73 * from.hashCode(); + for (String s : classes) { + hashcode ^= s.hashCode(); + } + return hashcode; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AnnotatedDependency)) { + return false; + } + AnnotatedDependency other = (AnnotatedDependency) obj; + boolean ret = this.from.equals(other.from) && this.classes.size() == other.classes.size(); + if (ret == true) { + for (int i = 0; i < this.classes.size(); i++) { + ret = ret && this.classes.get(i).equals(other.classes.get(i)); + } + } + return ret; + } + + static class ClassForName extends AnnotatedDependency { + + public ClassForName(Klass klass, boolean optional) { + super(klass, optional); + } + + @Override + String getTag() { + if (this.optional) { + return TAG + "(optional)"; + } else { + return TAG; + } + } + + @Override + boolean isDynamic() { + return true; + } + static final String TYPE = "sun.annotation.ClassForName"; + static final String TAG = "@ClassForName"; + } + + static class NativeFindClass extends AnnotatedDependency { + + public NativeFindClass(Klass klass, boolean optional) { + super(klass, optional); + } + + @Override + String getTag() { + if (this.optional) { + return TAG + "(optional)"; + } else { + return TAG; + } + } + + @Override + boolean isDynamic() { + return true; + } + static final String TYPE = "sun.annotation.NativeFindClass"; + static final String TAG = "@NativeFindClass"; + } + + static class Provider extends AnnotatedDependency { + + private List services = new ArrayList(); + + Provider(Klass klass) { + super(klass, true); + } + + @Override + boolean isDynamic() { + return true; + } + + public List services() { + return services; + } + + @Override + void addElement(String element, List value) { + if (element.equals("service")) { + List configFiles = new ArrayList(); + for (String s : value) { + if ((s = s.trim()).length() > 0) { + configFiles.add(metaInfPath + s); + } + } + addValue(configFiles); + } + } + + @Override + void addValue(List value) { + for (String s : value) { + if ((s = s.trim()).length() > 0) { + if (s.startsWith("META-INF")) { + services.add(s); + readServiceConfiguration(s, classes); + } else { + throw new RuntimeException("invalid value" + s); + } + } + } + } + + boolean isEmpty() { + return services.isEmpty(); + } + static final String metaInfPath = + "META-INF" + File.separator + "services" + File.separator; + + static void readServiceConfiguration(String config, List names) { + BufferedReader br = null; + try { + InputStream is = ClassPath.open(config); + if (is != null) { + // Properties doesn't perserve the order of the input file + br = new BufferedReader(new InputStreamReader(is, "utf-8")); + int lc = 1; + while ((lc = parseLine(br, lc, names)) >= 0); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } + } + + // Parse a single line from the given configuration file, adding the name + // on the line to the names list. + // + private static int parseLine(BufferedReader r, int lc, List names) throws IOException { + String ln = r.readLine(); + if (ln == null) { + return -1; + } + int ci = ln.indexOf('#'); + if (ci >= 0) { + ln = ln.substring(0, ci); + } + ln = ln.trim(); + int n = ln.length(); + if (n != 0) { + if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) { + throw new RuntimeException("Illegal configuration-file syntax"); + } + int cp = ln.codePointAt(0); + if (!Character.isJavaIdentifierStart(cp)) { + throw new RuntimeException("Illegal provider-class name: " + ln); + } + for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) { + cp = ln.codePointAt(i); + if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) { + throw new RuntimeException("Illegal provider-class name: " + ln); + } + } + if (!names.contains(ln)) { + names.add(ln); + } + } + return lc + 1; + } + + @Override + String getTag() { + return TAG; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AnnotatedDependency)) { + return false; + } + Provider other = (Provider) obj; + boolean ret = this.from.equals(other.from) && + this.services.size() == other.services.size(); + if (ret == true) { + for (int i = 0; i < this.services.size(); i++) { + ret = ret && this.services.get(i).equals(other.services.get(i)); + } + } + return ret; + } + + @Override + public int hashCode() { + int hashcode = 7 + 73 * from.hashCode(); + for (String s : services) { + hashcode ^= s.hashCode(); + } + return hashcode; + } + + @Override + public List getValue() { + List result = new ArrayList(); + result.addAll(services); + return result; + } + static final String TYPE = "sun.annotation.Provider"; + static final String TAG = "@Provider"; + } + + static class OptionalDependency extends AnnotatedDependency { + + static boolean isOptional(Klass from, Klass to) { + synchronized (OptionalDependency.class) { + if (optionalDepsMap == null) { + // Build a map of classes to its optional dependencies + initDependencies(); + } + } + for (Reference ref : optionalDepsMap.keySet()) { + if (ref.referrer() == from && ref.referree() == to) { + return true; + } + } + return false; + } + + OptionalDependency(Klass klass) { + super(klass, true); + } + + @Override + boolean isDynamic() { + return false; + } + + @Override + String getTag() { + return TAG; + } + static final String TYPE = "sun.annotation.Optional"; + static final String TAG = "@Optional"; + } + + static class CompilerInline extends AnnotatedDependency { + + public CompilerInline(Klass klass) { + super(klass); + } + + @Override + String getTag() { + return TAG; + } + + @Override + boolean isDynamic() { + return false; + } + static final String TYPE = "sun.annotation.Inline"; + static final String TAG = "@Inline"; + } + + static class Filter { + + final String pattern; + final String regex; + + Filter(String pattern) { + this.pattern = pattern; + + boolean isRegex = false; + for (int i = 0; i < pattern.length(); i++) { + char p = pattern.charAt(i); + if (p == '*' || p == '[' || p == ']') { + isRegex = true; + break; + } + } + + if (isRegex) { + this.regex = convertToRegex(pattern); + } else { + this.regex = null; + } + } + + private String convertToRegex(String pattern) { + StringBuilder sb = new StringBuilder(); + int i = 0; + int index = 0; + int plen = pattern.length(); + while (i < plen) { + char p = pattern.charAt(i); + if (p == '*') { + sb.append("(").append(pattern.substring(index, i)).append(")"); + if (i + 1 < plen && pattern.charAt(i + 1) == '*') { + sb.append(".*"); + index = i + 2; + } else { + sb.append("[^\\.]*"); + index = i + 1; + } + } else if (p == '[') { + int j = i + 1; + while (j < plen) { + if (pattern.charAt(j) == ']') { + break; + } + j++; + } + if (j >= plen || pattern.charAt(j) != ']') { + throw new RuntimeException("Malformed pattern " + pattern); + } + sb.append("(").append(pattern.substring(index, i)).append(")"); + sb.append(pattern.substring(i, j + 1)); + index = j + 1; + i = j; + } + i++; + } + if (index < plen) { + sb.append("(").append(pattern.substring(index, plen)).append(")"); + } + return sb.toString(); + } + + boolean matches(String name) { + if (regex == null) { + // the pattern is not a regex + return name.equals(pattern); + } else { + return name.matches(regex); + } + } + } + + static boolean isValidType(String type) { + if (type.endsWith("(optional)")) { + int len = type.length() - "(optional)".length(); + type = type.substring(0, len); + } + return type.equals(ClassForName.TYPE) || type.equals(ClassForName.TAG) || + type.equals(NativeFindClass.TYPE) || type.equals(NativeFindClass.TAG) || + type.equals(Provider.TYPE) || type.equals(Provider.TAG) || + type.equals(CompilerInline.TYPE) || type.equals(CompilerInline.TAG) || + type.equals(OptionalDependency.TYPE) || type.equals(OptionalDependency.TAG); + } + + static AnnotatedDependency newAnnotatedDependency(String tag, String value, Klass klass) { + AnnotatedDependency dep = newAnnotatedDependency(tag, klass); + if (dep != null) { + dep.addValue(Collections.singletonList(value)); + } + return dep; + } + static List annotatedDependencies = new LinkedList(); + static List optionalDependencies = new LinkedList(); + + static AnnotatedDependency newAnnotatedDependency(String type, Klass klass) { + boolean optional = false; + if (type.endsWith("(optional)")) { + optional = true; + int len = type.length() - "(optional)".length(); + type = type.substring(0, len); + } + + if (type.equals(OptionalDependency.TYPE) || type.equals(OptionalDependency.TAG)) { + return newOptionalDependency(klass); + } + + AnnotatedDependency dep; + if (type.equals(ClassForName.TYPE) || type.equals(ClassForName.TAG)) { + dep = new ClassForName(klass, optional); + } else if (type.equals(NativeFindClass.TYPE) || type.equals(NativeFindClass.TAG)) { + dep = new NativeFindClass(klass, optional); + } else if (type.equals(Provider.TYPE) || type.equals(Provider.TAG)) { + dep = new Provider(klass); + } else if (type.equals(CompilerInline.TYPE) || type.equals(CompilerInline.TAG)) { + dep = new CompilerInline(klass); + } else { + return null; + } + klass.addAnnotatedDep(dep); + annotatedDependencies.add(dep); + return dep; + } + + static OptionalDependency newOptionalDependency(Klass klass) { + OptionalDependency dep = new OptionalDependency(klass); + optionalDependencies.add(dep); + return dep; + } + static Map> annotatedDepsMap = null; + static Map> optionalDepsMap = null; + + static Map> getReferences(Module m) { + // ensure it's initialized + initDependencies(); + + Map> result = new TreeMap>(); + for (Reference ref : annotatedDepsMap.keySet()) { + if (m.contains(ref.referrer()) && m.isModuleDependence(ref.referree())) { + result.put(ref, annotatedDepsMap.get(ref)); + } + } + return result; + } + + static Set getDependencies(Module m) { + // ensure it's initialized + initDependencies(); + + Set deps = new TreeSet(); + for (Reference ref : annotatedDepsMap.keySet()) { + if (m.contains(ref.referrer())) { + Module other = m.getModuleDependence(ref.referree()); + if (other != null) { + for (AnnotatedDependency ad : annotatedDepsMap.get(ref)) { + Module.Dependency d = new Module.Dependency(other, ad.isOptional(), ad.isDynamic()); + deps.add(d); + } + } + } + } + return deps; + } + + synchronized static void initDependencies() { + if (annotatedDepsMap != null) { + return; + } + + // Build a map of references to its dependencies + annotatedDepsMap = new TreeMap>(); + optionalDepsMap = new TreeMap>(); + + for (Klass k : Klass.getAllClasses()) { + for (AnnotatedDependency ad : annotatedDependencies) { + if (ad.matches(k.getClassName())) { + Reference ref = new Reference(ad.from, k); + Set set = annotatedDepsMap.get(ref); + if (set == null) { + set = new TreeSet(); + annotatedDepsMap.put(ref, set); + } + set.add(ad); + } + } + + for (AnnotatedDependency ad : optionalDependencies) { + if (ad.matches(k.getClassName())) { + Reference ref = new Reference(ad.from, k); + Set set = optionalDepsMap.get(ref); + if (set == null) { + set = new TreeSet(); + optionalDepsMap.put(ref, set); + } + set.add(ad); + } + } + } + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/AnnotationParser.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/AnnotationParser.java new file mode 100644 index 0000000000000000000000000000000000000000..7d984aa2e74b3a58ce6437c764d924105182ba0c --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/AnnotationParser.java @@ -0,0 +1,293 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.classanalyzer; + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.Annotation; +import com.sun.tools.classfile.ExtendedAnnotation; +import com.sun.tools.classfile.Annotation.Annotation_element_value; +import com.sun.tools.classfile.Annotation.Array_element_value; +import com.sun.tools.classfile.Annotation.Class_element_value; +import com.sun.tools.classfile.Annotation.Enum_element_value; +import com.sun.tools.classfile.Annotation.Primitive_element_value; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.Descriptor; +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; +import java.util.ArrayList; +import java.util.List; + +import com.sun.classanalyzer.AnnotatedDependency.*; +import java.io.File; +import java.io.PrintWriter; +import java.util.Map; +import java.util.Set; + +/** + * + * @author Mandy Chung + */ +public class AnnotationParser { + + static boolean parseAnnotation = false; + static void setParseAnnotation(boolean newValue) { + parseAnnotation = newValue; + } + + private final ClassFileParser cfparser; + public AnnotationParser(ClassFileParser cfparser) { + this.cfparser = cfparser; + } + + private AnnotatedDependency addAnnotation(Annotation annot, Klass.Method method) { + String type = getType(annot.type_index); + 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]); + dep.addElement(element.name, element.value); + } + dep.setMethod(method); + } + return dep; + } + + private AnnotatedDependency addAnnotation(ExtendedAnnotation annot, Klass.Method method) { + return addAnnotation(annot.annotation, method); + } + + class Element { + + String name; + List value; + + Element(String name) { + this.name = name; + this.value = new ArrayList(); + } + + void add(String v) { + value.add(v); + } + } + + Element getElement(Annotation.element_value_pair pair) { + Element element = new Element(getName(pair.element_name_index)); + evp.parse(pair.value, element); + return element; + } + + private String getType(int index) { + try { + Descriptor d = new Descriptor(index); + return d.getFieldType(cfparser.classfile.constant_pool); + } catch (ConstantPoolException ignore) { + } catch (InvalidDescriptor ignore) { + } + return "Unknown"; + } + + private String getName(int index) { + return cfparser.constantPoolParser.stringValue(index); + } + element_value_Parser evp = new element_value_Parser(); + + class element_value_Parser implements Annotation.element_value.Visitor { + + public Void parse(Annotation.element_value value, Element element) { + value.accept(this, element); + return null; + } + + public Void visitPrimitive(Primitive_element_value ev, Element element) { + String value = getName(ev.const_value_index); + element.add(value); + return null; + } + + public Void visitEnum(Enum_element_value ev, Element element) { + String value = getName(ev.type_name_index) + "." + getName(ev.const_name_index); + element.add(value); + return null; + } + + public Void visitClass(Class_element_value ev, Element element) { + String value = getName(ev.class_info_index) + ".class"; + element.add(value); + return null; + } + + public Void visitAnnotation(Annotation_element_value ev, Element element) { + // AnnotationParser.this.addAnnotation(ev.annotation_value); + throw new UnsupportedOperationException("Not supported: " + ev); + } + + public Void visitArray(Array_element_value ev, Element element) { + for (int i = 0; i < ev.num_values; i++) { + parse(ev.values[i], element); + } + return null; + } + } + + void parseAttributes(Attributes attributes, Klass.Method method) { + if (!parseAnnotation) { + return; + } + + visitRuntimeAnnotations((RuntimeVisibleAnnotations_attribute) attributes.get(Attribute.RuntimeVisibleAnnotations), method); + visitRuntimeAnnotations((RuntimeInvisibleAnnotations_attribute) attributes.get(Attribute.RuntimeInvisibleAnnotations), method); + visitRuntimeTypeAnnotations((RuntimeVisibleTypeAnnotations_attribute) attributes.get(Attribute.RuntimeVisibleTypeAnnotations), method); + visitRuntimeTypeAnnotations((RuntimeInvisibleTypeAnnotations_attribute) attributes.get(Attribute.RuntimeInvisibleTypeAnnotations), method); + visitRuntimeParameterAnnotations((RuntimeVisibleParameterAnnotations_attribute) attributes.get(Attribute.RuntimeVisibleParameterAnnotations), method); + visitRuntimeParameterAnnotations((RuntimeInvisibleParameterAnnotations_attribute) attributes.get(Attribute.RuntimeInvisibleParameterAnnotations), method); + } + + public void visitRuntimeAnnotations(RuntimeAnnotations_attribute attr, Klass.Method method) { + if (attr == null) { + return; + } + + for (int i = 0; i < attr.annotations.length; i++) { + addAnnotation(attr.annotations[i], method); + } + } + + public void visitRuntimeTypeAnnotations(RuntimeTypeAnnotations_attribute attr, Klass.Method method) { + if (attr == null) { + return; + } + + for (int i = 0; i < attr.annotations.length; i++) { + addAnnotation(attr.annotations[i], method); + } + } + + public void visitRuntimeParameterAnnotations(RuntimeParameterAnnotations_attribute attr, Klass.Method method) { + if (attr == null) { + return; + } + + for (int param = 0; param < attr.parameter_annotations.length; param++) { + for (int i = 0; i < attr.parameter_annotations[param].length; i++) { + addAnnotation(attr.parameter_annotations[param][i], method); + } + } + } + + void parseAttributes(Attributes attributes) { + parseAttributes(attributes, null); + } + + public static void main(String[] args) throws Exception { + String jdkhome = null; + String output = "."; + + // process arguments + int i = 0; + while (i < args.length) { + String arg = args[i++]; + if (arg.equals("-jdkhome")) { + if (i < args.length) { + jdkhome = args[i++]; + } else { + usage(); + } + } else if (arg.equals("-output")) { + output = args[i++]; + } else { + usage(); + } + } + if (jdkhome == null) { + usage(); + } + + // parse annotation and code attribute to find all references + // to Class.forName etc + CodeAttributeParser.setParseCodeAttribute(true); + AnnotationParser.setParseAnnotation(true); + + ClassPath.setJDKHome(jdkhome); + ClassPath.parseAllClassFiles(); + + PrintWriter writer = new PrintWriter(new File(output, "jdk7.depconfig")); + + try { + for (Klass k : Klass.getAllClasses()) { + for (AnnotatedDependency dep : k.getAnnotatedDeps()) { + if (dep.isEmpty()) { + continue; + } + writer.format("# %s \n", dep.method == null ? dep.from : dep.method); + writer.format("%s\n\n", dep); + } + } + } finally { + writer.close(); + } + + writer = new PrintWriter(new File(output, "optional.depconfig")); + try { + AnnotatedDependency prev = null; + for (AnnotatedDependency dep : AnnotatedDependency.optionalDependencies) { + if (prev != null && !dep.equals(prev)) { + writer.format("%s\n\n", prev); + } + writer.format("# %s \n", dep.method == null ? dep.from : dep.method); + prev = dep; + } + if (prev != null) { + writer.format("%s\n\n", prev); + } + } finally { + writer.close(); + } + + writer = new PrintWriter(new File(output, "runtime.references")); + try { + for (Map.Entry> entry : CodeAttributeParser.runtimeReferences.entrySet()) { + writer.format("References to %s\n", entry.getKey()); + Klass prev = null; + for (Klass.Method m : entry.getValue()) { + if (prev == null || prev != m.getKlass()) { + writer.format(" %-50s # %s\n", m.getKlass(), m); + } else if (prev == m.getKlass()) { + writer.format(" %-50s # %s\n", "", m); + } + prev = m.getKlass(); + } + } + } finally { + writer.close(); + } + } + + private static void usage() { + System.out.println("Usage: AnnotationParser "); + System.out.println("Options: "); + System.out.println("\t-jdkhome where all jars will be parsed"); + System.out.println("\t-depconfig "); + System.out.println("\t-optional "); + System.exit(-1); + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/BootAnalyzer.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/BootAnalyzer.java new file mode 100644 index 0000000000000000000000000000000000000000..06e332ace7c372642cbc2f0f0904e67c31f7ce69 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/BootAnalyzer.java @@ -0,0 +1,819 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ +package com.sun.classanalyzer; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.File; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import com.sun.tools.classfile.*; +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.*; + +/** + * Generate the module config for the boot module with + * a given set of roots (classes or methods) and exclude list. + * + * This tool does method-level dependency analysis starting + * from the root set and follows references transitively as follows: + *
    + *
  • For a given class, it will parse the ClassFile to + * find its superclass and superinterfaces and also + * its static initializer <clinit>.
  • + *
  • For each method, it will parse its Code attribute + * to look for a Methodref, Fieldref, and InterfaceMethodref. + *
  • + *
  • For each Fieldref, it will include the type of + * the field in the dependency.
  • + *
  • For each MethodRef, it will follow all references in + * that method.
  • + *
  • For each InterfaceMethodref, it will follow all references in + * that method defined its implementation classes in + * the resulting dependency list.
  • + *
+ * + * Limitation: + *
    + *
  • For each Methodref, it only parses the method of + * the specified type. It doesn't analyze the class hierarchy + * and follow references of its subclasses since it ends up + * pulls in many unnecessary dependencies. For now, + * the list of subclasses and methods need to be listed in + * the root set.
  • + *
+ * + * @author Mandy Chung + */ +public class BootAnalyzer { + + public static void main(String[] args) throws Exception { + String jdkhome = null; + String config = null; + String output = "."; + boolean printClassList = false; + + // process arguments + int i = 0; + while (i < args.length) { + String arg = args[i++]; + if (arg.equals("-jdkhome")) { + if (i < args.length) { + jdkhome = args[i++]; + } else { + usage(); + } + } else if (arg.equals("-config")) { + config = args[i++]; + } else if (arg.equals("-output")) { + output = args[i++]; + } else if (arg.equals("-classlist")) { + printClassList = true; + } else { + usage(); + } + } + + + + if (jdkhome == null || config == null) { + usage(); + } + + File jre = new File(jdkhome, "jre"); + if (jre.exists()) { + ClassPath.setJDKHome(jdkhome); + } else { + File classes = new File(jdkhome, "classes"); + if (classes.exists()) { + ClassPath.setClassPath(classes.getCanonicalPath()); + } else { + throw new RuntimeException("Invalid jdkhome: " + jdkhome); + } + } + + parseConfigFile(config); + followRoots(); + + // create output directory if it doesn't exist + File dir = new File(output); + if (!dir.isDirectory()) { + if (!dir.exists()) { + boolean created = dir.mkdir(); + if (!created) { + throw new RuntimeException("Unable to create `" + dir + "'"); + } + } + } + + String bootmodule = "boot"; + String bootconfig = resolve(dir, bootmodule, "config"); + printBootConfig(bootconfig, bootmodule); + + List list = ModuleConfig.readConfigurationFile(bootconfig); + Module module = Module.addModule(list.get(0)); + for (Klass k : Klass.getAllClasses()) { + module.addKlass(k); + } + module.fixupDependencies(); + + if (printClassList) { + module.printClassListTo(resolve(dir, bootmodule, "classlist")); + module.printSummaryTo(resolve(dir, bootmodule, "summary")); + } + } + + // print boot.config file as an input to the ClassAnalyzer + private static void printBootConfig(String output, String bootmodule) throws IOException { + + File f = new File(output); + PrintWriter writer = new PrintWriter(f); + try { + int count = 0; + writer.format("module %s {%n", bootmodule); + for (Klass k : Klass.getAllClasses()) { + if (count++ == 0) { + writer.format("%4s%7s %s", "", "include", k); + } else { + writer.format(",%n"); + writer.format("%4s%7s %s", "", "", k); + } + } + writer.format(";%n}%n"); + } finally { + writer.close(); + } + } + + private static String resolve(File dir, String mname, String suffix) { + File f = new File(dir, mname + "." + suffix); + return f.toString(); + + } + static List methods = new LinkedList(); + static Deque pending = new ArrayDeque(); + static Deque interfaceMethodRefs = new ArrayDeque(); + static Filter filter = new Filter(); + + private static void followRoots() throws IOException { + MethodDescriptor md = null; + + while ((md = pending.poll()) != null) { + if (!methods.contains(md)) { + methods.add(md); + if (md.classname.isEmpty()) { + trace("Warning: class missing %s%n", md); + continue; + } + + if (filter.isExcluded(md.classname)) { + trace("excluded %s%n", md); + } else { + KlassInfo kinfo = getKlassInfo(md.classname); + if (kinfo.classname.contains("$")) { + int pos = kinfo.classname.lastIndexOf('$'); + String outer = kinfo.classname.substring(0, pos); + if (!cache.containsKey(outer)) { + trace(" include outer class %s%n", outer); + getKlassInfo(outer).ensureParse(); + } + } + + kinfo.ensureParse(); + if (md.methodname.length() > 0) { + if (filter.isExcluded(md.name)) { + trace("excluded %s%n", md); + } else { + if (md.interfaceMethodRef) { + trace("interface methodref %s%n", md); + interfaceMethodRefs.add(md); + } else { + List descriptors = kinfo.parse(md); + if (descriptors.isEmpty()) { + if (kinfo.getSuperclass() != null) { + String sn = kinfo.getSuperclass().classname; + MethodDescriptor superMD = new MethodDescriptor(sn + "." + md.methodname, md.descriptor, false); + if (!methods.contains(superMD) && !pending.contains(superMD)) { + trace(" delegated %s to %s%n", md, superMD); + pending.add(superMD); + } + } else if (kinfo.isClass()) { + trace(" %s (not found)%n", md); + } else { + trace(" %s (interface)%n", md); + } + } else { + if (md.descriptor.equals("*")) { + trace(" parsed %s : ", md.name); + for (String s : descriptors) { + trace(" %s", s); + } + trace("%n"); + } + } + } + } + } + } + } + if (pending.isEmpty()) { + for (Klass k : Klass.getAllClasses()) { + if (k.getFileSize() == 0) { + getKlassInfo(k.getClassName()).ensureParse(); + } + } + while ((md = interfaceMethodRefs.poll()) != null) { + addSubClassMethods(md); + } + } + } + } + + static void addSubClassMethods(MethodDescriptor md) throws IOException { + for (KlassInfo kinfo : getSubClasses(md.classname)) { + String methodname = kinfo.classname + "." + md.methodname; + MethodDescriptor other = new MethodDescriptor(methodname, md.descriptor, false); + if (!methods.contains(other) && !pending.contains(other)) { + trace("Warning: subclass from %s to %s%n", md.classname, other); + pending.add(other); + } + } + } + private final static String privilegedActionInterf = "java.security.PrivilegedAction"; + private final static String privilegedExceptionActionInterf = "java.security.PrivilegedExceptionAction"; + + static boolean isPrivilegedAction(String classname) { + if (classname.isEmpty()) { + return false; + } + KlassInfo kinfo = getKlassInfo(classname); + for (KlassInfo ki : kinfo.getInterfaces()) { + String interf = ki.classname; + if (interf.equals(privilegedActionInterf) || + interf.equals(privilegedExceptionActionInterf)) { + return true; + } + } + return false; + } + static Map cache = new HashMap(); + + static KlassInfo getKlassInfo(String classname) { + classname = classname.replace('/', '.'); + + KlassInfo kinfo = cache.get(classname); + if (kinfo == null) { + kinfo = new KlassInfo(classname); + cache.put(classname, kinfo); + } + return kinfo; + } + + static class KlassInfo { + + final String classname; + private ClassFileParser parser; + private KlassInfo superclass; + private List interfaces = new LinkedList(); + + KlassInfo(String classname) { + this.classname = classname; + } + + boolean isClass() { + ensureParse(); + return parser.classfile.isClass(); + } + + KlassInfo getSuperclass() { + ensureParse(); + return superclass; + } + + List getInterfaces() { + ensureParse(); + return java.util.Collections.unmodifiableList(interfaces); + } + + void ensureParse() { + try { + getClassFileParser(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + synchronized ClassFileParser getClassFileParser() throws IOException { + if (parser == null) { + parser = ClassPath.parserForClass(classname); + if (parser != null) { + parseClassFile(); + List descriptors = parse(new MethodDescriptor(classname + ".", "()V", false)); + } + } + return parser; + } + + List parse(MethodDescriptor md) { + ensureParse(); + try { + List descriptors = new LinkedList(); + for (Method m : parser.classfile.methods) { + String name = m.getName(parser.classfile.constant_pool); + String desc = parser.constantPoolParser.getDescriptor(m.descriptor.index); + if (name.equals(md.methodname)) { + if (md.descriptor.equals("*") || md.descriptor.equals(desc)) { + parseMethod(parser, m); + descriptors.add(desc); + } + } + } + return descriptors; + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + + private void parseClassFile() throws IOException { + parser.parseClassInfo(); + + ClassFile classfile = parser.classfile; + try { + if (classfile.super_class > 0) { + superclass = getKlassInfo(classfile.getSuperclassName()); + } + if (classfile.interfaces != null) { + for (int i = 0; i < classfile.interfaces.length; i++) { + interfaces.add(getKlassInfo(classfile.getInterfaceName(i))); + } + } + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + } + + static List getSubClasses(String classname) throws IOException { + List result = new LinkedList(); + List list = new LinkedList(); + list.addAll(cache.values()); + for (KlassInfo kinfo : list) { + if (kinfo.getSuperclass() != null && classname.equals(kinfo.getSuperclass().classname)) { + result.add(kinfo); + } + for (KlassInfo interf : kinfo.getInterfaces()) { + if (classname.equals(interf.classname)) { + result.add(kinfo); + } + } + } + return result; + } + + private static void parseConfigFile(String config) throws IOException { + FileInputStream in = new FileInputStream(config); + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line; + int lineNumber = 0; + while ((line = reader.readLine()) != null) { + lineNumber++; + if ((line = line.trim()).length() > 0) { + if (line.startsWith("#")) { + continue; + } + + String[] s = line.split("\\s+"); + if ("exclude".equals(s[0])) { + filter.exclude(s[1]); + } else { + String name = s[0].replace('/', '.'); + if (name.length() > 0) { + String classname = name.replace('/', '.'); + if (s.length == 2) { + // method name + int pos = classname.lastIndexOf('.'); + classname = classname.substring(0, pos); + } + + KlassInfo kinfo = getKlassInfo(classname); + if (kinfo.getClassFileParser() != null) { + // class exists + MethodDescriptor md = (s.length == 1) ? new MethodDescriptor(name) : new MethodDescriptor(name, s[1], false); + if (!pending.contains(md)) { + pending.add(md); + } + } else { + // class not found + trace("Class %s not found%n", classname); + } + } + } + } + } + + } finally { + in.close(); + } + } + + private static void parseMethod(ClassFileParser cfparser, Method m) { + Klass.Method kmethod = cfparser.parseMethod(m); + Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code); + if (c_attr != null) { + LineNumberTable_attribute lineNumTable = + (LineNumberTable_attribute) c_attr.attributes.get(Attribute.LineNumberTable); + InstructorVisitor visitor = new InstructorVisitor(cfparser, lineNumTable); + trace("parseMethod %s %s %n", cfparser.this_klass, kmethod); + for (Instruction instr : c_attr.getInstructions()) { + try { + instr.accept(visitor, kmethod); + } catch (ArrayIndexOutOfBoundsException e) { + throw new RuntimeException("error at or after byte " + instr.getPC()); + } + + } + + if (c_attr.exception_table_langth > 0) { + for (int i = 0; i < + c_attr.exception_table.length; i++) { + Code_attribute.Exception_data handler = c_attr.exception_table[i]; + int catch_type = handler.catch_type; + if (catch_type > 0) { + visitor.addConstantPoolRef(catch_type, kmethod, handler.start_pc); + } + + } + } + } + } + + static class MethodDescriptor { + + final String name; + final String classname; + final String methodname; + final String descriptor; + final boolean interfaceMethodRef; + + MethodDescriptor(String classname) { + this.classname = classname.replace('/', '.'); + this.name = this.classname; + this.methodname = ""; + this.descriptor = ""; + this.interfaceMethodRef = false; + if (this.classname.length() == 1) { + throw new RuntimeException("invalid " + this); + } + } + + MethodDescriptor(String name, String descriptor, boolean interfaceMethodRef) { + name = name.replace('/', '.'); + this.name = name; + int pos = name.lastIndexOf('.'); + this.classname = name.substring(0, pos); + this.methodname = name.substring(pos + 1, name.length()); + this.descriptor = descriptor; + this.interfaceMethodRef = interfaceMethodRef; + if (this.classname.length() == 1) { + throw new RuntimeException("invalid " + this); + } + } + + @Override + public boolean equals(Object obj) { + MethodDescriptor m = (MethodDescriptor) obj; + + return this.name.equals(m.name) && + this.descriptor.equals(m.descriptor); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0); + hash = 97 * hash + (this.descriptor != null ? this.descriptor.hashCode() : 0); + return hash; + } + + public String toString() { + if (descriptor.isEmpty()) { + return name; + } else { + return name + " : " + descriptor; + } + } + } + + static class Filter { + + private Set excludes = new TreeSet(); + + Filter exclude(String pattern) { + excludes.add(pattern); + return this; + } + + boolean isExcluded(String klass) { + for (String pattern : excludes) { + if (matches(klass, pattern)) { + return true; + } + } + return false; + } + + private boolean matches(String klass, String pattern) { + int pos = klass.lastIndexOf('.'); + String packageName = pos > 0 ? klass.substring(0, pos) : ""; + if (pattern.endsWith("**")) { + String p = pattern.substring(0, pattern.length() - 2); + return klass.startsWith(p); + } else if (pattern.endsWith("*")) { + pos = pattern.lastIndexOf('.'); + String pkg = pos > 0 ? pattern.substring(0, pos) : ""; + if (packageName.equals(pkg)) { + // package name has to be exact match + String p = pattern.substring(0, pattern.length() - 1); + return klass.startsWith(p); + } else { + return false; + } + } else { + // exact match or inner class + return klass.equals(pattern) || klass.startsWith(pattern + "$"); + } + } + } + + static class InstructorVisitor implements Instruction.KindVisitor { + + private final ClassFileParser parser; + private final LineNumberTable_attribute lineNumTable; + + InstructorVisitor(ClassFileParser parser, LineNumberTable_attribute lineNumTable) { + this.parser = parser; + this.lineNumTable = lineNumTable; + } + + int getLineNumber(int pc) { + if (lineNumTable != null) { + int start_pc = 0; + int lineno = 0; + for (int i = 0; i < lineNumTable.line_number_table_length; i++) { + int cur_start_pc = lineNumTable.line_number_table[i].start_pc; + if (pc == 0 && cur_start_pc == 0) { + return lineNumTable.line_number_table[i].line_number; + } else if (pc >= start_pc && pc < cur_start_pc) { + return lineno; + } + start_pc = cur_start_pc; + lineno = lineNumTable.line_number_table[i].line_number; + } + } + return 0; + } + + void addConstantPoolRef(int index, Klass.Method m, int pc) { + try { + CPInfo cpInfo = parser.classfile.constant_pool.get(index); + String name = cpInfo.accept(typeFinder, null); + if (name != null) { + trace(" %s %s at line %d%n", parser.constantPoolParser.tagName(index), name, getLineNumber(pc)); + } + } catch (InvalidIndex ex) { + throw new RuntimeException(ex); + } + } + + public Void visitNoOperands(Instruction instr, Klass.Method m) { + return null; + } + + public Void visitArrayType(Instruction instr, TypeKind kind, Klass.Method m) { + return null; + } + + public Void visitBranch(Instruction instr, int offset, Klass.Method m) { + return null; + } + + public Void visitConstantPoolRef(Instruction instr, int index, Klass.Method m) { + addConstantPoolRef(index, m, instr.getPC()); + return null; + } + + public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Klass.Method m) { + addConstantPoolRef(index, m, instr.getPC()); + return null; + } + + public Void visitLocal(Instruction instr, int index, Klass.Method m) { + return null; + } + + public Void visitLocalAndValue(Instruction instr, int index, int value, Klass.Method m) { + return null; + } + + public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Klass.Method m) { + return null; + } + + public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, Klass.Method m) { + return null; + } + + public Void visitValue(Instruction instr, int value, Klass.Method m) { + return null; + } + + public Void visitUnknown(Instruction instr, Klass.Method m) { + return null; + } + private ConstantPool.Visitor typeFinder = new ConstantPool.Visitor() { + + String getClassName(CPRefInfo info, Void p) { + try { + return parser.checkClassName(info.getClassName()).replace('/', '.'); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + + boolean addReferencedClass(String name) { + if (Klass.findKlass(name) == null) { + MethodDescriptor md = new MethodDescriptor(name); + if (!methods.contains(md) && !pending.contains(md)) { + pending.add(md); + } + return true; + } + return false; + } + private String privilegedActionClass = ""; + + void cachePrivilegedAction(String classname) { + trace(" found PrivilegedAction %s%n", classname); + privilegedActionClass = classname; + } + + void doPrivilegedCall(String method) { + if (privilegedActionClass.length() > 0) { + MethodDescriptor md = new MethodDescriptor(privilegedActionClass + ".run", "*", false); + if (!methods.contains(md) && !pending.contains(md)) { + trace(" doPrivileged %s%n", md); + pending.add(md); + } + } + } + + private String addMethodDescriptor(CPRefInfo info, Void p) { + try { + String classname = getClassName(info, null); + String method = classname + "." + info.getNameAndTypeInfo().getName(); + String descriptor = info.getNameAndTypeInfo().getType(); + + if (method.endsWith(".") && isPrivilegedAction(classname)) { + cachePrivilegedAction(classname); + } + if (method.equals("java.security.AccessController.doPrivileged")) { + doPrivilegedCall(method); + return method; + } + + boolean interfaceMethodRef = info instanceof CONSTANT_InterfaceMethodref_info; + MethodDescriptor md = new MethodDescriptor(method, descriptor, interfaceMethodRef); + if (!methods.contains(md) && !pending.contains(md)) { + pending.add(md); + } + return method; + } catch (ConstantPoolException e) { + throw new RuntimeException(e); + } + } + + public String visitClass(CONSTANT_Class_info info, Void p) { + try { + String classname = parser.checkClassName(info.getName()).replace('/', '.'); + if (classname.length() > 0) { + addReferencedClass(classname); + } + return classname; + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + + public String visitDouble(CONSTANT_Double_info info, Void p) { + // skip + return null; + } + + public String visitFieldref(CONSTANT_Fieldref_info info, Void p) { + try { + String classname = getClassName(info, p); + if (classname.length() > 0) { + addReferencedClass(classname); + } + + String type = info.getNameAndTypeInfo().getType(); + String fieldType = parser.checkClassName(type).replace('/', '.'); + if (fieldType.length() > 0) { + addReferencedClass(classname); + } + return parser.constantPoolParser.stringValue(info); + } catch (ConstantPoolException e) { + throw new RuntimeException(e); + } + } + + public String visitFloat(CONSTANT_Float_info info, Void p) { + // skip + return null; + } + + public String visitInteger(CONSTANT_Integer_info info, Void p) { + // skip + return null; + } + + public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) { + return addMethodDescriptor(info, p); + } + + public String visitLong(CONSTANT_Long_info info, Void p) { + // skip + return null; + } + + public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) { + // skip + return null; + } + + public String visitMethodref(CONSTANT_Methodref_info info, Void p) { + return addMethodDescriptor(info, p); + } + + public String visitString(CONSTANT_String_info info, Void p) { + // skip + return null; + } + + public String visitUtf8(CONSTANT_Utf8_info info, Void p) { + return null; + } + }; + } + static boolean traceOn = System.getProperty("classanalyzer.debug") != null; + + private static void trace(String format, Object... args) { + if (traceOn) { + System.out.format(format, args); + } + } + + private static void usage() { + System.out.println("Usage: BootAnalyzer "); + System.out.println("Options: "); + System.out.println("\t-jdkhome where all jars will be parsed"); + System.out.println("\t-config "); + System.out.println("\t-output "); + System.out.println("\t-classlist print class list and summary"); + System.exit(-1); + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/CheckDeps.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/CheckDeps.java new file mode 100644 index 0000000000000000000000000000000000000000..ea73b43e3fc330ac338963091de6ab99764551ca --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/CheckDeps.java @@ -0,0 +1,181 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.classanalyzer; + +import java.io.*; +import java.util.*; + +/** + * A simple tool to check module dependencies against a known list of + * dependencies. The tool fails (by throwing a RuntimeException) is an + * unexpected dependency is detected. + */ + +public class CheckDeps { + + /** + * Represents a dependency from one module to another module. The dependency + * may be optional. + */ + static class Dependency { + private final String module; + private final String other; + private final boolean optional; + + private Dependency(String module, String other, boolean optional) { + this.module = module; + this.other = other; + this.optional = optional; + } + + String module() { return module; } + String other() { return other; } + boolean isOptional() { return optional; } + + /** + * Parses a dependency in one of the following forms: + * a -> b + * [optional] a -> b + */ + static Dependency fromString(String s) { + String[] components = s.split(" "); + int count = components.length; + if (count != 3 && count != 4) + throw new IllegalArgumentException(s); + boolean optional = (count == 4); + if (optional && !components[0].equals("[optional]")) + throw new IllegalArgumentException(s); + String arrow = optional ? components[2] : components[1]; + if (!arrow.equals("->")) + throw new IllegalArgumentException(s); + String module = optional ? components[1] : components[0]; + String other = optional ? components[3] : components[2]; + return new Dependency(module, other, optional); + } + + @Override public String toString() { + StringBuilder sb = new StringBuilder(); + if (optional) + sb.append("[optional] "); + sb.append(module); + sb.append(" -> "); + sb.append(other); + return sb.toString(); + } + } + + /** + * Represents the "tail" + */ + static class DependencyTail { + private final String module; + private final boolean optional; + + DependencyTail(String module, boolean optional) { + this.module = module; + this.optional = optional; + } + String module() { return module; } + boolean isOptional() { return optional; } + } + + static void usage() { + System.out.println("java CheckDeps file1 file2"); + System.out.println(" where file1 is the expected dependencies and file2 is"); + System.out.println(" the actual dependencies. Both files are assumed to be"); + System.out.println(" in modules.summary format (see ClassAnalyzer tool)."); + System.out.println(); + System.out.println("Example usages:"); + System.out.println(" java CheckDeps make/modules/modules.summary " + + "$(OUTPUTDIR)/modules.summary"); + System.exit(-1); + } + + public static void main(String[] args) throws IOException { + if (args.length != 2) + usage(); + + // maps a module to the list of modules that it depends on + Map> expected = + new HashMap>(); + + // parse the expected dependencies file + Scanner s; + s = new Scanner(new FileInputStream(args[0])); + try { + while (s.hasNextLine()) { + Dependency ref = Dependency.fromString(s.nextLine()); + if (ref != null) { + String module = ref.module(); + List list = expected.get(module); + if (list == null) { + list = new ArrayList(); + expected.put(module, list); + } + list.add(new DependencyTail(ref.other(), ref.isOptional())); + } + } + } finally { + s.close(); + } + + // parse the actual dependencies file, checking each dependency + // against the expected list. + boolean fail = false; + s = new Scanner(new FileInputStream(args[1])); + try { + while (s.hasNextLine()) { + Dependency dep = Dependency.fromString(s.nextLine()); + + // check if this dependency is expected + List list = expected.get(dep.module()); + DependencyTail tail = null; + if (list != null) { + for (DependencyTail t: list) { + if (t.module().equals(dep.other())) { + tail = t; + break; + } + } + } + if (tail == null) { + System.err.println("Unexpected dependency: " + dep); + fail = true; + } else { + // hard dependency when optional dependency is expected + if (tail.isOptional() != dep.isOptional()) { + if (tail.isOptional()) { + System.err.println("Unexpected dependency: " + dep); + fail = true; + } + } + } + } + } finally { + s.close(); + } + + if (fail) + throw new RuntimeException("Unexpected dependencies found"); + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassAnalyzer.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassAnalyzer.java new file mode 100644 index 0000000000000000000000000000000000000000..fd570a7c0b1373101c3e0325fefc055446752a5e --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassAnalyzer.java @@ -0,0 +1,354 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.classanalyzer; + +import com.sun.classanalyzer.AnnotatedDependency.*; +import com.sun.classanalyzer.Module.Dependency; +import com.sun.classanalyzer.Module.PackageInfo; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.io.File; +import java.io.PrintWriter; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * + * @author Mandy Chung + */ +public class ClassAnalyzer { + + public static void main(String[] args) throws Exception { + String jdkhome = null; + String cpath = null; + List configs = new ArrayList(); + List depconfigs = new ArrayList(); + String output = "."; + boolean mergeModules = true; + boolean showDynamic = false; + + // process arguments + int i = 0; + while (i < args.length) { + String arg = args[i++]; + if (arg.equals("-jdkhome")) { + if (i < args.length) { + jdkhome = args[i++]; + } else { + usage(); + } + } else if (arg.equals("-cpath")) { + if (i < args.length) { + cpath = args[i++]; + } else { + usage(); + } + } else if (arg.equals("-config")) { + if (i < args.length) { + configs.add(args[i++]); + } else { + usage(); + } + } else if (arg.equals("-depconfig")) { + if (i < args.length) { + depconfigs.add(args[i++]); + } else { + usage(); + } + } else if (arg.equals("-output")) { + if (i < args.length) { + output = args[i++]; + } else { + usage(); + } + } else if (arg.equals("-base")) { + ModuleConfig.setBaseModule(args[i++]); + } else if (arg.equals("-nomerge")) { + // analyze the fine-grained module dependencies + mergeModules = false; + } else if (arg.equals("-showdynamic")) { + showDynamic = true; + } else { + System.err.println("Invalid option: " + arg); + usage(); + } + } + + if ((jdkhome == null && cpath == null) || (jdkhome != null && cpath != null)) { + usage(); + } + if (configs.isEmpty()) { + usage(); + } + + if (jdkhome != null) { + ClassPath.setJDKHome(jdkhome); + } else if (cpath != null) { + ClassPath.setClassPath(cpath); + } + + // create output directory if it doesn't exist + File dir = new File(output); + if (!dir.isDirectory()) { + if (!dir.exists()) { + boolean created = dir.mkdir(); + if (!created) { + throw new RuntimeException("Unable to create `" + dir + "'"); + } + } + } + + buildModules(configs, depconfigs, mergeModules); + + // generate output files + for (Module m : modules) { + // only generate reports for top-level modules + if (m.group() == m) { + m.printClassListTo(resolve(dir, m.name(), "classlist")); + m.printResourceListTo(resolve(dir, m.name(), "resources")); + m.printSummaryTo(resolve(dir, m.name(), "summary")); + m.printDependenciesTo(resolve(dir, m.name(), "dependencies"), showDynamic); + } + } + + // Generate other summary reports + printModulesSummary(dir, showDynamic); + printModulesDot(dir, showDynamic); + printModulesList(dir); + printPackagesSummary(dir); + } + private static List modules = new ArrayList(); + + static void buildModules(List configs, + List depconfigs, + boolean mergeModules) throws IOException { + // create modules based on the input config files + for (String file : configs) { + for (ModuleConfig mconfig : ModuleConfig.readConfigurationFile(file)) { + modules.add(Module.addModule(mconfig)); + } + } + + // parse class files + ClassPath.parseAllClassFiles(); + + // Add additional dependencies if specified + if (depconfigs != null && depconfigs.size() > 0) { + DependencyConfig.parse(depconfigs); + } + + // process the roots and dependencies to get the classes for each module + for (Module m : modules) { + m.processRootsAndReferences(); + } + + // update the dependencies for classes that were subsequently allocated + // to modules + for (Module m : modules) { + m.fixupDependencies(); + } + + if (mergeModules) { + Module.buildModuleMembers(); + } + } + + private static void printModulesSummary(File dir, boolean showDynamic) throws IOException { + // print summary of dependencies + PrintWriter writer = new PrintWriter(new File(dir, "modules.summary")); + try { + for (Module m : modules) { + // only show top-level module dependencies + if (m.group() == m) { + for (Dependency dep : m.dependents()) { + if (!showDynamic && dep.dynamic && dep.optional) { + continue; + } + if (dep.module == null || !dep.module.isBase()) { + + String prefix = ""; + if (dep.optional) { + if (dep.dynamic) { + prefix = "[dynamic] "; + } else { + prefix = "[optional] "; + } + } + + Module other = dep != null ? dep.module : null; + writer.format("%s%s -> %s%n", prefix, m, other); + } + } + } + } + } finally { + writer.close(); + } + } + + private static void printModulesDot(File dir, boolean showDynamic) throws IOException { + PrintWriter writer = new PrintWriter(new File(dir, "modules.dot")); + try { + writer.println("digraph jdk {"); + for (Module m : modules) { + if (m.group() == m) { + for (Dependency dep : m.dependents()) { + if (!showDynamic && dep.dynamic && dep.optional) { + continue; + } + if (dep.module == null || !dep.module.isBase()) { + String style = ""; + String color = ""; + String property = ""; + if (dep.optional) { + style = "style=dotted"; + } + if (dep.dynamic) { + color = "color=red"; + } + if (style.length() > 0 || color.length() > 0) { + String comma = ""; + if (style.length() > 0 && color.length() > 0) { + comma = ", "; + } + property = String.format(" [%s%s%s]", style, comma, color); + } + Module other = dep != null ? dep.module : null; + writer.format(" \"%s\" -> \"%s\"%s;%n", m, other, property); + } + } + } + } + writer.println("}"); + } finally { + writer.close(); + } + } + + private static void printMembers(Module m, PrintWriter writer) { + for (Module member : m.members()) { + if (!member.isEmpty()) { + writer.format("%s ", member); + printMembers(member, writer); + } + } + } + + private static void printModulesList(File dir) throws IOException { + // print module group / members relationship + PrintWriter writer = new PrintWriter(new File(dir, "modules.list")); + try { + for (Module m : modules) { + if (m.group() == m && !m.isEmpty()) { + writer.format("%s ", m); + printMembers(m, writer); + writer.println(); + } + } + } finally { + writer.close(); + } + } + + private static void printPackagesSummary(File dir) throws IOException { + // print package / module relationship + PrintWriter writer = new PrintWriter(new File(dir, "modules.pkginfo")); + try { + Map> packages = new TreeMap>(); + Set splitPackages = new TreeSet(); + + for (Module m : modules) { + if (m.group() == m) { + for (PackageInfo info : m.getPackageInfos()) { + Set value = packages.get(info.pkgName); + if (value == null) { + value = new TreeSet(); + packages.put(info.pkgName, value); + } else { + // package in more than one module + splitPackages.add(info.pkgName); + } + value.add(m); + } + } + } + + // packages that are splitted among multiple modules + writer.println("Packages splitted across modules:-\n"); + writer.format("%-60s %s\n", "Package", "Module"); + + for (String pkgname : splitPackages) { + writer.format("%-60s", pkgname); + for (Module m : packages.get(pkgname)) { + writer.format(" %s", m); + } + writer.println(); + } + + writer.println("\nPackage-private dependencies:-"); + for (String pkgname : splitPackages) { + for (Klass k : Klass.getAllClasses()) { + if (k.getPackageName().equals(pkgname)) { + Module m = k.getModule(); + // check if this klass references a package-private + // class that is in a different module + for (Klass other : k.getReferencedClasses()) { + if (other.getModule() != m && + !other.isPublic() && + other.getPackageName().equals(pkgname)) { + String from = k.getClassName() + " (" + m + ")"; + writer.format("%-60s -> %s (%s)\n", from, other, other.getModule()); + } + } + } + } + } + } finally { + writer.close(); + } + + } + + private static String resolve(File dir, String mname, String suffix) { + File f = new File(dir, mname + "." + suffix); + return f.toString(); + + } + + private static void usage() { + System.out.println("Usage: ClassAnalyzer "); + System.out.println("Options: "); + System.out.println("\t-jdkhome where all jars will be parsed"); + System.out.println("\t-cpath where classes and jars will be parsed"); + System.out.println("\t Either -jdkhome or -cpath option can be used."); + System.out.println("\t-config "); + System.out.println("\t This option can be repeated for multiple module config files"); + System.out.println("\t-output "); + System.out.println("\t-nomerge specify not to merge modules"); + System.out.println("\t-showdynamic show dynamic dependencies in the reports"); + System.exit(-1); + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassFileParser.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassFileParser.java new file mode 100644 index 0000000000000000000000000000000000000000..bbbeda7407f00c21a005662b0a359f6fe9640176 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassFileParser.java @@ -0,0 +1,629 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ +package com.sun.classanalyzer; + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.Type.*; +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; +import static com.sun.tools.classfile.AccessFlags.*; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +/** + * + * @author Mandy Chung + */ +public class ClassFileParser { + + final Klass this_klass; + final ClassFile classfile; + final ConstantPoolParser constantPoolParser; + final AnnotationParser annotationParser; + final CodeAttributeParser codeAttributeParser; + private final boolean buildDeps; + + protected ClassFileParser(InputStream in, long size, boolean buildDeps) throws IOException { + try { + this.classfile = ClassFile.read(in); + this.this_klass = getKlass(this.classfile); + this.buildDeps = buildDeps; + this.constantPoolParser = new ConstantPoolParser(this); + this.annotationParser = new AnnotationParser(this); + this.codeAttributeParser = new CodeAttributeParser(this); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + + private Klass getKlass(ClassFile cf) throws ConstantPoolException { + Klass k = Klass.getKlass(cf.getName()); + k.setAccessFlags(cf.access_flags.flags); + k.setFileSize(cf.byteLength()); + return k; + } + + public static ClassFileParser newParser(InputStream in, long size, boolean buildDeps) throws IOException { + return new ClassFileParser(in, size, buildDeps); + } + + public static ClassFileParser newParser(String classPathname, boolean buildDeps) throws IOException { + return newParser(new File(classPathname), buildDeps); + } + + public static ClassFileParser newParser(File f, boolean buildDeps) throws IOException { + BufferedInputStream in = new BufferedInputStream(new FileInputStream(f)); + try { + return newParser(in, f.length(), buildDeps); + } finally { + in.close(); + } + } + + public void parseDependency(boolean publicAPIs) throws IOException { + if (publicAPIs && !classfile.access_flags.is(ACC_PUBLIC)) { + // process public APIs only + return; + } + + parseClassInfo(); + if (!publicAPIs) { + // parse all references in the classfile + constantPoolParser.parseDependency(); + } + parseMethods(publicAPIs); + parseFields(publicAPIs); + } + + void parseClassInfo() throws IOException { + ConstantPool cpool = classfile.constant_pool; + try { + Signature_attribute sigAttr = (Signature_attribute) classfile.attributes.get(Attribute.Signature); + if (sigAttr == null) { + // use info from class file header + if (classfile.isClass() && classfile.super_class != 0) { + String sn = classfile.getSuperclassName(); + addExtends(sn); + } + for (int i = 0; i < classfile.interfaces.length; i++) { + String interf = classfile.getInterfaceName(i); + if (classfile.isClass()) { + addImplements(interf); + } else { + addExtends(interf); + } + } + } else { + Type t = sigAttr.getParsedSignature().getType(cpool); + // The signature parser cannot disambiguate between a + // FieldType and a ClassSignatureType that only contains a superclass type. + if (t instanceof Type.ClassSigType) { + Type.ClassSigType cst = Type.ClassSigType.class.cast(t); + if (cst.superclassType != null) { + for (Klass k : getKlass(cst.superclassType)) { + addExtends(k); + } + } + if (cst.superinterfaceTypes != null) { + for (Type t1 : cst.superinterfaceTypes) { + for (Klass k : getKlass(t1)) { + addImplements(k); + } + } + } + } else { + for (Klass k : getKlass(t)) { + addExtends(k); + } + } + } + // parse attributes + annotationParser.parseAttributes(classfile.attributes); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + + private void parseFields(boolean publicAPIs) throws IOException { + ConstantPool cpool = classfile.constant_pool; + for (Field f : classfile.fields) { + try { + AccessFlags flags = f.access_flags; + if (publicAPIs && !flags.is(ACC_PUBLIC) && !flags.is(ACC_PROTECTED)) { + continue; + } + String fieldname = f.getName(cpool); + Signature_attribute sigAttr = (Signature_attribute) f.attributes.get(Attribute.Signature); + + if (sigAttr == null) { + Set types = parseDescriptor(f.descriptor); + String info = getFlag(flags) + " " + f.descriptor.getFieldType(cpool) + " " + fieldname; + addFieldTypes(types, info, flags); + } else { + Type t = sigAttr.getParsedSignature().getType(cpool); + String info = getFlag(flags) + " " + t + " " + fieldname; + addFieldTypes(getKlass(t), info, flags); + } + // parse attributes + annotationParser.parseAttributes(f.attributes); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } catch (InvalidDescriptor ex) { + throw new RuntimeException(ex); + } + } + } + + private void parseMethods(boolean publicAPIs) { + for (Method m : classfile.methods) { + if (publicAPIs && !m.access_flags.is(ACC_PUBLIC) && !m.access_flags.is(ACC_PROTECTED)) { + // only interest in the API level + return; + } + + parseMethod(m); + } + } + + String checkClassName(String classname) { + int i = 0; + while (i < classname.length()) { + switch (classname.charAt(i)) { + case 'Z': + case 'B': + case 'C': + case 'S': + case 'I': + case 'J': + case 'F': + case 'D': + return ""; + case 'L': + if (!classname.endsWith(";")) { + throw new RuntimeException("Invalid classname " + classname); + } + return classname.substring(i + 1, classname.length() - 1); + case '[': + i++; + break; + default: + if (classname.endsWith(";")) { + throw new RuntimeException("Invalid classname " + classname); + } + return classname; + + } + } + throw new RuntimeException("Invalid classname " + classname); + } + + private void addExtends(String classname) throws IOException { + if (!buildDeps) { + return; + } + + addExtends(Klass.getKlass(classname)); + } + + private void addExtends(Klass k) { + if (!buildDeps) { + return; + } + + ResolutionInfo resInfo = ResolutionInfo.resolvedExtends(this_klass, k); + resInfo.setPublicAccess(classfile.access_flags.is(ACC_PUBLIC)); + this_klass.addDep(k, resInfo); + k.addReferrer(this_klass, resInfo); + } + + private void addImplements(String classname) throws IOException { + if (!buildDeps) { + return; + } + + addImplements(Klass.getKlass(classname)); + } + + private void addImplements(Klass k) { + if (!buildDeps) { + return; + } + + ResolutionInfo resInfo = ResolutionInfo.resolvedImplements(this_klass, k); + resInfo.setPublicAccess(classfile.access_flags.is(ACC_PUBLIC)); + + this_klass.addDep(k, resInfo); + + k.addReferrer(this_klass, resInfo); + } + + private Set getKlass(Type type) throws IOException { + Set refTypes = new TreeSet(); + if (!buildDeps) { + return refTypes; + } + + type.accept(typevisitor, refTypes); + return refTypes; + } + private Type.Visitor> typevisitor = new Type.Visitor>() { + + public Void visitSimpleType(SimpleType type, Set klasses) { + // nop + return null; + } + + public Void visitArrayType(ArrayType type, Set klasses) { + try { + klasses.addAll(getKlass(type.elemType)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + return null; + + } + + public Void visitMethodType(MethodType type, Set klasses) { + throw new InternalError("Unexpected type " + type); + } + + public Void visitClassSigType(ClassSigType type, Set klasses) { + try { + if (type.superclassType != null) { + klasses.addAll(getKlass(type.superclassType)); + } + if (type.superinterfaceTypes != null) { + for (Type t : type.superinterfaceTypes) { + klasses.addAll(getKlass(t)); + } + } + if (type.typeParamTypes != null) { + for (Type t : type.typeParamTypes) { + klasses.addAll(getKlass(t)); + } + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + return null; + } + + public Void visitClassType(ClassType type, Set klasses) { + klasses.add(Klass.getKlass(type.getBinaryName())); + if (type.typeArgs != null) { + for (Type t : type.typeArgs) { + try { + klasses.addAll(getKlass(t)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } + return null; + + } + + public Void visitTypeParamType(TypeParamType type, Set klasses) { + try { + if (type.classBound != null) { + klasses.addAll(getKlass(type.classBound)); + } + if (type.interfaceBounds != null) { + for (Type t : type.interfaceBounds) { + klasses.addAll(getKlass(t)); + } + } + + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + return null; + + } + + public Void visitWildcardType(WildcardType type, Set klasses) { + if (type.boundType != null) { + try { + klasses.addAll(getKlass(type.boundType)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + return null; + + } + }; + + private void printMethod(Method m) { + try { + System.out.println("parsing " + m.getName(classfile.constant_pool) + "(" + + m.descriptor.getParameterTypes(classfile.constant_pool) + ") return type " + + m.descriptor.getReturnType(classfile.constant_pool)); + + } catch (ConstantPoolException ex) { + } catch (InvalidDescriptor ex) { + } + } + + private static StringBuilder appendWord(StringBuilder sb, String word) { + if (sb.length() > 0) { + sb.append(" "); + } + sb.append(word); + return sb; + } + + private static String getFlag(AccessFlags flags) { + StringBuilder modifier = new StringBuilder(); + if (flags.is(ACC_PUBLIC)) { + modifier.append("public"); + } + if (flags.is(ACC_PRIVATE)) { + modifier.append("private"); + } + if (flags.is(ACC_PROTECTED)) { + modifier.append("protected"); + } + if (flags.is(ACC_STATIC)) { + appendWord(modifier, "static"); + } + if (flags.is(ACC_FINAL)) { + appendWord(modifier, "final"); + } + if (flags.is(ACC_SYNCHRONIZED)) { + // return "synchronized"; + } + if (flags.is(0x80)) { + // return (t == Type.Field ? "transient" : null); + // return "transient"; + } + if (flags.is(ACC_VOLATILE)) { + // return "volatile"; + } + if (flags.is(ACC_NATIVE)) { + // return "native"; + } + if (flags.is(ACC_ABSTRACT)) { + appendWord(modifier, "abstract"); + } + if (flags.is(ACC_STRICT)) { + // return "strictfp"; + } + if (flags.is(ACC_MODULE)) { + appendWord(modifier, "module"); + } + return modifier.toString(); + } + + private Klass.Method toKlassMethod(Method m, Descriptor d) { + try { + ConstantPool cpool = classfile.constant_pool; + String methodname = m.getName(cpool); + StringBuilder sb = new StringBuilder(); + sb.append(getFlag(m.access_flags)); + if (methodname.equals("")) { + String s = this_klass.getBasename() + d.getParameterTypes(cpool); + appendWord(sb, s); + } else if (methodname.equals("")) { + // + appendWord(sb, methodname); + } else { + String s = d.getReturnType(cpool) + " " + methodname + d.getParameterTypes(cpool); + appendWord(sb, s); + } + String signature = sb.toString().replace('/', '.'); + return this_klass.getMethod(methodname, signature); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } catch (InvalidDescriptor ex) { + throw new RuntimeException(ex); + } + } + + Klass.Method parseMethod(Method m) { + AccessFlags flags = m.access_flags; + Descriptor d; + List methodExceptions = null; + try { + ConstantPool cpool = classfile.constant_pool; + Klass.Method kmethod; + Signature_attribute sigAttr = (Signature_attribute) m.attributes.get(Attribute.Signature); + if (sigAttr == null) { + d = m.descriptor; + Set types = parseDescriptor(d); + + kmethod = toKlassMethod(m, d); + addMethodTypes(types, kmethod, flags); + } else { + Type.MethodType methodType; + Signature methodSig = sigAttr.getParsedSignature(); + d = methodSig; + try { + kmethod = toKlassMethod(m, d); + methodType = (Type.MethodType) methodSig.getType(cpool); + addMethodTypes(getKlass(methodType.returnType), kmethod, flags); + if (methodType.paramTypes != null) { + for (Type t : methodType.paramTypes) { + addMethodTypes(getKlass(t), kmethod, flags); + } + } + if (methodType.typeParamTypes != null) { + for (Type t : methodType.typeParamTypes) { + addMethodTypes(getKlass(t), kmethod, flags); + } + } + + methodExceptions = methodType.throwsTypes; + if (methodExceptions != null) { + if (methodExceptions.size() == 0) { + methodExceptions = null; + } else { + for (Type t : methodExceptions) { + addCheckedExceptionTypes(getKlass(t), kmethod, flags); + } + } + } + } catch (ConstantPoolException e) { + throw new RuntimeException(e); + } + } + + Attribute e_attr = m.attributes.get(Attribute.Exceptions); + if (e_attr != null && methodExceptions == null) { + // if there are generic exceptions, there must be erased exceptions + if (e_attr instanceof Exceptions_attribute) { + Exceptions_attribute exceptions = (Exceptions_attribute) e_attr; + for (int i = 0; i < exceptions.number_of_exceptions; i++) { + String classname = checkClassName(exceptions.getException(i, classfile.constant_pool)); + if (classname.length() > 0 && buildDeps) { + Klass to = Klass.getKlass(classname); + ResolutionInfo resInfo = ResolutionInfo.resolvedCheckedException(this_klass, to, kmethod); + resInfo.setPublicAccess(flags.is(ACC_PUBLIC)); + + this_klass.addDep(to, resInfo); + to.addReferrer(this_klass, resInfo); + } + } + } else { + throw new RuntimeException("Invalid attribute: " + e_attr); + } + } + + Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code); + if (c_attr != null) { + codeAttributeParser.parse(c_attr, kmethod); + } + kmethod.isAbstract = classfile.access_flags.is(ACC_ABSTRACT); + kmethod.setCodeLength(m.byteLength()); + + // parse annotation attributes + annotationParser.parseAttributes(m.attributes, kmethod); + return kmethod; + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + private void addFieldTypes(Set types, String info, AccessFlags flags) { + if (types.isEmpty() || !buildDeps) { + return; + } + + for (Klass to : types) { + ResolutionInfo resInfo = ResolutionInfo.resolvedField(this_klass, to, info); + resInfo.setPublicAccess(flags.is(ACC_PUBLIC)); + + this_klass.addDep(to, resInfo); + to.addReferrer(this_klass, resInfo); + } + } + + private void addReferencedTypes(Method m, Descriptor d, AccessFlags flags) { + Set types = parseDescriptor(d); + + Klass.Method method = toKlassMethod(m, d); + addMethodTypes(types, method, flags); + } + + private void addMethodTypes(Set types, Klass.Method method, AccessFlags flags) { + if (types.isEmpty() || !buildDeps) { + return; + } + for (Klass to : types) { + ResolutionInfo resInfo = ResolutionInfo.resolvedMethodSignature(this_klass, to, method); + resInfo.setPublicAccess(flags.is(ACC_PUBLIC)); + + this_klass.addDep(to, resInfo); + to.addReferrer(this_klass, resInfo); + } + } + + private void addCheckedExceptionTypes(Set types, Klass.Method method, AccessFlags flags) { + if (types.isEmpty() || !buildDeps) { + return; + } + for (Klass to : types) { + ResolutionInfo resInfo = ResolutionInfo.resolvedCheckedException(this_klass, to, method); + resInfo.setPublicAccess(flags.is(ACC_PUBLIC)); + + this_klass.addDep(to, resInfo); + to.addReferrer(this_klass, resInfo); + } + } + + private Set parseDescriptor(Descriptor d) { + Set types = new TreeSet(); + try { + String desc = d.getValue(classfile.constant_pool); + int p = 0; + while (p < desc.length()) { + String type; + char ch; + switch (ch = desc.charAt(p++)) { + case '(': + case ')': + case '[': + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + case 'Z': + case 'V': + continue; + case 'L': + int sep = desc.indexOf(';', p); + if (sep == -1) { + throw new RuntimeException("Invalid descriptor: " + (p - 1) + " " + desc); + } + type = checkClassName(desc.substring(p, sep)); + p = sep + 1; + break; + default: + throw new RuntimeException("Invalid descriptor: " + (p - 1) + " " + desc); + } + + if (!type.isEmpty() && buildDeps) { + Klass to = Klass.getKlass(type); + types.add(to); + + } + } + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + return types; + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassPath.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassPath.java new file mode 100644 index 0000000000000000000000000000000000000000..bfdcdd97f5999c3dfc82e30af1a03fcbdc573154 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassPath.java @@ -0,0 +1,275 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ +package com.sun.classanalyzer; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * + * @author mchung + */ +public class ClassPath { + + public class FileInfo { + + File file; + JarFile jarfile; + int classCount; + long filesize; + + FileInfo(File f) throws IOException { + this.file = f; + this.classCount = 0; + if (file.getName().endsWith(".jar")) { + this.filesize = file.length(); + jarfile = new JarFile(f); + } + } + + File getFile() { + return file; + } + + JarFile getJarFile() { + return jarfile; + } + + String getName() throws IOException { + return file.getCanonicalPath(); + } + } + private List fileList = new ArrayList(); + private static ClassPath instance = new ClassPath(); + + static List getFileInfos() { + return instance.fileList; + } + + static ClassPath setJDKHome(String jdkhome) throws IOException { + List files = new ArrayList(); + File jre = new File(jdkhome, "jre"); + File lib = new File(jdkhome, "lib"); + if (jre.exists() && jre.isDirectory()) { + listFiles(new File(jre, "lib"), ".jar", files); + } else if (lib.exists() && lib.isDirectory()) { + // either a JRE or a jdk build image + listFiles(lib, ".jar", files); + + File classes = new File(jdkhome, "classes"); + if (classes.exists() && classes.isDirectory()) { + // jdk build outputdir + instance.add(classes); + } + } else { + throw new RuntimeException("\"" + jdkhome + "\" not a JDK home"); + } + + for (File f : files) { + instance.add(f); + } + return instance; + } + + static ClassPath setClassPath(String path) throws IOException { + if (path.endsWith(".class")) { + // one class file + File f = new File(path); + if (!f.exists()) { + throw new RuntimeException("Classfile \"" + f + "\" doesn't exist"); + } + + instance.add(f); + } else { + List jarFiles = new ArrayList(); + String[] locs = path.split(File.pathSeparator); + for (String p : locs) { + File f = new File(p); + if (!f.exists()) { + throw new RuntimeException("\"" + f + "\" doesn't exist"); + } + + if (f.isDirectory()) { + instance.add(f); // add the directory to look up .class files + listFiles(f, ".jar", jarFiles); + } else if (p.endsWith(".jar")) { + // jar files + jarFiles.add(f); + } else { + throw new RuntimeException("Invalid file \"" + f); + } + } + // add jarFiles if any + for (File f : jarFiles) { + instance.add(f); + } + } + + return instance; + } + + private void add(File f) throws IOException { + fileList.add(new FileInfo(f)); + } + + public static InputStream open(String pathname) throws IOException { + for (FileInfo fi : instance.fileList) { + if (fi.getName().endsWith(".jar")) { + String path = pathname.replace(File.separatorChar, '/'); + JarEntry e = fi.jarfile.getJarEntry(path); + if (e != null) { + return fi.jarfile.getInputStream(e); + } + } else if (fi.getFile().isDirectory()) { + File f = new File(fi.getFile(), pathname); + if (f.exists()) { + return new FileInputStream(f); + } + } else if (fi.file.isFile()) { + if (fi.getName().endsWith(File.separator + pathname)) { + return new FileInputStream(fi.file); + } + } + } + return null; + } + + static ClassFileParser parserForClass(String classname) throws IOException { + String pathname = classname.replace('.', File.separatorChar) + ".class"; + + ClassFileParser cfparser = null; + for (FileInfo fi : instance.fileList) { + if (fi.getName().endsWith(".class")) { + if (fi.getName().endsWith(File.separator + pathname)) { + cfparser = ClassFileParser.newParser(fi.getFile(), true); + break; + } + } else if (fi.getName().endsWith(".jar")) { + JarEntry e = fi.jarfile.getJarEntry(classname.replace('.', '/') + ".class"); + if (e != null) { + cfparser = ClassFileParser.newParser(fi.jarfile.getInputStream(e), e.getSize(), true); + break; + } + } else if (fi.getFile().isDirectory()) { + File f = new File(fi.getFile(), pathname); + if (f.exists()) { + cfparser = ClassFileParser.newParser(f, true); + break; + } + } + } + return cfparser; + } + + public static void parseAllClassFiles() throws IOException { + instance.parseFiles(); + } + + private void parseFiles() throws IOException { + Set classes = new HashSet(); + + int count = 0; + for (FileInfo fi : fileList) { + // filter out public generated classes (i.e. not public API) + // javax.management.remote.rmi._RMIConnectionImpl_Tie + // javax.management.remote.rmi._RMIServerImpl_Tie + if (fi.getName().endsWith(".class")) { + parseClass(fi); + } else if (fi.getName().endsWith(".jar")) { + Enumeration entries = fi.jarfile.entries(); + while (entries.hasMoreElements()) { + JarEntry e = entries.nextElement(); + if (e.getName().endsWith(".class")) { + ClassFileParser cfparser = ClassFileParser.newParser(fi.jarfile.getInputStream(e), e.getSize(), true); + cfparser.parseDependency(false); + fi.classCount++; + } else if (!e.isDirectory() && ResourceFile.isResource(e.getName())) { + ResourceFile.addResource(e.getName(), fi.jarfile.getInputStream(e)); + } + } + } else if (fi.getFile().isDirectory()) { + List files = new ArrayList(); + listFiles(fi.getFile(), "", files); + for (File f : files) { + if (f.getName().endsWith(".class")) { + parseClass(fi, f); + } else if (!f.isDirectory() && ResourceFile.isResource(f.getCanonicalPath())) { + String pathname = f.getCanonicalPath(); + String dir = fi.getName(); + if (!pathname.startsWith(dir)) { + throw new RuntimeException("Incorrect pathname " + pathname); + } + String name = pathname.substring(dir.length() + 1, pathname.length()); + BufferedInputStream in = new BufferedInputStream(new FileInputStream(f)); + try { + ResourceFile.addResource(name, in); + } finally { + in.close(); + } + } + } + } else { + // should not reach here + throw new RuntimeException("Unexpected class path: " + fi.getFile()); + } + } + } + + private void parseClass(FileInfo fi) throws IOException { + parseClass(fi, fi.getFile()); + } + + private void parseClass(FileInfo fi, File f) throws IOException { + ClassFileParser cfparser = ClassFileParser.newParser(f, true); + cfparser.parseDependency(false); + fi.classCount++; + // need to update the filesize for this directory + fi.filesize += fi.getFile().length(); + + } + + public static void listFiles(File path, String suffix, List result) { + if (path.isDirectory()) { + File[] children = path.listFiles(); + for (File c : children) { + listFiles(c, suffix, result); + } + + } else { + if (suffix.isEmpty() || path.getName().endsWith(suffix)) { + result.add(path); + } + } + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/CodeAttributeParser.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/CodeAttributeParser.java new file mode 100644 index 0000000000000000000000000000000000000000..98ff1a4927702b3d55e7909c1d9c663d1e416219 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/CodeAttributeParser.java @@ -0,0 +1,157 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.classanalyzer; + +import com.sun.classanalyzer.Klass.Method; + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.Instruction.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +/** + * + * @author Mandy Chung + */ +public class CodeAttributeParser { + private final ClassFileParser cfparser; + private final ConstantPool cpool; + private final ConstantPoolParser constantPoolParser; + + + static final Map> runtimeReferences = + new HashMap>(); + + + CodeAttributeParser(ClassFileParser parser) { + this.cfparser = parser; + this.cpool = cfparser.classfile.constant_pool; + this.constantPoolParser = cfparser.constantPoolParser; + } + + static boolean parseCodeAttribute = false; // by default don't parse code attribute + static void setParseCodeAttribute(boolean newValue) { + parseCodeAttribute = newValue; + } + + void parse(Code_attribute attr, Klass.Method method) { + if (!parseCodeAttribute) { + return; + } + + for (Instruction instr : attr.getInstructions()) { + try { + instr.accept(instructionVisitor, method); + } catch (ArrayIndexOutOfBoundsException e) { + throw new RuntimeException("error at or after byte " + instr.getPC()); + } + + } + + if (attr.exception_table_langth > 0) { + for (int i = 0; i < + attr.exception_table.length; i++) { + Code_attribute.Exception_data handler = attr.exception_table[i]; + int catch_type = handler.catch_type; + if (catch_type > 0) { + addMethodReference(catch_type, method); + } + + } + } + + } + + + private void addMethodReference(int index, Klass.Method m) { + String method = constantPoolParser.getMethodName(index); + + if (method != null && + (method.equals("java.lang.Class.forName") || + method.equals("java.lang.Class.loadClass") || + method.startsWith("java.util.ServiceLoader.load") || + method.equals("sun.misc.Service.providers"))) { + Set refs = runtimeReferences.get(method); + if (refs == null) { + refs = new TreeSet(); + runtimeReferences.put(method, refs); + } + refs.add(m); + } + } + + Instruction.KindVisitor instructionVisitor = + new Instruction.KindVisitor() { + + public Void visitNoOperands(Instruction instr, Klass.Method m) { + return null; + } + + public Void visitArrayType(Instruction instr, TypeKind kind, Klass.Method m) { + return null; + } + + public Void visitBranch(Instruction instr, int offset, Klass.Method m) { + return null; + } + + public Void visitConstantPoolRef(Instruction instr, int index, Klass.Method m) { + addMethodReference(index, m); + return null; + } + + public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Klass.Method m) { + addMethodReference(index, m); + return null; + } + + public Void visitLocal(Instruction instr, int index, Klass.Method m) { + return null; + } + + public Void visitLocalAndValue(Instruction instr, int index, int value, Klass.Method m) { + return null; + } + + public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Klass.Method m) { + return null; + } + + public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, Klass.Method m) { + return null; + } + + public Void visitValue(Instruction instr, int value, Klass.Method m) { + return null; + } + + public Void visitUnknown(Instruction instr, Klass.Method m) { + return null; + } + }; +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ConstantPoolAnalyzer.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ConstantPoolAnalyzer.java new file mode 100644 index 0000000000000000000000000000000000000000..f79f2bf6c36a6d891beec6a59465d2436444e50d --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ConstantPoolAnalyzer.java @@ -0,0 +1,60 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.classanalyzer; + +/** + * + * @author Mandy Chung + */ +public class ConstantPoolAnalyzer { + public static void main(String[] args) throws Exception { + String jdkhome = null; + + // process arguments + int i = 0; + while (i < args.length) { + String arg = args[i++]; + if (arg.equals("-jdkhome")) { + if (i < args.length) { + jdkhome = args[i++]; + } else { + usage(); + } + } + } + if (jdkhome == null) { + usage(); + } + ClassPath.setJDKHome(jdkhome); + ClassPath.parseAllClassFiles(); + } + + private static void usage() { + System.out.println("Usage: ConstantPoolAnalyzer "); + System.out.println("Options: "); + System.out.println("\t-jdkhome where all jars will be parsed"); + System.out.println("\t-cpath where classes and jars will be parsed"); + System.exit(-1); + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ConstantPoolParser.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ConstantPoolParser.java new file mode 100644 index 0000000000000000000000000000000000000000..33e593df875c8889a3949800f69b7157774bc418 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ConstantPoolParser.java @@ -0,0 +1,377 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.classanalyzer; + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.*; +import static com.sun.tools.classfile.ConstantPool.*; + +/** + * + * @author Mandy Chung + */ +public class ConstantPoolParser { + + private final ClassFileParser cfparser; + private final StringValueVisitor visitor; + private final ConstantPool cpool; + + ConstantPoolParser(ClassFileParser parser) { + this.cfparser = parser; + this.cpool = cfparser.classfile.constant_pool; + this.visitor = new StringValueVisitor(); + } + + public String stringValue(CPInfo cpInfo) { + return visitor.visit(cpInfo); + } + + public String stringValue(int constant_pool_index) { + try { + return stringValue(cpool.get(constant_pool_index)); + } catch (ConstantPool.InvalidIndex e) { + throw new RuntimeException(e); + } + } + + public void parseDependency() { + ConstantPool.Visitor v = new ConstantPool.Visitor() { + + public Integer visitClass(CONSTANT_Class_info info, Void p) { + try { + String classname = cfparser.checkClassName(info.getName()); + if (classname.isEmpty()) { + return 1; + } + + Klass from = cfparser.this_klass; + Klass to = Klass.getKlass(classname); + ResolutionInfo resInfo = ResolutionInfo.resolvedConstantPool(from, to, info.name_index); + + from.addDep(to, resInfo); + to.addReferrer(from, resInfo); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + return 1; + } + + public Integer visitDouble(CONSTANT_Double_info info, Void p) { + // skip + return 2; + } + + public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) { + // skip + return 1; + } + + public Integer visitFloat(CONSTANT_Float_info info, Void p) { + // skip + return 1; + } + + public Integer visitInteger(CONSTANT_Integer_info info, Void p) { + // skip + return 1; + } + + public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) { + // skip + return 1; + } + + public Integer visitLong(CONSTANT_Long_info info, Void p) { + // skip + return 2; + } + + public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) { + // skip + return 1; + } + + public Integer visitMethodref(CONSTANT_Methodref_info info, Void p) { + // skip + return 1; + } + + public Integer visitString(CONSTANT_String_info info, Void p) { + // skip + return 1; + } + + public Integer visitUtf8(CONSTANT_Utf8_info info, Void p) { + // skip + return 1; + } + }; + int cpx = 1; + while (cpx < cpool.size()) { + try { + CPInfo cpInfo = cpool.get(cpx); + cpx += cpInfo.accept(v, null); + } catch (ConstantPool.InvalidIndex ex) { + throw new RuntimeException(ex); + } + } + } + + int getTag(int index) { + try { + return cpool.get(index).getTag(); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + + String getDescriptor(int index) { + CPInfo cpInfo; + try { + cpInfo = cpool.get(index); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + + int tag = cpInfo.getTag(); + switch (tag) { + case CONSTANT_Methodref: + case CONSTANT_InterfaceMethodref: + case CONSTANT_Fieldref: + // simplify references within this class + CPRefInfo ref = (CPRefInfo) cpInfo; + try { + return ref.getNameAndTypeInfo().getType(); + } catch (ConstantPoolException ex) { + } + } + return stringValue(cpInfo); + } + + String getMethodName(int index) { + try { + CPInfo cpInfo = cpool.get(index); + if (cpInfo.getTag() == CONSTANT_Methodref || + cpInfo.getTag() == CONSTANT_InterfaceMethodref) { + + // simplify references within this class + CPRefInfo ref = (CPRefInfo) cpInfo; + String classname; + if (ref.class_index == cfparser.classfile.this_class) { + classname = cfparser.this_klass.getClassName(); + } else { + classname = cfparser.checkClassName(ref.getClassName()).replace('/', '.'); + } + String methodname = ref.getNameAndTypeInfo().getName(); + return classname + "." + methodname; + } else { + return null; + } + } catch (InvalidIndex ex) { + throw new RuntimeException(ex); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + + } + + class StringValueVisitor implements ConstantPool.Visitor { + + public StringValueVisitor() { + } + + public String visit(CPInfo info) { + return info.accept(this, null); + } + + public String visitClass(CONSTANT_Class_info info, Void p) { + return getCheckedName(info); + } + + String getCheckedName(CONSTANT_Class_info info) { + try { + return checkName(info.getName()); + } catch (ConstantPoolException e) { + throw new RuntimeException(e); + } + } + + public String visitDouble(CONSTANT_Double_info info, Void p) { + return info.value + "d"; + } + + public String visitFieldref(CONSTANT_Fieldref_info info, Void p) { + return visitRef(info, p); + } + + public String visitFloat(CONSTANT_Float_info info, Void p) { + return info.value + "f"; + } + + public String visitInteger(CONSTANT_Integer_info info, Void p) { + return String.valueOf(info.value); + } + + public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) { + return visitRef(info, p); + } + + public String visitLong(CONSTANT_Long_info info, Void p) { + return info.value + "l"; + } + + public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) { + return getCheckedName(info) + ":" + getType(info); + } + + String getCheckedName(CONSTANT_NameAndType_info info) { + try { + return checkName(info.getName()); + } catch (ConstantPoolException e) { + throw new RuntimeException(e); + } + } + + String getType(CONSTANT_NameAndType_info info) { + try { + return info.getType(); + } catch (ConstantPoolException e) { + throw new RuntimeException(e); + } + } + + public String visitMethodref(CONSTANT_Methodref_info info, Void p) { + return visitRef(info, p); + } + + public String visitString(CONSTANT_String_info info, Void p) { + try { + int string_index = info.string_index; + return cpool.getUTF8Info(string_index).accept(this, p); + } catch (ConstantPoolException e) { + throw new RuntimeException(e); + } + } + + public String visitUtf8(CONSTANT_Utf8_info info, Void p) { + String s = info.value; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '\t': + sb.append('\\').append('t'); + break; + case '\n': + sb.append('\\').append('n'); + break; + case '\r': + sb.append('\\').append('r'); + break; + case '\"': + sb.append('\\').append('\"'); + break; + default: + sb.append(c); + } + } + return sb.toString(); + } + + String visitRef(CPRefInfo info, Void p) { + String cn = getCheckedClassName(info); + String nat; + try { + nat = info.getNameAndTypeInfo().accept(this, p); + } catch (ConstantPoolException e) { + nat = e.getMessage(); + } + return cn + "." + nat; + } + + String getCheckedClassName(CPRefInfo info) { + try { + return checkName(info.getClassName()); + } catch (ConstantPoolException e) { + throw new RuntimeException(e); + } + } + } + /* If name is a valid binary name, return it; otherwise quote it. */ + + private static String checkName(String name) { + if (name == null) { + return "null"; + } + + int len = name.length(); + if (len == 0) { + return "\"\""; + } + + int cc = '/'; + int cp; + for (int k = 0; k < len; k += Character.charCount(cp)) { + cp = name.codePointAt(k); + if ((cc == '/' && !Character.isJavaIdentifierStart(cp)) || (cp != '/' && !Character.isJavaIdentifierPart(cp))) { + return "\"" + name + "\""; + } + cc = cp; + } + return name; + } + + String tagName(int index) { + try { + int tag = cpool.get(index).getTag(); + switch (tag) { + case CONSTANT_Utf8: + return "Utf8"; + case CONSTANT_Integer: + return "int"; + case CONSTANT_Float: + return "float"; + case CONSTANT_Long: + return "long"; + case CONSTANT_Double: + return "double"; + case CONSTANT_Class: + return "class"; + case CONSTANT_String: + return "String"; + case CONSTANT_Fieldref: + return "Field"; + case CONSTANT_Methodref: + return "Method"; + case CONSTANT_InterfaceMethodref: + return "InterfaceMethod"; + case CONSTANT_NameAndType: + return "NameAndType"; + default: + return "(unknown tag)"; + } + } catch (InvalidIndex e) { + throw new RuntimeException(e); + } + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/DependencyConfig.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/DependencyConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..107e1d10c85d82baffb61161390ba112529db924 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/DependencyConfig.java @@ -0,0 +1,99 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.classanalyzer; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.List; + +/** + * Config file specifying additional dependency + * Each line consists of: + * -> + * where can be: + * @ClassForName and is its dependency + * @Provider and is the service name + * @Providers and is the list of the service names + * + * @author Mandy Chung + */ +public class DependencyConfig { + private DependencyConfig() { + } + + static void parse(List configs) throws IOException { + for (String s : configs) { + parse(s); + } + } + + private static void parse(String config) throws IOException { + // parse configuration file + FileInputStream in = new FileInputStream(config); + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line; + int lineNumber = 0; + String type = null; + while ((line = reader.readLine()) != null) { + lineNumber++; + line = line.trim(); + if (line.length() == 0 || line.charAt(0) == '#') { + continue; + } + if (line.charAt(0) == '@') { + if (AnnotatedDependency.isValidType(line)) { + type = line; + continue; + } else { + throw new RuntimeException(config + ", line " + + lineNumber + ", invalid annotation type."); + } + } + String[] s = line.split("\\s+"); + if (s.length < 3 || !s[1].equals("->")) { + throw new RuntimeException(config + ", line " + + lineNumber + ", is malformed"); + } + String classname = s[0].trim(); + String value = s[2].trim(); + + Klass k = Klass.findKlass(classname); + if (k == null) { + // System.out.println("Warning: " + classname + " cannot be found"); + continue; + } + AnnotatedDependency dep = AnnotatedDependency.newAnnotatedDependency(type, value, k); + if (dep == null) { + throw new RuntimeException(config + ", line " + + lineNumber + ", is malformed. Fail to construct the dependency."); + } + } + + } finally { + in.close(); + } + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/Klass.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/Klass.java new file mode 100644 index 0000000000000000000000000000000000000000..a4d2eb277755dc4cc80170af102f7dcfbe6a1dc6 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/Klass.java @@ -0,0 +1,357 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.classanalyzer; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.sun.tools.classfile.AccessFlags; + +/** + * + * @author Mandy Chung + */ +public class Klass implements Comparable { + private final String classname; + private final String packagename; + private Module module; + private boolean isJavaLangObject; + private String[] paths; + private Map> methods; + private AccessFlags accessFlags; + private long filesize; + + private SortedMap> deps; + private SortedMap> referrers; + private List annotatedDeps; + private Set classForNameRefs; + + private Klass(String classname) { + this.classname = classname; + this.paths = classname.replace('.', '/').split("/"); + this.isJavaLangObject = classname.equals("java.lang.Object"); + this.deps = new TreeMap>(); + this.referrers = new TreeMap>(); + this.methods = new HashMap>(); + this.annotatedDeps = new ArrayList(); + this.classForNameRefs = new TreeSet(); + + int pos = classname.lastIndexOf('.'); + this.packagename = (pos > 0) ? classname.substring(0, pos) : ""; + } + + String getBasename() { + return paths[paths.length - 1]; + } + + String getClassName() { + return classname; + } + + String getPackageName() { + return packagename; + } + + String getClassFilePathname() { + StringBuilder sb = new StringBuilder(paths[0]); + for (int i = 1; i < paths.length; i++) { + String p = paths[i]; + sb.append(File.separator).append(p); + } + return sb.append(".class").toString(); + } + + boolean isPublic() { + return accessFlags == null || accessFlags.is(AccessFlags.ACC_PUBLIC); + } + + Module getModule() { + return module; + } + + void setModule(Module m) { + if (module != null) { + throw new RuntimeException("Module for " + this + " already set"); + } + this.module = m; + } + + Set getReferencedClasses() { + return deps.keySet(); + } + + Set getReferencingClasses() { + return referrers.keySet(); + } + + void setAccessFlags(int flags) { + this.accessFlags = new AccessFlags(flags); + } + + void setFileSize(long size) { + this.filesize = size; + } + + long getFileSize() { + return this.filesize; + } + + boolean exists() { + return filesize > 0; + } + + boolean skip(Klass k) { + // skip if either class is a root or same class + return k.isJavaLangObject || this == k || k.classname.equals(classname); + } + + void addDep(Method callee, ResolutionInfo resInfo) { + addDep(callee.getKlass(), resInfo); + } + + void addDep(Klass ref, ResolutionInfo ri) { + if (skip(ref)) { + return; + } + Set resInfos; + if (!deps.containsKey(ref)) { + resInfos = new TreeSet(); + deps.put(ref, resInfos); + } else { + resInfos = deps.get(ref); + } + resInfos.add(ri); + } + + void addReferrer(Method caller, ResolutionInfo resInfo) { + addReferrer(caller.getKlass(), resInfo); + } + + void addReferrer(Klass k, ResolutionInfo ri) { + if (skip(k)) { + return; + } + Set resInfos; + if (!referrers.containsKey(k)) { + resInfos = new TreeSet(); + referrers.put(k, resInfos); + } else { + resInfos = referrers.get(k); + } + resInfos.add(ri); + } + + Method getMethod(String name) { + return getMethod(name, ""); + } + + Method getMethod(String name, String signature) { + Set set; + if (methods.containsKey(name)) { + set = methods.get(name); + } else { + set = new TreeSet(); + methods.put(name, set); + } + + for (Method m : set) { + if (m.getName().equals(name) && m.getSignature().equals(signature)) { + return m; + } + } + Method m = new Method(this, name, signature); + set.add(m); + return m; + } + + @Override + public String toString() { + return classname; + } + + @Override + public int compareTo(Klass o) { + return classname.compareTo(o.classname); + } + + void addAnnotatedDep(AnnotatedDependency dep) { + annotatedDeps.add(dep); + } + + void addClassForNameReference(String method) { + classForNameRefs.add(method); + } + + List getAnnotatedDeps() { + return annotatedDeps; + } + + private static Map classes = new TreeMap(); + static Set getAllClasses() { + return new TreeSet(classes.values()); + } + + static Klass findKlassFromPathname(String filename) { + String name = filename; + if (filename.endsWith(".class")) { + name = filename.substring(0, filename.length() - 6); + } + + // trim ".class" + name = name.replace('/', '.'); + for (Klass k : classes.values()) { + if (name.endsWith(k.getClassName())) { + return k; + } + } + return null; + } + + static Klass findKlass(String classname) { + return classes.get(classname); + } + + static Klass getKlass(String name) { + Klass k; + String classname = name.replace('/', '.'); + if (classname.charAt(classname.length() - 1) == ';') { + classname = classname.substring(0, classname.length() - 1); + } + if (classes.containsKey(classname)) { + k = classes.get(classname); + } else { + k = new Klass(classname); + classes.put(classname, k); + } + return k; + } + + public class Method implements Comparable { + + private final Klass k; + private final String method; + private final String signature; + private long codeLength; + // non-primitive types only + private final List argTypes; + private final Klass returnType; + boolean isAbstract = false; + boolean marked = false; + + public Method(Klass k, String method, String signature) { + this(k, method, signature, null, null); + } + + public Method(Klass k, String method, String signature, Klass returnType, List argTypes) { + this.k = k; + this.method = method; + this.signature = signature; + this.argTypes = argTypes; + this.returnType = returnType; + this.codeLength = 0; + } + + public Klass getKlass() { + return k; + } + + public String getName() { + return method; + } + + public String getSignature() { + return signature; + } + + public Klass getReturnType() { + return returnType; + } + + public List argTypes() { + return argTypes; + } + + public void setCodeLength(long len) { + this.codeLength = len; + } + + public long getCodeLength() { + return codeLength; + } + + @Override + public boolean equals(Object o) { + if (o instanceof Method) { + return compareTo((Method) o) == 0; + } else { + return false; + } + } + + @Override + public int hashCode() { + int hash = 3; + hash = 71 * hash + (this.k != null ? this.k.hashCode() : 0); + hash = 71 * hash + (this.method != null ? this.method.hashCode() : 0); + return hash; + } + + @Override + public String toString() { + if (signature.isEmpty()) { + return k.classname + "." + method; + } else { + return signature; + } + } + + public String toHtmlString() { + return toString().replace("<", "<").replace(">", ">"); + } + + boolean isClinit() { + return method.equals(""); + } + + public int compareTo(Method m) { + if (k == m.getKlass()) { + if (method.equals(m.method)) { + return signature.compareTo(m.signature); + } else { + return method.compareTo(m.method); + } + } else { + return k.compareTo(m.getKlass()); + } + } + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/Module.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/Module.java new file mode 100644 index 0000000000000000000000000000000000000000..26af227763725c688da8f85ab646a3c67f5bc8ec --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/Module.java @@ -0,0 +1,693 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ +package com.sun.classanalyzer; + +import com.sun.classanalyzer.AnnotatedDependency.OptionalDependency; +import java.io.IOException; +import java.io.PrintWriter; +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.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * + * @author Mandy Chung + */ +public class Module implements Comparable { + + private static Map modules = new LinkedHashMap(); + + 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); + modules.put(name, m); + return m; + } + + public static Module findModule(String name) { + return modules.get(name); + } + + static Collection getAllModules() { + return Collections.unmodifiableCollection(modules.values()); + } + private final String name; + private final ModuleConfig config; + private final Set classes; + private final Set resources; + private final Set unresolved; + private final Set dependents; + private final Map packages; + private final Set members; + private Module group; + private boolean isBaseModule; + + private Module(ModuleConfig config) { + this.name = config.module; + this.isBaseModule = config.isBase; + this.classes = new TreeSet(); + this.resources = new TreeSet(); + this.config = config; + this.unresolved = new HashSet(); + this.dependents = new TreeSet(); + this.packages = new TreeMap(); + this.members = new TreeSet(); + this.group = this; // initialize to itself + } + + String name() { + return name; + } + + Module group() { + return group; + } + + boolean isBase() { + return isBaseModule; + } + + Set members() { + return members; + } + + boolean contains(Klass k) { + return k != null && classes.contains(k); + } + + boolean isEmpty() { + return classes.isEmpty() && resources.isEmpty(); + } + + /** + * Returns an Iterable of Dependency, only one for each dependent + * module of the strongest dependency (i.e. + * hard static > hard dynamic > optional static > optional dynamic + */ + Iterable dependents() { + Map deps = new LinkedHashMap(); + for (Dependency dep : dependents) { + Dependency d = deps.get(dep.module); + if (d == null || dep.compareTo(d) > 0) { + deps.put(dep.module, dep); + } + } + return deps.values(); + } + + @Override + public int compareTo(Module o) { + if (o == null) { + return -1; + } + return name.compareTo(o.name); + } + + @Override + public String toString() { + return name; + } + + void addKlass(Klass k) { + classes.add(k); + k.setModule(this); + + // update package statistics + String pkg = k.getPackageName(); + PackageInfo pkginfo = packages.get(pkg); + if (pkginfo == null) { + pkginfo = new PackageInfo(pkg); + packages.put(pkg, pkginfo); + } + if (k.exists()) { + // only count the class that is parsed + pkginfo.add(k.getFileSize()); + } + } + + void addResource(ResourceFile res) { + resources.add(res); + res.setModule(this); + } + + void processRootsAndReferences() { + // start with the root set + Deque pending = new ArrayDeque(); + for (Klass k : Klass.getAllClasses()) { + if (k.getModule() != null) { + continue; + } + String classname = k.getClassName(); + if (config.matchesRoot(classname) && !config.isExcluded(classname)) { + addKlass(k); + pending.add(k); + } + } + + // follow all references + Klass k; + while ((k = pending.poll()) != null) { + if (!classes.contains(k)) { + addKlass(k); + } + for (Klass other : k.getReferencedClasses()) { + Module otherModule = other.getModule(); + if (otherModule != null && otherModule != this) { + // this module is dependent on otherModule + addDependency(k, other); + continue; + } + + if (!classes.contains(other)) { + if (config.isExcluded(other.getClassName())) { + // reference to an excluded class + unresolved.add(new Reference(k, other)); + } else { + pending.add(other); + } + } + } + } + + // add other matching classes that don't require dependency analysis + for (Klass c : Klass.getAllClasses()) { + if (c.getModule() == null) { + String classname = c.getClassName(); + if (config.matchesIncludes(classname) && !config.isExcluded(classname)) { + addKlass(c); + // dependencies + for (Klass other : c.getReferencedClasses()) { + Module otherModule = other.getModule(); + if (otherModule == null) { + unresolved.add(new Reference(c, other)); + } else { + if (otherModule != this) { + // this module is dependent on otherModule + addDependency(c, other); + } + } + } + } + } + } + + + // add other matching classes that don't require dependency analysis + for (ResourceFile res : ResourceFile.getAllResources()) { + if (res.getModule() == null) { + String name = res.getName(); + if (config.matchesIncludes(name) && !config.isExcluded(name)) { + addResource(res); + } + } + } + } + + void addDependency(Klass from, Klass to) { + Dependency dep = new Dependency(from, to); + dependents.add(dep); + } + + void fixupDependencies() { + // update dependencies for classes that were allocated to modules after + // this module was processed. + for (Reference ref : unresolved) { + Module m = ref.referree().getModule(); + if (m == null || m != this) { + addDependency(ref.referrer, ref.referree); + } + } + + fixupAnnotatedDependencies(); + } + + private void fixupAnnotatedDependencies() { + // add dependencies that this klass may depend on due to the AnnotatedDependency + dependents.addAll(AnnotatedDependency.getDependencies(this)); + } + + boolean isModuleDependence(Klass k) { + Module m = k.getModule(); + return m == null || (!classes.contains(k) && !m.isBase()); + } + + Module getModuleDependence(Klass k) { + if (isModuleDependence(k)) { + Module m = k.getModule(); + if (group == this && m != null) { + // top-level module + return m.group; + } else { + return m; + } + } + return null; + } + +

void visit(Set visited, Visitor

visitor, P p) { + if (!visited.contains(this)) { + visited.add(this); + visitor.preVisit(this, p); + for (Module m : members) { + m.visit(visited, visitor, p); + visitor.postVisit(this, m, p); + } + } else { + throw new RuntimeException("Cycle detected: module " + this.name); + } + } + + void addMember(Module m) { + // merge class list + for (Klass k : m.classes) { + classes.add(k); + } + + // merge resource list + for (ResourceFile res : m.resources) { + resources.add(res); + } + + // merge the package statistics + for (PackageInfo pinfo : m.getPackageInfos()) { + String packageName = pinfo.pkgName; + PackageInfo pkginfo = packages.get(packageName); + if (pkginfo == null) { + pkginfo = new PackageInfo(packageName); + packages.put(packageName, pkginfo); + } + pkginfo.add(pinfo); + } + } + + 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); + } + } + + // set up the top-level module + Visitor groupSetter = new Visitor() { + + public void preVisit(Module m, Module p) { + m.group = p; + if (p.isBaseModule) { + // all members are also base + m.isBaseModule = true; + } + } + + public void postVisit(Module m, Module child, Module p) { + // nop - breadth-first search + } + }; + + // propagate the top-level module to all its members + for (Module p : modules.values()) { + for (Module m : p.members) { + if (m.group == m) { + m.visit(new TreeSet(), groupSetter, p); + } + } + } + + Visitor mergeClassList = new Visitor() { + + public void preVisit(Module m, Module p) { + // nop - depth-first search + } + + public void postVisit(Module m, Module child, Module p) { + m.addMember(child); + } + }; + + Set visited = new TreeSet(); + for (Module m : modules.values()) { + if (m.group() == m) { + if (m.members().size() > 0) { + // merge class list from all its members + m.visit(visited, mergeClassList, m); + } + + // clear the dependencies before fixup + m.dependents.clear(); + + // fixup dependencies + for (Klass k : m.classes) { + for (Klass other : k.getReferencedClasses()) { + if (m.isModuleDependence(other)) { + // this module is dependent on otherModule + m.addDependency(k, other); + } + } + } + + // add dependencies that this klass may depend on due to the AnnotatedDependency + m.fixupAnnotatedDependencies(); + } + } + } + + class PackageInfo implements Comparable { + + final String pkgName; + int count; + long filesize; + + PackageInfo(String name) { + 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 compareTo(Object o) { + return pkgName.compareTo(((PackageInfo) o).pkgName); + } + } + + Set getPackageInfos() { + return new TreeSet(packages.values()); + } + + void printSummaryTo(String output) throws IOException { + PrintWriter writer = new PrintWriter(output); + try { + long total = 0L; + int count = 0; + writer.format("%10s\t%10s\t%s\n", "Bytes", "Classes", "Package name"); + for (String pkg : packages.keySet()) { + PackageInfo info = packages.get(pkg); + if (info.count > 0) { + writer.format("%10d\t%10d\t%s\n", info.filesize, info.count, pkg); + total += info.filesize; + count += info.count; + } + } + + writer.format("\nTotal: %d bytes (uncompressed) %d classes\n", total, count); + } finally { + writer.close(); + } + + } + + void printClassListTo(String output) throws IOException { + // no file created if the module doesn't have any class + if (classes.isEmpty()) { + return; + } + + PrintWriter writer = new PrintWriter(output); + try { + for (Klass c : classes) { + if (c.exists()) { + writer.format("%s\n", c.getClassFilePathname()); + } else { + trace("%s in module %s missing\n", c, this); + } + } + + } finally { + writer.close(); + } + } + + void printResourceListTo(String output) throws IOException { + // no file created if the module doesn't have any resource file + if (resources.isEmpty()) { + return; + } + + PrintWriter writer = new PrintWriter(output); + try { + for (ResourceFile res : resources) { + writer.format("%s\n", res.getPathname()); + } + } finally { + writer.close(); + } + } + + void printDependenciesTo(String output, boolean showDynamic) throws IOException { + // no file created if the module doesn't have any class + if (classes.isEmpty()) { + return; + } + + PrintWriter writer = new PrintWriter(output); + try { + // classes that this klass may depend on due to the AnnotatedDependency + Map> annotatedDeps = AnnotatedDependency.getReferences(this); + + for (Klass klass : classes) { + Set references = klass.getReferencedClasses(); + for (Klass other : references) { + String classname = klass.getClassName(); + boolean optional = OptionalDependency.isOptional(klass, other); + if (optional) { + classname = "[optional] " + classname; + } + + Module m = getModuleDependence(other); + if (m != null || other.getModule() == null) { + writer.format("%-40s -> %s (%s)", classname, other, m); + Reference ref = new Reference(klass, other); + if (annotatedDeps.containsKey(ref)) { + for (AnnotatedDependency ad : annotatedDeps.get(ref)) { + writer.format(" %s", ad.getTag()); + } + // printed; so remove the dependency from the annotated deps list + annotatedDeps.remove(ref); + } + writer.format("\n"); + } + } + } + + + // print remaining dependencies specified in AnnotatedDependency list + if (annotatedDeps.size() > 0) { + for (Map.Entry> entry : annotatedDeps.entrySet()) { + Reference ref = entry.getKey(); + Module m = getModuleDependence(ref.referree); + if (m != null || ref.referree.getModule() == null) { + String classname = ref.referrer.getClassName(); + boolean optional = true; + boolean dynamic = true; + String tag = ""; + for (AnnotatedDependency ad : entry.getValue()) { + if (optional && !ad.isOptional()) { + optional = false; + tag = ad.getTag(); + } + if (!ad.isDynamic()) { + dynamic = false; + } + } + if (!showDynamic && optional && dynamic) { + continue; + } + if (optional) { + if (dynamic) { + classname = "[dynamic] " + classname; + } else { + classname = "[optional] " + classname; + } + } + writer.format("%-40s -> %s (%s) %s%n", classname, ref.referree, m, tag); + } + } + } + + } finally { + writer.close(); + } + } + + static class Dependency implements Comparable { + + final Module module; + final boolean optional; + final boolean dynamic; + + Dependency(Klass from, Klass to) { + // static dependency + this.module = to.getModule() != null ? to.getModule().group() : null; + this.optional = OptionalDependency.isOptional(from, to); + this.dynamic = false; + } + + Dependency(Module m, boolean optional, boolean dynamic) { + this.module = m != null ? m.group() : null; + this.optional = optional; + this.dynamic = dynamic; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Dependency)) { + return false; + } + if (this == obj) { + return true; + } + + Dependency d = (Dependency) obj; + if (this.module != d.module) { + return false; + } else { + return this.optional == d.optional && this.dynamic == d.dynamic; + } + } + + @Override + public int hashCode() { + int hash = 3; + hash = 19 * hash + (this.module != null ? this.module.hashCode() : 0); + hash = 19 * hash + (this.optional ? 1 : 0); + hash = 19 * hash + (this.dynamic ? 1 : 0); + return hash; + } + + @Override + public int compareTo(Dependency d) { + if (this.equals(d)) { + return 0; + } + + // Hard static > hard dynamic > optional static > optional dynamic + if (this.module == d.module) { + if (this.optional == d.optional) { + return this.dynamic ? -1 : 1; + } else { + return this.optional ? -1 : 1; + } + } else if (this.module != null && d.module != null) { + return (this.module.compareTo(d.module)); + } else { + return (this.module == null) ? -1 : 1; + } + } + + @Override + public String toString() { + String s = module.name(); + if (dynamic && optional) { + s += " (dynamic)"; + } else if (optional) { + s += " (optional)"; + } + return s; + } + } + + static class Reference implements Comparable { + + private final Klass referrer, referree; + + Reference(Klass referrer, Klass referree) { + this.referrer = referrer; + this.referree = referree; + } + + Klass referrer() { + return referrer; + } + + Klass referree() { + return referree; + } + + @Override + public int hashCode() { + return referrer.hashCode() ^ referree.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Reference)) { + return false; + } + if (this == obj) { + return true; + } + + Reference r = (Reference) obj; + return (this.referrer.equals(r.referrer) && + this.referree.equals(r.referree)); + } + + @Override + public int compareTo(Reference r) { + int ret = referrer.compareTo(r.referrer); + if (ret == 0) { + ret = referree.compareTo(r.referree); + } + return ret; + } + } + + interface Visitor

{ + + public void preVisit(Module m, P param); + + public void postVisit(Module m, Module child, P param); + } + private static boolean traceOn = System.getProperty("classanalyzer.debug") != null; + + private static void trace(String format, Object... params) { + System.err.format(format, params); + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ModuleConfig.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ModuleConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..d5ead840e01b5eea3e03a35328b65f870e5ddb69 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ModuleConfig.java @@ -0,0 +1,562 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.classanalyzer; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.regex.Pattern; + +/** + * + * @author Mandy Chung + */ +public class ModuleConfig { + + private static String baseModuleName = "base"; + private final Set roots; + private final Set includes; + private final Filter filter; + private List members; + final String module; + final boolean isBase; + + private ModuleConfig(String name) throws IOException { + this.roots = new TreeSet(); + this.includes = new TreeSet(); + this.module = name; + this.isBase = name.equals(baseModuleName); + this.filter = new Filter(this); + } + + List members() { + if (members == null) { + members = new LinkedList(); + + for (String s : includes) { + if (!s.contains("*") && Module.findModule(s) != null) { + // module member + members.add(s); + } + } + } + return members; + } + + boolean matchesRoot(String name) { + for (String pattern : roots) { + if (matches(name, pattern)) { + return true; + } + } + return false; + } + + boolean matchesIncludes(String name) { + for (String pattern : includes) { + if (matches(name, pattern)) { + return true; + } + } + return false; + } + + boolean isExcluded(String name) { + return filter.isExcluded(name); + } + + boolean matchesPackage(String packageName, String pattern) { + int pos = pattern.lastIndexOf('.'); + String pkg = pos > 0 ? pattern.substring(0, pos) : ""; + return packageName.equals(pkg); + } + + + boolean matches(String name, String pattern) { + if (pattern.contains("**") && !pattern.endsWith("**")) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + String javaName = name; + + boolean isResourceFile = name.indexOf('/') >= 0; + if (isResourceFile) { + // it's a resource file; convert the name as a java + javaName = name.replace('/', '.'); + } + if (pattern.indexOf('/') < 0) { + // if the pattern doesn't contain '/ + return matchesJavaName(javaName, pattern); + } else { + if (isResourceFile) { + // the pattern is for matching resource file + return matchesNameWithSlash(name, pattern); + } else { + return false; + } + } + } + + boolean matchesJavaName(String name, String pattern) { + int pos = name.lastIndexOf('.'); + String packageName = pos > 0 ? name.substring(0, pos) : ""; + if (pattern.endsWith("**")) { + String p = pattern.substring(0, pattern.length() - 2); + return name.startsWith(p); + } else if (pattern.endsWith("*") && pattern.indexOf('*') == pattern.lastIndexOf('*')) { + if (matchesPackage(packageName, pattern)) { + // package name has to be exact match + String p = pattern.substring(0, pattern.length() - 1); + return name.startsWith(p); + } else { + return false; + } + } else if (pattern.contains("*")) { + String basename = pos > 0 ? name.substring(pos + 1, name.length()) : name; + pos = pattern.indexOf('*'); + String prefix = pattern.substring(0, pos); + String suffix = pattern.substring(pos + 1, pattern.length()); + if (name.startsWith(prefix) && matchesPackage(packageName, prefix)) { + // package name has to be exact match + if (suffix.contains("*")) { + return name.matches(convertToRegex(pattern)); + } else { + return basename.endsWith(suffix); + } + } else { + // we don't support wildcard be used in the package name + return false; + } + } else { + // exact match or inner class + return name.equals(pattern) || name.startsWith(pattern + "$"); + } + } + + boolean matchesNameWithSlash(String name, String pattern) { + if (pattern.endsWith("**")) { + String p = pattern.substring(0, pattern.length() - 2); + return name.startsWith(p); + } else if (pattern.contains("*")) { + 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; + } + + if (pattern.indexOf('*') == pattern.lastIndexOf('*')) { + // exact match prefix with no '/' in the tail string + String wildcard = tail.substring(0, tail.length() - suffix.length()); + return tail.indexOf('/') < 0 && tail.endsWith(suffix); + } + + if (suffix.contains("*")) { + return matchesNameWithSlash(tail, suffix); + } else { + // tail ends with the suffix while no '/' in the wildcard matched string + String any = tail.substring(0, tail.length() - suffix.length()); + return tail.endsWith(suffix) && any.indexOf('/') < 0; + } + } else { + // exact match + return name.equals(pattern); + } + } + + private String convertToRegex(String pattern) { + StringBuilder sb = new StringBuilder(); + int i = 0; + int index = 0; + int plen = pattern.length(); + while (i < plen) { + char p = pattern.charAt(i); + if (p == '*') { + sb.append("(").append(pattern.substring(index, i)).append(")"); + if (i + 1 < plen && pattern.charAt(i + 1) == '*') { + sb.append(".*"); + index = i + 2; + } else { + sb.append("[^\\.]*"); + index = i + 1; + } + } + i++; + } + if (index < plen) { + sb.append("(").append(pattern.substring(index, plen)).append(")"); + } + return sb.toString(); + } + + static class Filter { + + final ModuleConfig config; + final Set exclude = new TreeSet(); + final Set allow = new TreeSet(); + + Filter(ModuleConfig config) { + this.config = config; + } + + Filter exclude(String pattern) { + exclude.add(pattern); + return this; + } + + Filter allow(String pattern) { + allow.add(pattern); + return this; + } + + String allowedBy(String name) { + String allowedBy = null; + for (String pattern : allow) { + if (config.matches(name, pattern)) { + if (name.equals(pattern)) { + return pattern; // exact match + } + if (allowedBy == null) { + allowedBy = pattern; + } else { + if (pattern.length() > allowedBy.length()) { + allowedBy = pattern; + } + } + } + } + return allowedBy; + } + + String excludedBy(String name) { + String allowedBy = allowedBy(name); + String excludedBy = null; + + if (allowedBy != null && name.equals(allowedBy)) { + return null; // exact match + } + for (String pattern : exclude) { + if (config.matches(name, pattern)) { + // not matched by allowed rule or exact match + if (allowedBy == null || name.equals(pattern)) { + return pattern; + } + if (excludedBy == null) { + excludedBy = pattern; + } else { + if (pattern.length() > excludedBy.length()) { + excludedBy = pattern; + } + } + } + } + return excludedBy; + } + + boolean isExcluded(String name) { + String allowedBy = allowedBy(name); + String excludedBy = excludedBy(name); + + if (excludedBy == null) { + return false; + } + // not matched by allowed rule or exact match + if (allowedBy == null || name.equals(excludedBy)) { + return true; + } + + if (allowedBy == null) { + return true; + } + if (allowedBy != null && + excludedBy.length() > allowedBy.length()) { + return true; + } + return false; + } + } + + private static String trimComment(String line) { + StringBuilder sb = new StringBuilder(); + + int pos = 0; + while (pos >= 0 && pos < line.length()) { + int c1 = line.indexOf("//", pos); + if (c1 > 0 && !Character.isWhitespace(line.charAt(c1-1))) { + // not a comment + c1 = -1; + } + + int c2 = line.indexOf("/*", pos); + if (c2 > 0 && !Character.isWhitespace(line.charAt(c2-1))) { + // not a comment + c2 = -1; + } + + int c = line.length(); + int n = line.length(); + if (c1 >= 0 || c2 >= 0) { + if (c1 >= 0) { + c = c1; + } + if (c2 >= 0 && c2 < c) { + c = c2; + } + int c3 = line.indexOf("*/", c2 + 2); + if (c == c2 && c3 > c2) { + n = c3 + 2; + } + } + if (c > 0) { + if (sb.length() > 0) { + // add a whitespace if multiple comments on one line + sb.append(" "); + } + sb.append(line.substring(pos, c)); + } + pos = n; + } + return sb.toString(); + } + + private static boolean beginBlockComment(String line) { + int pos = 0; + while (pos >= 0 && pos < line.length()) { + int c = line.indexOf("/*", pos); + if (c < 0) { + return false; + } + + if (c > 0 && !Character.isWhitespace(line.charAt(c-1))) { + return false; + } + + int c1 = line.indexOf("//", pos); + if (c1 >= 0 && c1 < c) { + return false; + } + + int c2 = line.indexOf("*/", c + 2); + if (c2 < 0) { + return true; + } + pos = c + 2; + } + return false; + } + + static void setBaseModule(String name) { + baseModuleName = name; + } + // TODO: we shall remove "-" from the regex once we define + // the naming convention for the module names without dashes + static final Pattern classNamePattern = Pattern.compile("[\\w\\.\\*_$-/]+"); + + static List readConfigurationFile(String file) throws IOException { + List result = new ArrayList(); + // parse configuration file + FileInputStream in = new FileInputStream(file); + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line; + + int lineNumber = 0; + boolean inRoots = false; + boolean inIncludes = false; + boolean inAllows = false; + boolean inExcludes = false; + boolean inBlockComment = false; + ModuleConfig config = null; + + while ((line = reader.readLine()) != null) { + lineNumber++; + + if (inBlockComment) { + int c = line.indexOf("*/"); + if (c >= 0) { + line = line.substring(c + 2, line.length()); + inBlockComment = false; + } else { + // skip lines until end of comment block + continue; + } + } + + inBlockComment = beginBlockComment(line); + + line = trimComment(line).trim(); + // ignore empty lines + if (line.length() == 0) { + continue; + } + + String values; + if (inRoots || inIncludes || inExcludes || inAllows) { + values = line; + } else { + String[] s = line.split("\\s+"); + String keyword = s[0].trim(); + if (keyword.equals("module")) { + if (s.length != 3 || !s[2].trim().equals("{")) { + throw new RuntimeException(file + ", line " + + lineNumber + ", is malformed"); + } + config = new ModuleConfig(s[1].trim()); + result.add(config); + // switch to a new module; so reset the flags + inRoots = false; + inIncludes = false; + inExcludes = false; + inAllows = false; + continue; + } else if (keyword.equals("roots")) { + inRoots = true; + } else if (keyword.equals("include")) { + inIncludes = true; + } else if (keyword.equals("exclude")) { + inExcludes = true; + } else if (keyword.equals("allow")) { + inAllows = true; + } else if (keyword.equals("}")) { + if (config == null || s.length != 1) { + throw new RuntimeException(file + ", line " + + lineNumber + ", is malformed"); + } else { + // end of a module + config = null; + continue; + } + } else { + throw new RuntimeException(file + ", \"" + keyword + "\" on line " + + lineNumber + ", is not recognized"); + } + values = line.substring(keyword.length(), line.length()).trim(); + } + + if (config == null) { + throw new RuntimeException(file + ", module not specified"); + } + + int len = values.length(); + if (len == 0) { + continue; + } + char lastchar = values.charAt(len - 1); + if (lastchar != ',' && lastchar != ';') { + throw new RuntimeException(file + ", line " + + lineNumber + ", is malformed:" + + " ',' or ';' is missing."); + } + + values = values.substring(0, len - 1); + // parse the values specified for a keyword specified + for (String s : values.split(",")) { + s = s.trim(); + if (s.length() > 0) { + if (!classNamePattern.matcher(s).matches()) { + throw new RuntimeException(file + ", line " + + lineNumber + ", is malformed: \"" + s + "\""); + } + if (inRoots) { + config.roots.add(s); + } else if (inIncludes) { + config.includes.add(s); + } else if (inExcludes) { + config.filter.exclude(s); + } else if (inAllows) { + config.filter.allow(s); + } + + } + } + if (lastchar == ';') { + inRoots = false; + inIncludes = false; + inExcludes = false; + inAllows = false; + } + } + + if (inBlockComment) { + throw new RuntimeException(file + ", line " + + lineNumber + ", missing \"*/\" to end a block comment"); + } + if (config != null) { + throw new RuntimeException(file + ", line " + + lineNumber + ", missing \"}\" to end module definition" + + " for \"" + config.module + "\""); + } + + } finally { + in.close(); + } + + return result; + } + + private String format(String keyword, Collection values) { + if (values.size() == 0) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + String format = "%4s%-9s"; + String spaces = String.format(format, "", ""); + sb.append(String.format(format, "", keyword)); + int count = 0; + for (String s : values) { + if (count > 0) { + sb.append(",\n").append(spaces); + } else if (count++ > 0) { + sb.append(", "); + } + sb.append(s); + } + if (count > 0) { + sb.append(";\n"); + } + return sb.toString(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("module " + module).append(" {\n"); + sb.append(format("include", includes)); + sb.append(format("root", roots)); + sb.append(format("allow", filter.allow)); + sb.append(format("exclude", filter.exclude)); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ResolutionInfo.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ResolutionInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..19746a49648b415d064a745d31902e35ae873a8c --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ResolutionInfo.java @@ -0,0 +1,201 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.classanalyzer; + +import com.sun.classanalyzer.Klass.Method; + +/** + * + * @author mchung + */ +public class ResolutionInfo implements Comparable { + + enum Type { + + REFLECTION("reflection", true), + NATIVE("native", true), + INTERFACE("interface", false), + SUPER("super", false), + EXPLICIT("explicit", false), + VERIFICATION("verification", false), + METHODTRACE("method trace", true), + CONSTANT_POOL("constant pool", true), + CHECKED_EXCEPTION("throws", true), + METHOD("method", true), + FIELD("field", true), + EXTENDS("extends", true), + IMPLEMENTS("implements", true), + NOINFO("No info", false); + + private final String name; + private final boolean hasInfo; + + private Type(String name, boolean hasInfo) { + this.name = name; + this.hasInfo = hasInfo; + } + + public String getName() { + return name; + } + + public boolean hasInfo() { + return hasInfo; + } + + public static Type getType(String s) { + if (s.isEmpty()) { + return NOINFO; + } + for (Type t : values()) { + if (s.equals(t.name)) { + return t; + } + } + // Need to fix the VM output to add "native" + // throw new IllegalArgumentException("Invalid ResolutionInfo.type \"" + s + "\""); + System.out.println("WARNING: Invalid ResolutionInfo.type \"" + s + "\""); + return null; + } + } + final Klass fromClass; + final Method method; + final Klass toClass; + final int linenumber; + final Type type; + final String info; + private boolean isPublic = false; + + private ResolutionInfo(Klass from, Klass to, int linenumber, Type type, String info) { + this.fromClass = from; + this.method = null; + this.toClass = to; + this.linenumber = linenumber; + this.type = type; + this.info = info; + } + + private ResolutionInfo(Klass from, Method m, Klass to, int linenumber, Type type) { + this.fromClass = from; + this.method = m; + this.toClass = to; + this.linenumber = linenumber; + this.type = type; + this.info = m.toString(); + } + + public boolean isPublic() { + return isPublic; + } + + public void setPublicAccess(boolean value) { + isPublic = value; + } + static ResolutionInfo resolved(Klass from, Klass to) { + return new ResolutionInfo(from, to, 0, Type.NOINFO, ""); + } + + static ResolutionInfo resolved(Klass from, Klass to, int linenumber) { + return new ResolutionInfo(from, to, linenumber, Type.NOINFO, ""); + } + + static ResolutionInfo resolved(Klass from, Klass to, int linenumber, String reason) { + String[] ss = reason.split("\\s+"); + Type type; + String info; + if (linenumber == -1) { + type = Type.NATIVE; + info = ss[0]; // native method name + } else { + info = ss.length == 2 ? ss[1] : ""; + type = Type.getType(ss[0]); + if (type == null) { + if (reason.isEmpty()) { + throw new IllegalArgumentException("Invalid type: " + reason + " (" + ss[0] + ")" + ss.length); + } + // assume it's native + type = Type.NATIVE; + info = reason.isEmpty() ? ss[0] : reason; + } + } + + return new ResolutionInfo(from, to, linenumber, type, info); + } + + static ResolutionInfo resolved(Klass from, Klass to, Method callee) { + return new ResolutionInfo(from, callee, to, 0, Type.METHODTRACE); + } + + static ResolutionInfo resolvedConstantPool(Klass from, Klass to, int index) { + return new ResolutionInfo(from, to, 0, Type.CONSTANT_POOL, "#" + index); + } + + static ResolutionInfo resolvedField(Klass from, Klass to, String fieldname) { + return new ResolutionInfo(from, to, 0, Type.FIELD, fieldname); + } + + static ResolutionInfo resolvedMethodSignature(Klass from, Klass to, Method m) { + return new ResolutionInfo(from, m, to, 0, Type.METHOD); + } + + static ResolutionInfo resolvedCheckedException(Klass from, Klass to, Method m) { + return new ResolutionInfo(from, m, to, 0, Type.CHECKED_EXCEPTION); + } + + static ResolutionInfo resolvedExtends(Klass from, Klass to) { + String info = from.getClassName() + " implements " + to.getClassName(); + return new ResolutionInfo(from, to, 0, Type.EXTENDS, info); + } + + static ResolutionInfo resolvedImplements(Klass from, Klass to) { + String info = from.getClassName() + " implements " + to.getClassName(); + return new ResolutionInfo(from, to, 0, Type.IMPLEMENTS, info); + } + + @Override + public int compareTo(ResolutionInfo ri) { + if (this.fromClass == ri.fromClass && + this.toClass == ri.toClass && + this.linenumber == ri.linenumber && + this.type == ri.type && + this.info.equals(ri.info)) { + return 0; + } else if (this.fromClass == ri.fromClass) { + if (this.linenumber > ri.linenumber) { + return 1; + } else if (this.linenumber < ri.linenumber) { + return -1; + } else if (this.type != ri.type) { + return this.type.getName().compareTo(ri.type.getName()); + } else if (this.toClass != ri.toClass) { + return this.toClass.compareTo(ri.toClass); + } else { + return this.info.compareTo(ri.info); + } + } else { + return this.fromClass.compareTo(ri.fromClass); + } + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ResourceFile.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ResourceFile.java new file mode 100644 index 0000000000000000000000000000000000000000..8c6714085a63f9269fe45ba8e0b9030c7377888e --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ResourceFile.java @@ -0,0 +1,186 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ +package com.sun.classanalyzer; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +/** + * + * @author Mandy Chung + */ +public class ResourceFile implements Comparable { + + private final String pathname; + private Module module; + + ResourceFile(String pathname) { + this.pathname = pathname.replace(File.separatorChar, '/'); + } + + Module getModule() { + return module; + } + + void setModule(Module m) { + if (module != null) { + throw new RuntimeException("Module for " + this + " already set"); + } + this.module = m; + } + + String getName() { + return pathname; + } + + String getPathname() { + return pathname; + } + + @Override + public String toString() { + return pathname; + } + + @Override + public int compareTo(ResourceFile o) { + return pathname.compareTo(o.pathname); + } + static Set resources = new TreeSet(); + + static boolean isResource(String pathname) { + String name = pathname.replace(File.separatorChar, '/'); + + if (name.endsWith("META-INF/MANIFEST.MF")) { + return false; + } + if (name.contains("META-INF/JCE_RSA.")) { + return false; + } + + return true; + } + + static void addResource(String name, InputStream in) { + ResourceFile res; + name = name.replace(File.separatorChar, '/'); + if (name.startsWith("META-INF/services")) { + res = new ServiceProviderConfigFile(name, in); + } else { + res = new ResourceFile(name); + } + resources.add(res); + } + + static Set getAllResources() { + return Collections.unmodifiableSet(resources); + } + + static class ServiceProviderConfigFile extends ResourceFile { + + private final List providers = new ArrayList(); + private final String service; + ServiceProviderConfigFile(String pathname, InputStream in) { + super(pathname); + readServiceConfiguration(in, providers); + this.service = pathname.substring("META-INF/services".length() + 1, pathname.length()); + } + + @Override + String getName() { + if (providers.isEmpty()) { + return service; + } else { + // just use the first one for matching + return providers.get(0); + } + } + + @SuppressWarnings("empty-statement") + void readServiceConfiguration(InputStream in, List names) { + BufferedReader br = null; + try { + if (in != null) { + // Properties doesn't perserve the order of the input file + br = new BufferedReader(new InputStreamReader(in, "utf-8")); + int lc = 1; + while ((lc = parseLine(br, lc, names)) >= 0); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } + } + + // Parse a single line from the given configuration file, adding the name + // on the line to the names list. + // + private int parseLine(BufferedReader r, int lc, List names) throws IOException { + String ln = r.readLine(); + if (ln == null) { + return -1; + } + int ci = ln.indexOf('#'); + if (ci >= 0) { + ln = ln.substring(0, ci); + } + ln = ln.trim(); + int n = ln.length(); + if (n != 0) { + if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) { + throw new RuntimeException("Illegal configuration-file syntax"); + } + int cp = ln.codePointAt(0); + if (!Character.isJavaIdentifierStart(cp)) { + throw new RuntimeException("Illegal provider-class name: " + ln); + } + for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) { + cp = ln.codePointAt(i); + if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) { + throw new RuntimeException("Illegal provider-class name: " + ln); + } + } + if (!names.contains(ln)) { + names.add(ln); + } + } + return lc + 1; + } + } +} diff --git a/jdk/make/modules/tools/src/com/sun/classanalyzer/ShowDeps.java b/jdk/make/modules/tools/src/com/sun/classanalyzer/ShowDeps.java new file mode 100644 index 0000000000000000000000000000000000000000..ce585553ba6941f23d827dcdaf87a1b46da7ea02 --- /dev/null +++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ShowDeps.java @@ -0,0 +1,100 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.classanalyzer; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * A simple tool to print out the static dependencies for a given set of JAR, + * class files, or combinations of. The tools supports an -ignore option to + * ignore references to classes listed in the file (including .classlists + * created by the ClassAnalyzer tool). + */ + +public class ShowDeps { + + static void usage() { + System.out.println("java ShowDeps [-ignore ] file..."); + System.out.println(" where is a class or JAR file, or a directory"); + System.out.println(); + System.out.println("Example usages:"); + System.out.println(" java ShowDeps Foo.jar"); + System.out.println(" java ShowDeps -ignore base.classlist Foo.jar"); + System.out.println(" java ShowDeps -ignore base.classlist -ignore " + + "jaxp-parsers.classlist

"); + System.exit(-1); + } + + public static void main(String[] args) throws IOException { + // process -ignore options + int argi = 0; + Set ignore = new HashSet(); + while (argi < args.length && args[argi].equals("-ignore")) { + argi++; + Scanner s = new Scanner(new File(args[argi++])); + try { + while (s.hasNextLine()) { + String line = s.nextLine(); + if (!line.endsWith(".class")) + continue; + int len = line.length(); + // convert to class names + String clazz = line.replace('\\', '.').replace('/', '.') + .substring(0, len-6); + ignore.add(clazz); + } + } finally { + s.close(); + } + } + + if (argi >= args.length) + usage(); + + // parse all classes + while (argi < args.length) + ClassPath.setClassPath(args[argi++]); + ClassPath.parseAllClassFiles(); + + // find the classes that don't exist + Set unresolved = new TreeSet(); + for (Klass k : Klass.getAllClasses()) { + if (k.getFileSize() == 0) + unresolved.add(k); + } + + // print references to classes that don't exist + for (Klass k: Klass.getAllClasses()) { + for (Klass other : k.getReferencedClasses()) { + if (unresolved.contains(other)) { + String name = other.toString(); + if (!ignore.contains(name)) { + System.out.format("%s -> %s\n", k, other); + } + } + } + } + } +} diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c index 2494ce1ea2e5a1d4e246d296d53c1e81c585933a..8f9d2edee1c53a6b3cafb027ad50996adec84976 100644 --- a/jdk/src/share/bin/java.c +++ b/jdk/src/share/bin/java.c @@ -93,6 +93,7 @@ static int numOptions, maxOptions; * Prototypes for functions internal to launcher. */ static void SetClassPath(const char *s); +static void SetModulesBootClassPath(const char *s); static void SelectVersion(int argc, char **argv, char **main_class); static jboolean ParseArguments(int *pargc, char ***pargv, char **pjarfile, char **pclassname, int *pret, const char *jvmpath); @@ -277,6 +278,9 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ return(ret); } + /* Set bootclasspath for modules */ + SetModulesBootClassPath(jrepath); + /* Override class path if -jar flag was specified */ if (jarfile != 0) { SetClassPath(jarfile); @@ -693,6 +697,44 @@ SetClassPath(const char *s) JLI_MemFree((char *) s); } +/* + * Set the bootclasspath for modules. + * A temporary workaround until jigsaw is integrated into JDK 7. + */ +static void +SetModulesBootClassPath(const char *jrepath) +{ + char *def, *s; + char pathname[MAXPATHLEN]; + const char separator[] = { FILE_SEPARATOR, '\0' }; + const char *orig = jrepath; + static const char format[] = "-Xbootclasspath/p:%s"; + struct stat statbuf; + + /* return if jre/lib/rt.jar exists */ + sprintf(pathname, "%s%slib%srt.jar", jrepath, separator, separator); + if (stat(pathname, &statbuf) == 0) { + return; + } + + /* return if jre/classes exists */ + sprintf(pathname, "%s%sclasses", jrepath, separator); + if (stat(pathname, &statbuf) == 0) { + return; + } + + /* modularized jre */ + sprintf(pathname, "%s%slib%s*", jrepath, separator, separator); + s = (char *) JLI_WildcardExpandClasspath(pathname); + def = JLI_MemAlloc(sizeof(format) + - 2 /* strlen("%s") */ + + JLI_StrLen(s)); + sprintf(def, format, s); + AddOption(def, NULL); + if (s != orig) + JLI_MemFree((char *) s); +} + /* * The SelectVersion() routine ensures that an appropriate version of * the JRE is running. The specification for the appropriate version diff --git a/jdk/src/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java b/jdk/src/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java index 00cdf1ee6a74a921615fd08008d503f340ec98d4..b56aea82e42319d999f6c753291329bc7e6bec49 100644 --- a/jdk/src/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java +++ b/jdk/src/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java @@ -33,10 +33,10 @@ import java.lang.reflect.InvocationTargetException; import java.util.Hashtable; import java.util.Properties; import java.util.Enumeration; -import java.applet.Applet; import org.omg.CORBA.ORB; +import javax.naming.Context; import javax.naming.ConfigurationException; /** @@ -191,16 +191,48 @@ public class CorbaUtils { } // Get Applet from environment - Applet applet = null; if (env != null) { - applet = (Applet) env.get("java.naming.applet"); + Object applet = env.get(Context.APPLET); + if (applet != null) { + // Create ORBs for an applet + return initAppletORB(applet, orbProp); + } } - // Create ORBs using applet and orbProp - if (applet != null) { - return ORB.init(applet, orbProp); - } else { - return ORB.init(new String[0], orbProp); + // Create ORBs using orbProp for a standalone application + return ORB.init(new String[0], orbProp); + } + + /** + * This method returns a new ORB instance for the given applet + * without creating a static dependency on java.applet. + */ + private static ORB initAppletORB(Object applet, Properties orbProp) { + try { + Class appletClass = Class.forName("java.applet.Applet", true, null); + if (!appletClass.isInstance(applet)) { + throw new ClassCastException(applet.getClass().getName()); + } + + // invoke the static method ORB.init(applet, orbProp); + Method method = ORB.class.getMethod("init", appletClass, Properties.class); + return (ORB) method.invoke(null, applet, orbProp); + } catch (ClassNotFoundException e) { + // java.applet.Applet doesn't exist and the applet parameter is + // non-null; so throw CCE + throw new ClassCastException(applet.getClass().getName()); + } catch (NoSuchMethodException e) { + throw new AssertionError(e); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause instanceof Error) { + throw (Error) cause; + } + throw new AssertionError(e); + } catch (IllegalAccessException iae) { + throw new AssertionError(iae); } } diff --git a/jdk/src/share/classes/java/lang/StrictMath.java b/jdk/src/share/classes/java/lang/StrictMath.java index dad91405741c53b6d072f3ae4562e530ca608a8f..704be3e310ed7fc726421b3a3c06d42646734043 100644 --- a/jdk/src/share/classes/java/lang/StrictMath.java +++ b/jdk/src/share/classes/java/lang/StrictMath.java @@ -26,6 +26,7 @@ package java.lang; import java.util.Random; import sun.misc.FpUtils; +import sun.misc.DoubleConsts; /** * The class {@code StrictMath} contains methods for performing basic @@ -316,7 +317,9 @@ public final class StrictMath { * floating-point value that is greater than or equal to * the argument and is equal to a mathematical integer. */ - public static native double ceil(double a); + public static double ceil(double a) { + return floorOrCeil(a, -0.0, 1.0, 1.0); + } /** * Returns the largest (closest to positive infinity) @@ -333,7 +336,54 @@ public final class StrictMath { * floating-point value that less than or equal to the argument * and is equal to a mathematical integer. */ - public static native double floor(double a); + public static double floor(double a) { + return floorOrCeil(a, -1.0, 0.0, -1.0); + } + + /** + * Internal method to share logic between floor and ceil. + * + * @param a the value to be floored or ceiled + * @param negativeBoundary result for values in (-1, 0) + * @param positiveBoundary result for values in (0, 1) + * @param increment value to add when the argument is non-integral + */ + private static double floorOrCeil(double a, + double negativeBoundary, + double positiveBoundary, + double sign) { + int exponent = Math.getExponent(a); + + if (exponent < 0) { + /* + * Absolute value of argument is less than 1. + * floorOrceil(-0.0) => -0.0 + * floorOrceil(+0.0) => +0.0 + */ + return ((a == 0.0) ? a : + ( (a < 0.0) ? negativeBoundary : positiveBoundary) ); + } else if (exponent >= 52) { + /* + * Infinity, NaN, or a value so large it must be integral. + */ + return a; + } + // Else the argument is either an integral value already XOR it + // has to be rounded to one. + assert exponent >= 0 && exponent <= 51; + + long doppel = Double.doubleToRawLongBits(a); + long mask = DoubleConsts.SIGNIF_BIT_MASK >> exponent; + + if ( (mask & doppel) == 0L ) + return a; // integral value + else { + double result = Double.longBitsToDouble(doppel & (~mask)); + if (sign*a > 0.0) + result = result + sign; + return result; + } + } /** * Returns the {@code double} value that is closest in value diff --git a/jdk/src/share/classes/java/lang/management/PlatformManagedObject.java b/jdk/src/share/classes/java/lang/management/PlatformManagedObject.java index 5f68635d4fe8c57e76d04e7d9f2e7e75fd216c73..ca5edbeb51834de70cf68fe6123d2ef9c052c969 100644 --- a/jdk/src/share/classes/java/lang/management/PlatformManagedObject.java +++ b/jdk/src/share/classes/java/lang/management/PlatformManagedObject.java @@ -32,7 +32,7 @@ import javax.management.ObjectName; * for monitoring and managing a component in the Java platform. * Each platform managed object has a unique * object name - * for the {@linkplain ManagementFactory.getPlatformMBeanServer + * for the {@linkplain ManagementFactory#getPlatformMBeanServer * platform MBeanServer} access. * All platform MXBeans will implement this interface. * diff --git a/jdk/src/share/classes/java/nio/X-Buffer.java.template b/jdk/src/share/classes/java/nio/X-Buffer.java.template index 9fc8185b646ef0387d26889e548ba1bf99cab1f7..e3431a02dfec700e36a8f8b4ff585898a839cc7d 100644 --- a/jdk/src/share/classes/java/nio/X-Buffer.java.template +++ b/jdk/src/share/classes/java/nio/X-Buffer.java.template @@ -32,24 +32,24 @@ import java.io.IOException; #end[char] /** - * $A$ $fulltype$ buffer. + * $A$ $type$ buffer. * *

This class defines {#if[byte]?six:four} categories of operations upon - * $fulltype$ buffers: + * $type$ buffers: * *

    * *
  • Absolute and relative {@link #get() get} and * {@link #put($type$) put} methods that read and write - * single $fulltype$s;

  • + * single $type$s;

    * *
  • Relative {@link #get($type$[]) bulk get} - * methods that transfer contiguous sequences of $fulltype$s from this buffer + * methods that transfer contiguous sequences of $type$s from this buffer * into an array; {#if[!byte]?and}

  • * *
  • Relative {@link #put($type$[]) bulk put} - * methods that transfer contiguous sequences of $fulltype$s from $a$ - * $fulltype$ array{#if[char]?, a string,} or some other $fulltype$ + * methods that transfer contiguous sequences of $type$s from $a$ + * $type$ array{#if[char]?, a string,} or some other $type$ * buffer into this buffer;{#if[!byte]? and}

  • * #if[byte] @@ -67,22 +67,22 @@ import java.io.IOException; * *
  • Methods for {@link #compact compacting}, {@link * #duplicate duplicating}, and {@link #slice - * slicing} $a$ $fulltype$ buffer.

  • + * slicing} $a$ $type$ buffer.

    * *
* - *

$Fulltype$ buffers can be created either by {@link #allocate + *

$Type$ buffers can be created either by {@link #allocate * allocation}, which allocates space for the buffer's * #if[byte] * * content, or by {@link #wrap($type$[]) wrapping} an - * existing $fulltype$ array {#if[char]?or string} into a buffer. + * existing $type$ array {#if[char]?or string} into a buffer. * #else[byte] * * content, by {@link #wrap($type$[]) wrapping} an existing - * $fulltype$ array {#if[char]?or string} into a buffer, or by creating a + * $type$ array {#if[char]?or string} into a buffer, or by creating a * view of an existing byte buffer. * #end[byte] @@ -189,12 +189,12 @@ import java.io.IOException; * #if[!byte] * - *

Like a byte buffer, $a$ $fulltype$ buffer is either Like a byte buffer, $a$ $type$ buffer is either direct or non-direct. A - * $fulltype$ buffer created via the wrap methods of this class will - * be non-direct. $A$ $fulltype$ buffer created as a view of a byte buffer will + * $type$ buffer created via the wrap methods of this class will + * be non-direct. $A$ $type$ buffer created as a view of a byte buffer will * be direct if, and only if, the byte buffer itself is direct. Whether or not - * $a$ $fulltype$ buffer is direct may be determined by invoking the {@link + * $a$ $type$ buffer is direct may be determined by invoking the {@link * #isDirect isDirect} method.

* #end[!byte] @@ -287,7 +287,7 @@ public abstract class $Type$Buffer #if[byte] /** - * Allocates a new direct $fulltype$ buffer. + * Allocates a new direct $type$ buffer. * *

The new buffer's position will be zero, its limit will be its * capacity, its mark will be undefined, and each of its elements will be @@ -295,9 +295,9 @@ public abstract class $Type$Buffer * {@link #hasArray backing array} is unspecified. * * @param capacity - * The new buffer's capacity, in $fulltype$s + * The new buffer's capacity, in $type$s * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer * * @throws IllegalArgumentException * If the capacity is a negative integer @@ -309,7 +309,7 @@ public abstract class $Type$Buffer #end[byte] /** - * Allocates a new $fulltype$ buffer. + * Allocates a new $type$ buffer. * *

The new buffer's position will be zero, its limit will be its * capacity, its mark will be undefined, and each of its elements will be @@ -318,9 +318,9 @@ public abstract class $Type$Buffer * offset} will be zero. * * @param capacity - * The new buffer's capacity, in $fulltype$s + * The new buffer's capacity, in $type$s * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer * * @throws IllegalArgumentException * If the capacity is a negative integer @@ -332,9 +332,9 @@ public abstract class $Type$Buffer } /** - * Wraps $a$ $fulltype$ array into a buffer. + * Wraps $a$ $type$ array into a buffer. * - *

The new buffer will be backed by the given $fulltype$ array; + *

The new buffer will be backed by the given $type$ array; * that is, modifications to the buffer will cause the array to be modified * and vice versa. The new buffer's capacity will be * array.length, its position will be offset, its limit @@ -356,7 +356,7 @@ public abstract class $Type$Buffer * array.length - offset. * The new buffer's limit will be set to offset + length. * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer * * @throws IndexOutOfBoundsException * If the preconditions on the offset and length @@ -373,9 +373,9 @@ public abstract class $Type$Buffer } /** - * Wraps $a$ $fulltype$ array into a buffer. + * Wraps $a$ $type$ array into a buffer. * - *

The new buffer will be backed by the given $fulltype$ array; + *

The new buffer will be backed by the given $type$ array; * that is, modifications to the buffer will cause the array to be modified * and vice versa. The new buffer's capacity and limit will be * array.length, its position will be zero, and its mark will be @@ -386,7 +386,7 @@ public abstract class $Type$Buffer * @param array * The array that will back this buffer * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer */ public static $Type$Buffer wrap($type$[] array) { return wrap(array, 0, array.length); @@ -486,7 +486,7 @@ public abstract class $Type$Buffer #end[char] /** - * Creates a new $fulltype$ buffer whose content is a shared subsequence of + * Creates a new $type$ buffer whose content is a shared subsequence of * this buffer's content. * *

The content of the new buffer will start at this buffer's current @@ -495,17 +495,17 @@ public abstract class $Type$Buffer * values will be independent. * *

The new buffer's position will be zero, its capacity and its limit - * will be the number of $fulltype$s remaining in this buffer, and its mark + * will be the number of $type$s remaining in this buffer, and its mark * will be undefined. The new buffer will be direct if, and only if, this * buffer is direct, and it will be read-only if, and only if, this buffer * is read-only.

* - * @return The new $fulltype$ buffer + * @return The new $type$ buffer */ public abstract $Type$Buffer slice(); /** - * Creates a new $fulltype$ buffer that shares this buffer's content. + * Creates a new $type$ buffer that shares this buffer's content. * *

The content of the new buffer will be that of this buffer. Changes * to this buffer's content will be visible in the new buffer, and vice @@ -517,12 +517,12 @@ public abstract class $Type$Buffer * and only if, this buffer is direct, and it will be read-only if, and * only if, this buffer is read-only.

* - * @return The new $fulltype$ buffer + * @return The new $type$ buffer */ public abstract $Type$Buffer duplicate(); /** - * Creates a new, read-only $fulltype$ buffer that shares this buffer's + * Creates a new, read-only $type$ buffer that shares this buffer's * content. * *

The content of the new buffer will be that of this buffer. Changes @@ -537,7 +537,7 @@ public abstract class $Type$Buffer *

If this buffer is itself read-only then this method behaves in * exactly the same way as the {@link #duplicate duplicate} method.

* - * @return The new, read-only $fulltype$ buffer + * @return The new, read-only $type$ buffer */ public abstract $Type$Buffer asReadOnlyBuffer(); @@ -545,10 +545,10 @@ public abstract class $Type$Buffer // -- Singleton get/put methods -- /** - * Relative get method. Reads the $fulltype$ at this buffer's + * Relative get method. Reads the $type$ at this buffer's * current position, and then increments the position.

* - * @return The $fulltype$ at the buffer's current position + * @return The $type$ at the buffer's current position * * @throws BufferUnderflowException * If the buffer's current position is not smaller than its limit @@ -558,11 +558,11 @@ public abstract class $Type$Buffer /** * Relative put method  (optional operation). * - *

Writes the given $fulltype$ into this buffer at the current + *

Writes the given $type$ into this buffer at the current * position, and then increments the position.

* * @param $x$ - * The $fulltype$ to be written + * The $type$ to be written * * @return This buffer * @@ -575,13 +575,13 @@ public abstract class $Type$Buffer public abstract $Type$Buffer put($type$ $x$); /** - * Absolute get method. Reads the $fulltype$ at the given + * Absolute get method. Reads the $type$ at the given * index.

* * @param index - * The index from which the $fulltype$ will be read + * The index from which the $type$ will be read * - * @return The $fulltype$ at the given index + * @return The $type$ at the given index * * @throws IndexOutOfBoundsException * If index is negative @@ -592,14 +592,14 @@ public abstract class $Type$Buffer /** * Absolute put method  (optional operation). * - *

Writes the given $fulltype$ into this buffer at the given + *

Writes the given $type$ into this buffer at the given * index.

* * @param index - * The index at which the $fulltype$ will be written + * The index at which the $type$ will be written * * @param $x$ - * The $fulltype$ value to be written + * The $type$ value to be written * * @return This buffer * @@ -618,14 +618,14 @@ public abstract class $Type$Buffer /** * Relative bulk get method. * - *

This method transfers $fulltype$s from this buffer into the given - * destination array. If there are fewer $fulltype$s remaining in the + *

This method transfers $type$s from this buffer into the given + * destination array. If there are fewer $type$s remaining in the * buffer than are required to satisfy the request, that is, if * length > remaining(), then no - * $fulltype$s are transferred and a {@link BufferUnderflowException} is + * $type$s are transferred and a {@link BufferUnderflowException} is * thrown. * - *

Otherwise, this method copies length $fulltype$s from this + *

Otherwise, this method copies length $type$s from this * buffer into the given array, starting at the current position of this * buffer and at the given offset in the array. The position of this * buffer is then incremented by length. @@ -638,26 +638,26 @@ public abstract class $Type$Buffer * for (int i = off; i < off + len; i++) * dst[i] = src.get(); * - * except that it first checks that there are sufficient $fulltype$s in + * except that it first checks that there are sufficient $type$s in * this buffer and it is potentially much more efficient.

* * @param dst - * The array into which $fulltype$s are to be written + * The array into which $type$s are to be written * * @param offset - * The offset within the array of the first $fulltype$ to be + * The offset within the array of the first $type$ to be * written; must be non-negative and no larger than * dst.length * * @param length - * The maximum number of $fulltype$s to be written to the given + * The maximum number of $type$s to be written to the given * array; must be non-negative and no larger than * dst.length - offset * * @return This buffer * * @throws BufferUnderflowException - * If there are fewer than length $fulltype$s + * If there are fewer than length $type$s * remaining in this buffer * * @throws IndexOutOfBoundsException @@ -677,7 +677,7 @@ public abstract class $Type$Buffer /** * Relative bulk get method. * - *

This method transfers $fulltype$s from this buffer into the given + *

This method transfers $type$s from this buffer into the given * destination array. An invocation of this method of the form * src.get(a) behaves in exactly the same way as the invocation * @@ -687,7 +687,7 @@ public abstract class $Type$Buffer * @return This buffer * * @throws BufferUnderflowException - * If there are fewer than length $fulltype$s + * If there are fewer than length $type$s * remaining in this buffer */ public $Type$Buffer get($type$[] dst) { @@ -700,15 +700,15 @@ public abstract class $Type$Buffer /** * Relative bulk put method  (optional operation). * - *

This method transfers the $fulltype$s remaining in the given source - * buffer into this buffer. If there are more $fulltype$s remaining in the + *

This method transfers the $type$s remaining in the given source + * buffer into this buffer. If there are more $type$s remaining in the * source buffer than in this buffer, that is, if * src.remaining() > remaining(), - * then no $fulltype$s are transferred and a {@link + * then no $type$s are transferred and a {@link * BufferOverflowException} is thrown. * *

Otherwise, this method copies - * n = src.remaining() $fulltype$s from the given + * n = src.remaining() $type$s from the given * buffer into this buffer, starting at each buffer's current position. * The positions of both buffers are then incremented by n. * @@ -723,14 +723,14 @@ public abstract class $Type$Buffer * buffer and it is potentially much more efficient.

* * @param src - * The source buffer from which $fulltype$s are to be read; + * The source buffer from which $type$s are to be read; * must not be this buffer * * @return This buffer * * @throws BufferOverflowException * If there is insufficient space in this buffer - * for the remaining $fulltype$s in the source buffer + * for the remaining $type$s in the source buffer * * @throws IllegalArgumentException * If the source buffer is this buffer @@ -752,14 +752,14 @@ public abstract class $Type$Buffer /** * Relative bulk put method  (optional operation). * - *

This method transfers $fulltype$s into this buffer from the given - * source array. If there are more $fulltype$s to be copied from the array + *

This method transfers $type$s into this buffer from the given + * source array. If there are more $type$s to be copied from the array * than remain in this buffer, that is, if * length > remaining(), then no - * $fulltype$s are transferred and a {@link BufferOverflowException} is + * $type$s are transferred and a {@link BufferOverflowException} is * thrown. * - *

Otherwise, this method copies length $fulltype$s from the + *

Otherwise, this method copies length $type$s from the * given array into this buffer, starting at the given offset in the array * and at the current position of this buffer. The position of this buffer * is then incremented by length. @@ -776,14 +776,14 @@ public abstract class $Type$Buffer * buffer and it is potentially much more efficient.

* * @param src - * The array from which $fulltype$s are to be read + * The array from which $type$s are to be read * * @param offset - * The offset within the array of the first $fulltype$ to be read; + * The offset within the array of the first $type$ to be read; * must be non-negative and no larger than array.length * * @param length - * The number of $fulltype$s to be read from the given array; + * The number of $type$s to be read from the given array; * must be non-negative and no larger than * array.length - offset * @@ -813,7 +813,7 @@ public abstract class $Type$Buffer * Relative bulk put method  (optional operation). * *

This method transfers the entire content of the given source - * $fulltype$ array into this buffer. An invocation of this method of the + * $type$ array into this buffer. An invocation of this method of the * form dst.put(a) behaves in exactly the same way as the * invocation * @@ -837,15 +837,15 @@ public abstract class $Type$Buffer /** * Relative bulk put method  (optional operation). * - *

This method transfers $fulltype$s from the given string into this - * buffer. If there are more $fulltype$s to be copied from the string than + *

This method transfers $type$s from the given string into this + * buffer. If there are more $type$s to be copied from the string than * remain in this buffer, that is, if * end - start > remaining(), - * then no $fulltype$s are transferred and a {@link + * then no $type$s are transferred and a {@link * BufferOverflowException} is thrown. * *

Otherwise, this method copies - * n = end - start $fulltype$s + * n = end - start $type$s * from the given string into this buffer, starting at the given * start index and at the current position of this buffer. The * position of this buffer is then incremented by n. @@ -862,15 +862,15 @@ public abstract class $Type$Buffer * buffer and it is potentially much more efficient.

* * @param src - * The string from which $fulltype$s are to be read + * The string from which $type$s are to be read * * @param start - * The offset within the string of the first $fulltype$ to be read; + * The offset within the string of the first $type$ to be read; * must be non-negative and no larger than * string.length() * * @param end - * The offset within the string of the last $fulltype$ to be read, + * The offset within the string of the last $type$ to be read, * plus one; must be non-negative and no larger than * string.length() * @@ -921,7 +921,7 @@ public abstract class $Type$Buffer // -- Other stuff -- /** - * Tells whether or not this buffer is backed by an accessible $fulltype$ + * Tells whether or not this buffer is backed by an accessible $type$ * array. * *

If this method returns true then the {@link #array() array} @@ -936,7 +936,7 @@ public abstract class $Type$Buffer } /** - * Returns the $fulltype$ array that backs this + * Returns the $type$ array that backs this * buffer  (optional operation). * *

Modifications to this buffer's content will cause the returned @@ -993,17 +993,17 @@ public abstract class $Type$Buffer /** * Compacts this buffer  (optional operation). * - *

The $fulltype$s between the buffer's current position and its limit, + *

The $type$s between the buffer's current position and its limit, * if any, are copied to the beginning of the buffer. That is, the - * $fulltype$ at index p = position() is copied - * to index zero, the $fulltype$ at index p + 1 is copied - * to index one, and so forth until the $fulltype$ at index + * $type$ at index p = position() is copied + * to index zero, the $type$ at index p + 1 is copied + * to index one, and so forth until the $type$ at index * limit() - 1 is copied to index * n = limit() - 1 - p. * The buffer's position is then set to n+1 and its limit is set to * its capacity. The mark, if defined, is discarded. * - *

The buffer's position is set to the number of $fulltype$s copied, + *

The buffer's position is set to the number of $type$s copied, * rather than to zero, so that an invocation of this method can be * followed immediately by an invocation of another relative put * method.

@@ -1032,7 +1032,7 @@ public abstract class $Type$Buffer public abstract $Type$Buffer compact(); /** - * Tells whether or not this $fulltype$ buffer is direct.

+ * Tells whether or not this $type$ buffer is direct.

* * @return true if, and only if, this buffer is direct */ @@ -1098,6 +1098,13 @@ public abstract class $Type$Buffer * *
  • The two sequences of remaining elements, considered * independently of their starting positions, are pointwise equal. +#if[floatingPointType] + * This method considers two $type$ elements {@code a} and {@code b} + * to be equal if + * {@code (a == b) || ($Fulltype$.isNaN(a) && $Fulltype$.isNaN(b))}. + * The values {@code -0.0} and {@code +0.0} are considered to be + * equal, unlike {@link $Fulltype$#equals(Object)}. +#end[floatingPointType] *

  • * * @@ -1118,24 +1125,37 @@ public abstract class $Type$Buffer if (this.remaining() != that.remaining()) return false; int p = this.position(); - for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) { - $type$ v1 = this.get(i); - $type$ v2 = that.get(j); - if (v1 != v2) { - if ((v1 != v1) && (v2 != v2)) // For float and double - continue; + for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) + if (!equals(this.get(i), that.get(j))) return false; - } - } return true; } + private static boolean equals($type$ x, $type$ y) { +#if[floatingPointType] + return (x == y) || ($Fulltype$.isNaN(x) && $Fulltype$.isNaN(y)); +#else[floatingPointType] + return x == y; +#end[floatingPointType] + } + /** * Compares this buffer to another. * *

    Two $type$ buffers are compared by comparing their sequences of * remaining elements lexicographically, without regard to the starting * position of each sequence within its corresponding buffer. +#if[floatingPointType] + * Pairs of {@code $type$} elements are compared as if by invoking + * {@link $Fulltype$#compare($type$,$type$)}, except that + * {@code -0.0} and {@code 0.0} are considered to be equal. + * {@code $Fulltype$.NaN} is considered by this method to be equal + * to itself and greater than all other {@code $type$} values + * (including {@code $Fulltype$.POSITIVE_INFINITY}). +#else[floatingPointType] + * Pairs of {@code $type$} elements are compared as if by invoking + * {@link $Fulltype$#compare($type$,$type$)}. +#end[floatingPointType] * *

    A $type$ buffer is not comparable to any other type of object. * @@ -1145,20 +1165,23 @@ public abstract class $Type$Buffer public int compareTo($Type$Buffer that) { int n = this.position() + Math.min(this.remaining(), that.remaining()); for (int i = this.position(), j = that.position(); i < n; i++, j++) { - $type$ v1 = this.get(i); - $type$ v2 = that.get(j); - if (v1 == v2) - continue; - if ((v1 != v1) && (v2 != v2)) // For float and double - continue; - if (v1 < v2) - return -1; - return +1; + int cmp = compare(this.get(i), that.get(j)); + if (cmp != 0) + return cmp; } return this.remaining() - that.remaining(); } - + private static int compare($type$ x, $type$ y) { +#if[floatingPointType] + return ((x < y) ? -1 : + (x > y) ? +1 : + (x == y) ? 0 : + $Fulltype$.isNaN(x) ? ($Fulltype$.isNaN(y) ? 0 : +1) : -1); +#else[floatingPointType] + return $Fulltype$.compare(x, y); +#end[floatingPointType] + } // -- Other char stuff -- @@ -1326,7 +1349,7 @@ public abstract class $Type$Buffer } /** - * Appends the specified $fulltype$ to this + * Appends the specified $type$ to this * buffer  (optional operation). * *

    An invocation of this method of the form dst.append($x$) @@ -1336,7 +1359,7 @@ public abstract class $Type$Buffer * dst.put($x$) * * @param $x$ - * The 16-bit $fulltype$ to append + * The 16-bit $type$ to append * * @return This buffer * @@ -1362,10 +1385,10 @@ public abstract class $Type$Buffer /** * Retrieves this buffer's byte order. * - *

    The byte order of $a$ $fulltype$ buffer created by allocation or by + *

    The byte order of $a$ $type$ buffer created by allocation or by * wrapping an existing $type$ array is the {@link * ByteOrder#nativeOrder native order} of the underlying - * hardware. The byte order of $a$ $fulltype$ buffer created as a view of a byte buffer is that of the * byte buffer at the moment that the view is created.

    * diff --git a/jdk/src/share/classes/java/rmi/activation/Activatable.java b/jdk/src/share/classes/java/rmi/activation/Activatable.java index 07879812774dd75abcdf82d22a5ed2432260b2a7..de02b0d6e31e274ac5774dcd4e200b0601dbfc9d 100644 --- a/jdk/src/share/classes/java/rmi/activation/Activatable.java +++ b/jdk/src/share/classes/java/rmi/activation/Activatable.java @@ -73,7 +73,7 @@ public abstract class Activatable extends RemoteServer { * can be handled properly. * *

    This method invokes the {@link - * exportObject(Remote,String,MarshalledObject,boolean,port) + * #exportObject(Remote,String,MarshalledObject,boolean,int) * exportObject} method with this object, and the specified location, * data, restart mode, and port. Subsequent calls to {@link #getID} * will return the activation identifier returned from the call to @@ -120,7 +120,7 @@ public abstract class Activatable extends RemoteServer { * can be handled properly. * *

    This method invokes the {@link - * exportObject(Remote,String,MarshalledObject,boolean,port,RMIClientSocketFactory,RMIServerSocketFactory) + * #exportObject(Remote,String,MarshalledObject,boolean,int,RMIClientSocketFactory,RMIServerSocketFactory) * exportObject} method with this object, and the specified location, * data, restart mode, port, and client and server socket factories. * Subsequent calls to {@link #getID} will return the activation @@ -312,7 +312,7 @@ public abstract class Activatable extends RemoteServer { * separately, so that exceptions can be handled properly. * *

    This method invokes the {@link - * exportObject(Remote,String,MarshalledObject,boolean,port,RMIClientSocketFactory,RMIServerSocketFactory) + * #exportObject(Remote,String,MarshalledObject,boolean,int,RMIClientSocketFactory,RMIServerSocketFactory) * exportObject} method with the specified object, location, data, * restart mode, and port, and null for both client and * server socket factories, and then returns the resulting activation diff --git a/jdk/src/share/classes/java/rmi/registry/LocateRegistry.java b/jdk/src/share/classes/java/rmi/registry/LocateRegistry.java index d32e40357493ab5df6b37203a0089add1223d10f..b65feca8c80bd2ac0ac05a34def3e1a1370e7da6 100644 --- a/jdk/src/share/classes/java/rmi/registry/LocateRegistry.java +++ b/jdk/src/share/classes/java/rmi/registry/LocateRegistry.java @@ -187,7 +187,7 @@ public final class LocateRegistry { * host that accepts requests on the specified port. * *

    The Registry instance is exported as if the static - * {@link UnicastRemoteObject.exportObject(Remote,int) + * {@link UnicastRemoteObject#exportObject(Remote,int) * UnicastRemoteObject.exportObject} method is invoked, passing the * Registry instance and the specified port as * arguments, except that the Registry instance is @@ -213,7 +213,7 @@ public final class LocateRegistry { * *

    The Registry instance is exported as if * the static {@link - * UnicastRemoteObject.exportObject(Remote,int,RMIClientSocketFactory,RMIServerSocketFactory) + * UnicastRemoteObject#exportObject(Remote,int,RMIClientSocketFactory,RMIServerSocketFactory) * UnicastRemoteObject.exportObject} method is invoked, passing the * Registry instance, the specified port, the * specified RMIClientSocketFactory, and the specified diff --git a/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java b/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java index 59de6cfad0204ace772f657a09973d55eba1f32c..06647bac951f181d98429ba3cac811e73a591788 100644 --- a/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java +++ b/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java @@ -138,7 +138,6 @@ public class RemoteObjectInvocationHandler * instance * @throws Throwable the exception to throw from the method invocation * on the proxy instance - * @see **/ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable diff --git a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java index c1ca1d2b8de4cfdb2f41bbd8f58fb01e7a2e14c5..86b0b45e276ef0ca2a77d925dd907362ce3c9225 100644 --- a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java +++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java @@ -216,7 +216,7 @@ public class CertPathValidatorException extends GeneralSecurityException { /** * Returns the reason that the validation failed. The reason is * associated with the index of the certificate returned by - * {@link getIndex}. + * {@link #getIndex}. * * @return the reason that the validation failed, or * BasicReason.UNSPECIFIED if a reason has not been diff --git a/jdk/src/share/classes/java/text/Bidi.java b/jdk/src/share/classes/java/text/Bidi.java index e4db4b2d08625872b1ab34be30952b3e4adbd068..504021ff143062d35f9eba5a6976acf8da57981a 100644 --- a/jdk/src/share/classes/java/text/Bidi.java +++ b/jdk/src/share/classes/java/text/Bidi.java @@ -121,9 +121,9 @@ public final class Bidi { * * @param paragraph a paragraph of text with optional character and paragraph attribute information * - * @see TextAttribute#BIDI_EMBEDDING - * @see TextAttribute#NUMERIC_SHAPING - * @see TextAttribute#RUN_DIRECTION + * @see java.awt.font.TextAttribute#BIDI_EMBEDDING + * @see java.awt.font.TextAttribute#NUMERIC_SHAPING + * @see java.awt.font.TextAttribute#RUN_DIRECTION */ public Bidi(AttributedCharacterIterator paragraph) { if (paragraph == null) { diff --git a/jdk/src/share/classes/java/util/Objects.java b/jdk/src/share/classes/java/util/Objects.java index 3ef61bde98d528ac65384c85395019e95960aaec..8b009243eb938db4acc80b13424c009d09828b84 100644 --- a/jdk/src/share/classes/java/util/Objects.java +++ b/jdk/src/share/classes/java/util/Objects.java @@ -119,7 +119,7 @@ public final class Objects { * * @param values the values to be hashed * @return a hash value of the sequence of input values - * @see Arrays#hashCode + * @see Arrays#hashCode(Object[]) * @see List#hashCode */ public static int hash(Object... values) { diff --git a/jdk/src/share/classes/java/util/logging/PlatformLoggingMXBean.java b/jdk/src/share/classes/java/util/logging/PlatformLoggingMXBean.java index f994e285bcd0a3c19786d9e49d63303e5c8a15e0..b27339461cb19c852f07014c2b1fd413a1abb721 100644 --- a/jdk/src/share/classes/java/util/logging/PlatformLoggingMXBean.java +++ b/jdk/src/share/classes/java/util/logging/PlatformLoggingMXBean.java @@ -51,7 +51,7 @@ import java.lang.management.PlatformManagedObject; * The {@link PlatformManagedObject#getObjectName} method * can be used to obtain its {@code ObjectName}. * - * @See java.lang.management.PlatformManagedObject + * @see java.lang.management.PlatformManagedObject * * @author Mandy Chung * @since 1.7 diff --git a/jdk/src/share/classes/javax/accessibility/AccessibleContext.java b/jdk/src/share/classes/javax/accessibility/AccessibleContext.java index fbe7e9b1d6f6429a76aec01c47457b0a8f00810f..d4a093f72ecd22c2d05a3c6db921e811f1f78c5a 100644 --- a/jdk/src/share/classes/javax/accessibility/AccessibleContext.java +++ b/jdk/src/share/classes/javax/accessibility/AccessibleContext.java @@ -296,7 +296,7 @@ public abstract class AccessibleContext { * * @see #getAccessibleText * @see #addPropertyChangeListener - * @see #AccessibleText.AccessibleTextSequence + * @see AccessibleTextSequence */ public static final String ACCESSIBLE_TEXT_PROPERTY = "AccessibleText"; @@ -311,7 +311,7 @@ public abstract class AccessibleContext { * * @see #getAccessibleText * @see #addPropertyChangeListener - * @see #AccessibleText.AccessibleTextSequence + * @see AccessibleTextSequence * * @since 1.5 */ @@ -334,7 +334,7 @@ public abstract class AccessibleContext { * * @see #getAccessibleText * @see #addPropertyChangeListener - * @see #AccessibleText.AccessibleAttributeSequence + * @see AccessibleAttributeSequence * * @since 1.5 */ diff --git a/jdk/src/share/classes/javax/accessibility/AccessibleExtendedText.java b/jdk/src/share/classes/javax/accessibility/AccessibleExtendedText.java index 4868ab85e8f7bd0dae7225ffc63e6bf03a5bd84f..f7a0425213601d123686d314323fd32c730bf30d 100644 --- a/jdk/src/share/classes/javax/accessibility/AccessibleExtendedText.java +++ b/jdk/src/share/classes/javax/accessibility/AccessibleExtendedText.java @@ -45,7 +45,6 @@ import javax.swing.text.*; * @see Accessible#getAccessibleContext * @see AccessibleContext * @see AccessibleContext#getAccessibleText - * @see AccessibleText.AccessibleTextChunk * * @author Peter Korn * @author Lynn Monsanto diff --git a/jdk/src/share/classes/javax/accessibility/AccessibleKeyBinding.java b/jdk/src/share/classes/javax/accessibility/AccessibleKeyBinding.java index cdf4c493a62de27d451e9cc93982e8d9159eef23..e50e9f54259d3d5fb6be90940d33bf4eb1d9ecf2 100644 --- a/jdk/src/share/classes/javax/accessibility/AccessibleKeyBinding.java +++ b/jdk/src/share/classes/javax/accessibility/AccessibleKeyBinding.java @@ -32,16 +32,11 @@ package javax.accessibility; * the standard mechanism for an assistive technology to determine the * key bindings which exist for this object. * Any object that has such key bindings should support this - * interface. Applications can determine if an object supports the - * AccessibleKeyBinding interface by first obtaining its AccessibleContext - * (see @link Accessible} and then calling the - * {@link AccessibleContext#getAccessibleKeyBinding} method. If the return - * value is not null, the object supports this interface. + * interface. * * @see Accessible * @see Accessible#getAccessibleContext * @see AccessibleContext - * @see AccessibleContext#getAccessibleKeyBinding * * @author Lynn Monsanto * @since 1.4 @@ -58,21 +53,7 @@ public interface AccessibleKeyBinding { /** * Returns a key binding for this object. The value returned is an * java.lang.Object which must be cast to appropriate type depending - * on the underlying implementation of the key. For example, if the - * Object returned is a javax.swing.KeyStroke, the user of this - * method should do the following: - * - * Component c = - * AccessibleContext ac = c.getAccessibleContext(); - * AccessibleKeyBinding akb = ac.getAccessibleKeyBinding(); - * for (int i = 0; i < akb.getAccessibleKeyBindingCount(); i++) { - * Object o = akb.getAccessibleKeyBinding(i); - * if (o instanceof javax.swing.KeyStroke) { - * javax.swing.KeyStroke keyStroke = (javax.swing.KeyStroke)o; - * - * } - * } - * + * on the underlying implementation of the key. * * @param i zero-based index of the key bindings * @return a javax.lang.Object which specifies the key binding diff --git a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java index a758486e0cbdaaf81d3e80e71bc80fa0d68eed96..092681bd92d95fe66a1f3c091b88e38a986d9946 100644 --- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java +++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java @@ -326,7 +326,7 @@ public final class DOMXMLSignature extends DOMStructure } // generate references and signature value - List allReferences = new ArrayList(si.getReferences()); + List allReferences = new ArrayList(); // traverse the Signature and register all objects with IDs that // may contain References @@ -356,6 +356,9 @@ public final class DOMXMLSignature extends DOMStructure } } } + // always add SignedInfo references after Manifest references so + // that Manifest reference are digested first + allReferences.addAll(si.getReferences()); // generate/digest each reference for (int i = 0, size = allReferences.size(); i < size; i++) { diff --git a/jdk/src/share/native/java/lang/StrictMath.c b/jdk/src/share/native/java/lang/StrictMath.c index 2bf12e3b71e911961a6c88a0b8daf0bce0e4fb3b..01024b309d34adcd88eb547a11f8b9620cb4395b 100644 --- a/jdk/src/share/native/java/lang/StrictMath.c +++ b/jdk/src/share/native/java/lang/StrictMath.c @@ -94,18 +94,6 @@ Java_java_lang_StrictMath_cbrt(JNIEnv *env, jclass unused, jdouble d) return (jdouble) jcbrt((double)d); } -JNIEXPORT jdouble JNICALL -Java_java_lang_StrictMath_ceil(JNIEnv *env, jclass unused, jdouble d) -{ - return (jdouble) jceil((double)d); -} - -JNIEXPORT jdouble JNICALL -Java_java_lang_StrictMath_floor(JNIEnv *env, jclass unused, jdouble d) -{ - return (jdouble) jfloor((double)d); -} - JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_atan2(JNIEnv *env, jclass unused, jdouble d1, jdouble d2) { diff --git a/jdk/src/windows/native/java/net/SocketInputStream.c b/jdk/src/windows/native/java/net/SocketInputStream.c index 54c9a8a88feff33e662f870f0a183cb4a316bf96..bbf6a9ac6fc0ef90da5c2d053f4f7c03a4ee5d6d 100644 --- a/jdk/src/windows/native/java/net/SocketInputStream.c +++ b/jdk/src/windows/native/java/net/SocketInputStream.c @@ -121,6 +121,9 @@ Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this, newfd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); if (newfd == -1) { NET_ThrowSocketException(env, "Socket Closed"); + if (bufP != BUF) { + free(bufP); + } return -1; } } diff --git a/jdk/test/Makefile b/jdk/test/Makefile index 25f0dc1ed6fcb3b32e218d4eda4a2fa2f462e4d3..bffa3ad7cb06a346d9e7354502bef3c81ca862e0 100644 --- a/jdk/test/Makefile +++ b/jdk/test/Makefile @@ -291,7 +291,7 @@ TESTEXIT = \ fi ; \ testExitCode=`$(CAT) $(EXITCODE)`; \ $(ECHO) "EXIT CODE: $${testExitCode}"; \ - exit ${testExitCode} + exit $${testExitCode} BUNDLE_UP_AND_EXIT = \ ( \ @@ -300,7 +300,7 @@ BUNDLE_UP_AND_EXIT = \ $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \ $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \ if [ -r "$${_summary}" ] ; then \ - $(ECHO) "Summary: $${_summary}" > $(STATS_TXT); \ + $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \ $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \ $(EGREP) ' Passed\.' $(RUNLIST) \ | $(EGREP) -v ' Error\.' \ @@ -370,7 +370,8 @@ ifndef USE_JTREG_SAMEVM endif # With samevm, you cannot use -javaoptions? ifeq ($(USE_JTREG_SAMEVM),true) - EXTRA_JTREG_OPTIONS += -samevm $(JAVA_ARGS) $(JAVA_ARGS:%=-vmoption:%) + JTREG_SAMEVM_OPTION = -samevm + EXTRA_JTREG_OPTIONS += $(JTREG_SAMEVM_OPTION) $(JAVA_ARGS) $(JAVA_ARGS:%=-vmoption:%) JTREG_TEST_OPTIONS = $(JAVA_VM_ARGS:%=-vmoption:%) else JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%) @@ -418,8 +419,9 @@ $(ECHO) "Running tests in othervm mode: $(call TestDirs, $?)" $(MAKE) TESTDIRS="$(call TestDirs, $?)" USE_JTREG_SAMEVM=false UNIQUE_DIR=$@ jtreg_tests endef define SummaryInfo -$(ECHO) "Summary for: $?" +$(ECHO) "########################################################" $(CAT) $(?:%=$(ABS_TEST_OUTPUT_DIR)/%/$(STATS_TXT_NAME)) +$(ECHO) "########################################################" endef # ------------------------------------------------------------------ @@ -446,10 +448,14 @@ JDK_ALL_TARGETS += jdk_beans2 jdk_beans2: java/beans/Beans java/beans/EventHandler java/beans/XMLDecoder \ java/beans/PropertyEditor $(call RunOthervmBatch) + +# Stable othervm testruns (minus items from PROBLEM_LIST) +# Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_beans3 jdk_beans3: java/beans/XMLEncoder $(call RunOthervmBatch) +# All beans tests jdk_beans: jdk_beans1 jdk_beans2 jdk_beans3 @$(SummaryInfo) @@ -475,6 +481,7 @@ JDK_ALL_TARGETS += jdk_management2 jdk_management2: com/sun/jmx com/sun/management sun/management $(call RunOthervmBatch) +# All management tests jdk_management: jdk_management1 jdk_management2 @$(SummaryInfo) @@ -506,10 +513,14 @@ JDK_ALL_TARGETS += jdk_nio2 jdk_nio2: java/nio/Buffer java/nio/ByteOrder \ java/nio/channels java/nio/BufferPoolMXBean java/nio/MappedByteBuffer $(call RunOthervmBatch) + +# Stable othervm testruns (minus items from PROBLEM_LIST) +# Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_nio3 jdk_nio3: com/sun/nio sun/nio $(call RunOthervmBatch) +# All nio tests jdk_nio: jdk_nio1 jdk_nio2 jdk_nio3 @$(SummaryInfo) @@ -529,10 +540,14 @@ jdk_security1: java/security JDK_ALL_TARGETS += jdk_security2 jdk_security2: javax/crypto com/sun/crypto $(call RunOthervmBatch) + +# Stable othervm testruns (minus items from PROBLEM_LIST) +# Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_security3 jdk_security3: com/sun/security lib/security javax/security sun/security $(call RunOthervmBatch) +# All security tests jdk_security: jdk_security1 jdk_security2 jdk_security3 @$(SummaryInfo) @@ -547,15 +562,18 @@ JDK_ALL_TARGETS += jdk_text jdk_text: java/text sun/text $(call RunSamevmBatch) -# Stable othervm testruns (minus items from PROBLEM_LIST) -# Using samevm has serious problems with these tests +# Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_tools1 jdk_tools1: com/sun/jdi $(call RunSamevmBatch) + +# Stable othervm testruns (minus items from PROBLEM_LIST) +# Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_tools2 jdk_tools2: com/sun/tools sun/jvmstat sun/tools tools vm com/sun/servicetag com/sun/tracing $(call RunOthervmBatch) +# All tools tests jdk_tools: jdk_tools1 jdk_tools2 @$(SummaryInfo) @@ -567,7 +585,9 @@ jdk_util: java/util sun/util # ------------------------------------------------------------------ # Run all tests -jdk_all: $(filter-out jdk_awt jdk_rmi jdk_swing, $(JDK_ALL_TARGETS)) +FILTER_OUT_LIST=jdk_awt jdk_rmi jdk_swing +JDK_ALL_STABLE_TARGETS := $(filter-out $(FILTER_OUT_LIST), $(JDK_ALL_TARGETS)) +jdk_all: $(JDK_ALL_STABLE_TARGETS) @$(SummaryInfo) # These are all phony targets @@ -581,16 +601,22 @@ JTREG = $(JT_HOME)/win32/bin/jtreg JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS) # Only run automatic tests JTREG_BASIC_OPTIONS += -a +# Always turn on assertions +JTREG_ASSERT_OPTION = -ea -esa +JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION) # Report details on all failed or error tests, times too JTREG_BASIC_OPTIONS += -v:fail,error,time # Retain all files for failing tests JTREG_BASIC_OPTIONS += -retain:fail,error # Ignore tests are not run and completely silent about it -JTREG_BASIC_OPTIONS += -ignore:quiet -# Multiple by 2 the timeout numbers -JTREG_BASIC_OPTIONS += -timeoutFactor:2 +JTREG_IGNORE_OPTION = -ignore:quiet +JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION) +# Multiple by 4 the timeout numbers +JTREG_TIMEOUT_OPTION = -timeoutFactor:4 +JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION) # Boost the max memory for jtreg to avoid gc thrashing -JTREG_BASIC_OPTIONS += -J-Xmx512m +JTREG_MEMORY_OPTION = -J-Xmx512m +JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION) # Make sure jtreg exists $(JTREG): $(JT_HOME) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 2edcfd4d59502614b29122531660724ce476ac91..9cf24b2a5e143d8b04e4879fcd430f19a83d025e 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -431,6 +431,11 @@ java/lang/ClassLoader/deadlock/TestCrossDelegate.sh generic-all # jdk_management +# Fails on Windows 2000, Test failed for iiop java.lang.NullPointerException +# at org.omg.stub.javax.management.remote.rmi._RMIConnectionImpl_Tie._invoke(Unknown Source) +# at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:653) +javax/management/remote/mandatory/connection/ReconnectTest.java generic-all + # Solaris 10 sparc, NPE from org.omg.stub.javax.management.remote.rmi._RMIConnectionImpl_Tie._invoke javax/management/remote/mandatory/threads/ExecutorTest.java generic-all @@ -581,6 +586,14 @@ javax/print/attribute/MediaMappingsTest.java generic-all # Suspect many of these tests auffer from using fixed ports, no concrete # evidence. +# Dies on Solaris 10 sparc and sparcv9, Linux -ea -esa with +# Interrupted or IO exception, maybe writing to non-unique named file? +com/sun/net/httpserver/bugs/B6373555.java generic-all + +# Dies on pretty much all platforms when run with -ea -esa, Assertion error +java/net/CookieHandler/TestHttpCookie.java generic-all +java/net/URLClassLoader/closetest/CloseTest.java generic-all + # Fails on OpenSolaris, BindException unexpected java/net/BindException/Test.java generic-all @@ -717,6 +730,9 @@ sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java generic-all # Connection refused, windows samevm sun/net/www/protocol/http/DigestTest.java generic-all +# Fails on Fedora 9 32bit & 64bit & Solaris 10, wrong proxy for http://localhost/index.html +java/net/ProxySelector/B6737819.java generic-all + ############################################################################ # jdk_nio @@ -724,6 +740,33 @@ sun/net/www/protocol/http/DigestTest.java generic-all # Suspect many of these tests auffer from using fixed ports, no concrete # evidence. +# Fails with -ea -esa, Assertion error, but only on Solaris 10 machines? +com/sun/nio/sctp/SctpChannel/Send.java generic-all +com/sun/nio/sctp/SctpChannel/Shutdown.java generic-all + +# Fails on Windows 2000, Can't delete test directory .\x.SetLastModified.dir +# at SetLastModified.main(SetLastModified.java:107) +java/io/File/SetLastModified.java generic-all + +# Fails on Solaris 10 x64, address already in use +java/nio/channels/DatagramChannel/SRTest.java generic-all + +# Fails on Solaris 10 x86, times out +java/nio/channels/DatagramChannel/Sender.java generic-all + +# Fails on Fedora 9 x86, address in use +java/nio/channels/Selector/SelectWrite.java generic-all + +# Fails on Fedora 9 32bit times out +java/nio/channels/DatagramChannel/EmptyBuffer.java generic-all + +# Fails on Windows 2000, ExceptionInInitializerError +# in WindowsAsynchronousServerSocketChannelImpl.java:316 +java/nio/channels/AsynchronousChannelGroup/Unbounded.java generic-all + +# Fails on Windows 2000, times out +java/nio/channels/FileChannel/Transfer.java generic-all + # Fails on OpenSolaris, IllegalStateException: Cannot add or remove addresses # from a channel that is bound to the wildcard address com/sun/nio/sctp/SctpChannel/Bind.java generic-all @@ -893,6 +936,48 @@ java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java generic-all # jdk_security +# Fails with -ea -esa, but only on Solaris sparc? Suspect it is timing out +sun/security/tools/keytool/standard.sh generic-all + +# Fails on Solaris 10 X64, address already in use +sun/security/krb5/auto/HttpNegotiateServer.java generic-all + +# Fails on almost all platforms +# java.lang.UnsupportedClassVersionError: SerialTest : +# Unsupported major.minor version 51.0 +# at java.lang.ClassLoader.defineClass1(Native Method) +sun/security/util/Oid/S11N.sh generic-all + +# Fails on Fedora 9 32bit +# GSSException: Failure unspecified at GSS-API level (Mechanism level: +# Invalid argument (400) - Cannot find key of appropriate type to decrypt +# AP REP - DES CBC mode with MD5) +# at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:778) +sun/security/krb5/auto/NonMutualSpnego.java generic-all + +# Fails on Solaris 10 sparc, GSSException: Failure unspecified at GSS-API level +# Also fails on Windows 2000 similar way +sun/security/krb5/auto/ok-as-delegate.sh generic-all + +# Fails on Windows 2000, GSSException: Failure unspecified at GSS-API level +# (Mechanism level: Request is a replay (34)) +sun/security/krb5/auto/ok-as-delegate-xrealm.sh generic-all + +# Fails on Windows 2000, ExceptionInInitializerError +sun/security/mscapi/AccessKeyStore.sh generic-all + +# Fails on Windows 2000, UnsatisfiedLinkError: libnspr4.dll: Access is denied +sun/security/pkcs11/KeyAgreement/TestDH.java generic-all + +# Fails on Windows 2000, UnsatisfiedLinkError: libnspr4.dll: Access is denied +sun/security/pkcs11/fips/ClientJSSEServerJSSE.java generic-all + +# Fails on Solaris 10, KrbException: Additional pre-authentication required (25) +sun/security/krb5/auto/basic.sh generic-all + +# Fails on Fedora 9 64bit, PKCS11Exception: CKR_DEVICE_ERROR +sun/security/pkcs11/KeyAgreement/TestDH.java generic-all + # Run too slow on Solaris 10 sparc sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/SSLSocketTimeoutNulls.java solaris-sparc sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientTimeout.java solaris-sparc @@ -1088,6 +1173,16 @@ java/text/Bidi/Bug6665028.java linux-x64 # So most if not all tools tests are now being run with "othervm" mode. # Some of these tools tests have a tendency to use fixed ports, bad idea. +# Fails with -ea -esa on Solaris, Assertion error (Solaris specific test) +com/sun/tracing/BasicFunctionality.java generic-all + +# Fails on Fedora 9 32bit, jps output differs problem +sun/tools/jstatd/jstatdDefaults.sh generic-all + +# Fails on Linux Fedora 9 32bit, Could not read data for remote JVM 16133 +# jstat output differs from expected output +sun/tools/jstatd/jstatdExternalRegistry.sh generic-all + # Output of jps differs from expected output. # Invalid argument count on solaris-sparc and x64 sun/tools/jstatd/jstatdPort.sh generic-all @@ -1099,6 +1194,11 @@ sun/tools/jps/jps-lm.sh generic-all sun/tools/jps/jps-Vvml_2.sh generic-all sun/tools/jps/jps-m_2.sh generic-all +# Fails on Solaris 10 sparcv9, shell exits with 1 +# Turning off use of shared archive because of choice of garbage collector or large pages +# Could not synchronize with target +sun/tools/jps/jps-v_1.sh generic-all + # Fails on OpenSolaris "Could not synchronize with target" sun/tools/jps/jps-Defaults.sh generic-all sun/tools/jps/jps-V_2.sh generic-all @@ -1160,6 +1260,12 @@ tools/jar/index/MetaInf.java windows-all # jdk_util +# Fails with -ea -esa on all platforms with Assertion error +java/util/ResourceBundle/Test4300693.java generic-all + +# Failing on all -client 32bit platforms starting with b77? See 6908348. +java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java generic-all + # Assert error, failures, on Linux Fedora 9 -server # Windows samevm failure, assert error "Passed = 134, failed = 2" java/util/Arrays/ArrayObjectMethods.java generic-all diff --git a/jdk/test/com/sun/jdi/NoLaunchOptionTest.java b/jdk/test/com/sun/jdi/NoLaunchOptionTest.java index b65b375c85e3eeea22cf80fd80bce4ad658de995..14e6acd2c5d2b6af0770250d9c8fd43e6250d784 100644 --- a/jdk/test/com/sun/jdi/NoLaunchOptionTest.java +++ b/jdk/test/com/sun/jdi/NoLaunchOptionTest.java @@ -31,6 +31,9 @@ * @build VMConnection * @run main/othervm NoLaunchOptionTest */ + +import java.net.ServerSocket; + public class NoLaunchOptionTest extends Object { private Process subprocess; private int subprocessStatus; @@ -121,12 +124,19 @@ public class NoLaunchOptionTest extends Object { } public static void main(String[] args) throws Exception { + // find a free port + ServerSocket ss = new ServerSocket(0); + int port = ss.getLocalPort(); + ss.close(); + String address = String.valueOf(port); + String javaExe = System.getProperty("java.home") + java.io.File.separator + "bin" + java.io.File.separator + "java"; String targetClass = "NotAClass"; String cmds [] = {javaExe, - "-agentlib:jdwp=transport=dt_socket,address=8000," + + "-agentlib:jdwp=transport=dt_socket,address=" + + address + "," + "onthrow=java.lang.ClassNotFoundException,suspend=n", targetClass}; NoLaunchOptionTest myTest = new NoLaunchOptionTest(); diff --git a/jdk/test/com/sun/jdi/OptionTest.java b/jdk/test/com/sun/jdi/OptionTest.java index e3d6eb60b2dadeca0c03f9db6631805bd4e228f3..f6124d3e02abd00e6b90f6832a68935ad8aa5384 100644 --- a/jdk/test/com/sun/jdi/OptionTest.java +++ b/jdk/test/com/sun/jdi/OptionTest.java @@ -32,6 +32,9 @@ * @run compile -g VMConnection.java * @run main/othervm OptionTest */ + +import java.net.ServerSocket; + public class OptionTest extends Object { private Process subprocess; private int subprocessStatus; @@ -122,12 +125,18 @@ public class OptionTest extends Object { } public static void main(String[] args) throws Exception { + // find a free port + ServerSocket ss = new ServerSocket(0); + int port = ss.getLocalPort(); + ss.close(); + String address = String.valueOf(port); + String javaExe = System.getProperty("java.home") + java.io.File.separator + "bin" + java.io.File.separator + "java"; String targetClass = "HelloWorld"; String baseOptions = "transport=dt_socket" + - ",address=8000" + + ",address=" + address + ",server=y" + ",suspend=n"; diff --git a/jdk/test/java/lang/Math/CeilAndFloorTests.java b/jdk/test/java/lang/Math/CeilAndFloorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..12d899d8180899eed2a2619b19d0539f2c40ad3a --- /dev/null +++ b/jdk/test/java/lang/Math/CeilAndFloorTests.java @@ -0,0 +1,201 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6908131 + * @summary Check for correct implementation of Math.ceil and Math.floor + */ + +import sun.misc.FpUtils; +import sun.misc.DoubleConsts; + +public class CeilAndFloorTests { + private static int testCeilCase(double input, double expected) { + int failures = 0; + failures += Tests.test("Math.ceil", input, Math.ceil(input), expected); + failures += Tests.test("StrictMath.ceil", input, StrictMath.ceil(input), expected); + return failures; + } + + private static int testFloorCase(double input, double expected) { + int failures = 0; + failures += Tests.test("Math.floor", input, Math.floor(input), expected); + failures += Tests.test("StrictMath.floor", input, StrictMath.floor(input), expected); + return failures; + } + + private static int nearIntegerTests() { + int failures = 0; + + double [] fixedPoints = { + -0.0, + 0.0, + -1.0, + 1.0, + -0x1.0p52, + 0x1.0p52, + -Double.MAX_VALUE, + Double.MAX_VALUE, + Double.NEGATIVE_INFINITY, + Double.POSITIVE_INFINITY, + Double.NaN, + }; + + for(double fixedPoint : fixedPoints) { + failures += testCeilCase(fixedPoint, fixedPoint); + failures += testFloorCase(fixedPoint, fixedPoint); + } + + for(int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) { + double powerOfTwo = Math.scalb(1.0, i); + double neighborDown = FpUtils.nextDown(powerOfTwo); + double neighborUp = Math.nextUp(powerOfTwo); + + if (i < 0) { + failures += testCeilCase( powerOfTwo, 1.0); + failures += testCeilCase(-powerOfTwo, -0.0); + + failures += testFloorCase( powerOfTwo, 0.0); + failures += testFloorCase(-powerOfTwo, -1.0); + + failures += testCeilCase( neighborDown, 1.0); + failures += testCeilCase(-neighborDown, -0.0); + + failures += testFloorCase( neighborUp, 0.0); + failures += testFloorCase(-neighborUp, -1.0); + } else { + failures += testCeilCase(powerOfTwo, powerOfTwo); + failures += testFloorCase(powerOfTwo, powerOfTwo); + + if (neighborDown==Math.rint(neighborDown)) { + failures += testCeilCase( neighborDown, neighborDown); + failures += testCeilCase(-neighborDown, -neighborDown); + + failures += testFloorCase( neighborDown, neighborDown); + failures += testFloorCase(-neighborDown,-neighborDown); + } else { + failures += testCeilCase( neighborDown, powerOfTwo); + failures += testFloorCase(-neighborDown, -powerOfTwo); + } + + if (neighborUp==Math.rint(neighborUp)) { + failures += testCeilCase(neighborUp, neighborUp); + failures += testCeilCase(-neighborUp, -neighborUp); + + failures += testFloorCase(neighborUp, neighborUp); + failures += testFloorCase(-neighborUp, -neighborUp); + } else { + failures += testFloorCase(neighborUp, powerOfTwo); + failures += testCeilCase(-neighborUp, -powerOfTwo); + } + } + } + + for(int i = -(0x10000); i <= 0x10000; i++) { + double d = (double) i; + double neighborDown = FpUtils.nextDown(d); + double neighborUp = Math.nextUp(d); + + failures += testCeilCase( d, d); + failures += testCeilCase(-d, -d); + + failures += testFloorCase( d, d); + failures += testFloorCase(-d, -d); + + if (Math.abs(d) > 1.0) { + failures += testCeilCase( neighborDown, d); + failures += testCeilCase(-neighborDown, -d+1); + + failures += testFloorCase( neighborUp, d); + failures += testFloorCase(-neighborUp, -d-1); + } + } + + return failures; + } + + public static int roundingTests() { + int failures = 0; + double [][] testCases = { + { Double.MIN_VALUE, 1.0}, + {-Double.MIN_VALUE, -0.0}, + { FpUtils.nextDown(DoubleConsts.MIN_NORMAL), 1.0}, + {-FpUtils.nextDown(DoubleConsts.MIN_NORMAL), -0.0}, + { DoubleConsts.MIN_NORMAL, 1.0}, + {-DoubleConsts.MIN_NORMAL, -0.0}, + + { 0.1, 1.0}, + {-0.1, -0.0}, + + { 0.5, 1.0}, + {-0.5, -0.0}, + + { 1.5, 2.0}, + {-1.5, -1.0}, + + { 2.5, 3.0}, + {-2.5, -2.0}, + + { FpUtils.nextDown(1.0), 1.0}, + { FpUtils.nextDown(-1.0), -1.0}, + + { Math.nextUp(1.0), 2.0}, + { Math.nextUp(-1.0), -0.0}, + + { 0x1.0p51, 0x1.0p51}, + {-0x1.0p51, -0x1.0p51}, + + { FpUtils.nextDown(0x1.0p51), 0x1.0p51}, + {-Math.nextUp(0x1.0p51), -0x1.0p51}, + + { Math.nextUp(0x1.0p51), 0x1.0p51+1}, + {-FpUtils.nextDown(0x1.0p51), -0x1.0p51+1}, + + { FpUtils.nextDown(0x1.0p52), 0x1.0p52}, + {-Math.nextUp(0x1.0p52), -0x1.0p52-1.0}, + + { Math.nextUp(0x1.0p52), 0x1.0p52+1.0}, + {-FpUtils.nextDown(0x1.0p52), -0x1.0p52+1.0}, + }; + + for(double[] testCase : testCases) { + failures += testCeilCase(testCase[0], testCase[1]); + failures += testFloorCase(-testCase[0], -testCase[1]); + } + return failures; + } + + public static void main(String... args) { + int failures = 0; + + failures += nearIntegerTests(); + failures += roundingTests(); + + if (failures > 0) { + System.err.println("Testing {Math, StrictMath}.ceil incurred " + + failures + " failures."); + throw new RuntimeException(); + } + } +} diff --git a/jdk/test/java/nio/Buffer/Basic-X.java.template b/jdk/test/java/nio/Buffer/Basic-X.java.template index 6612771def4d2c49d9298d3fe7baeb79be39d0a7..93cbe8eb5ee1b1de66fb2546ed1f43ad03e020df 100644 --- a/jdk/test/java/nio/Buffer/Basic-X.java.template +++ b/jdk/test/java/nio/Buffer/Basic-X.java.template @@ -38,6 +38,26 @@ public class Basic$Type$ extends Basic { + private static final $type$[] VALUES = { + $Fulltype$.MIN_VALUE, + ($type$) -1, + ($type$) 0, + ($type$) 1, + $Fulltype$.MAX_VALUE, +#if[float] + $Fulltype$.NEGATIVE_INFINITY, + $Fulltype$.POSITIVE_INFINITY, + $Fulltype$.NaN, + ($type$) -0.0, +#end[float] +#if[double] + $Fulltype$.NEGATIVE_INFINITY, + $Fulltype$.POSITIVE_INFINITY, + $Fulltype$.NaN, + ($type$) -0.0, +#end[double] + }; + private static void relGet($Type$Buffer b) { int n = b.capacity(); $type$ v; @@ -309,6 +329,12 @@ public class Basic$Type$ #end[byte] + private static void fail(String problem, + $Type$Buffer xb, $Type$Buffer yb, + $type$ x, $type$ y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ public class Basic$Type$ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for ($type$ x : VALUES) { + $Type$Buffer xb = $Type$Buffer.wrap(new $type$[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for ($type$ y : VALUES) { + $Type$Buffer yb = $Type$Buffer.wrap(new $type$[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != $Fulltype$.compare(x, y)) { +#if[float] + if (x == 0.0 && y == 0.0) continue; +#end[float] +#if[double] + if (x == 0.0 && y == 0.0) continue; +#end[double] + fail("Incorrect results for $Type$Buffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for $Type$Buffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b); diff --git a/jdk/test/java/nio/Buffer/BasicByte.java b/jdk/test/java/nio/Buffer/BasicByte.java index 7e259a1416ded179ab076c0b7c9dab17c3718be3..78b209936d76ec5dce341d0e2a15e709245865e5 100644 --- a/jdk/test/java/nio/Buffer/BasicByte.java +++ b/jdk/test/java/nio/Buffer/BasicByte.java @@ -38,6 +38,26 @@ public class BasicByte extends Basic { + private static final byte[] VALUES = { + Byte.MIN_VALUE, + (byte) -1, + (byte) 0, + (byte) 1, + Byte.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(ByteBuffer b) { int n = b.capacity(); byte v; @@ -309,6 +329,12 @@ public class BasicByte + private static void fail(String problem, + ByteBuffer xb, ByteBuffer yb, + byte x, byte y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ public class BasicByte if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (byte x : VALUES) { + ByteBuffer xb = ByteBuffer.wrap(new byte[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (byte y : VALUES) { + ByteBuffer yb = ByteBuffer.wrap(new byte[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Byte.compare(x, y)) { + + + + + + + fail("Incorrect results for ByteBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for ByteBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b); diff --git a/jdk/test/java/nio/Buffer/BasicChar.java b/jdk/test/java/nio/Buffer/BasicChar.java index a0df9fcf3a92dc00751f41301af8025f4831730b..9f3c5e4219c15154268c4934ebfef137a8a2b3a3 100644 --- a/jdk/test/java/nio/Buffer/BasicChar.java +++ b/jdk/test/java/nio/Buffer/BasicChar.java @@ -38,6 +38,26 @@ public class BasicChar extends Basic { + private static final char[] VALUES = { + Character.MIN_VALUE, + (char) -1, + (char) 0, + (char) 1, + Character.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(CharBuffer b) { int n = b.capacity(); char v; @@ -308,6 +328,12 @@ public class BasicChar + + private static void fail(String problem, + CharBuffer xb, CharBuffer yb, + char x, char y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; @@ -522,6 +548,42 @@ public class BasicChar if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (char x : VALUES) { + CharBuffer xb = CharBuffer.wrap(new char[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (char y : VALUES) { + CharBuffer yb = CharBuffer.wrap(new char[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Character.compare(x, y)) { + + + + + + + fail("Incorrect results for CharBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for CharBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b); diff --git a/jdk/test/java/nio/Buffer/BasicDouble.java b/jdk/test/java/nio/Buffer/BasicDouble.java index a627d0e919469911e73b09a61195896b0374ae74..97f5fa200de192b295e36b821534e98c8945b6b7 100644 --- a/jdk/test/java/nio/Buffer/BasicDouble.java +++ b/jdk/test/java/nio/Buffer/BasicDouble.java @@ -38,6 +38,26 @@ public class BasicDouble extends Basic { + private static final double[] VALUES = { + Double.MIN_VALUE, + (double) -1, + (double) 0, + (double) 1, + Double.MAX_VALUE, + + + + + + + + Double.NEGATIVE_INFINITY, + Double.POSITIVE_INFINITY, + Double.NaN, + (double) -0.0, + + }; + private static void relGet(DoubleBuffer b) { int n = b.capacity(); double v; @@ -308,6 +328,12 @@ public class BasicDouble + + private static void fail(String problem, + DoubleBuffer xb, DoubleBuffer yb, + double x, double y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; @@ -522,6 +548,42 @@ public class BasicDouble if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (double x : VALUES) { + DoubleBuffer xb = DoubleBuffer.wrap(new double[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (double y : VALUES) { + DoubleBuffer yb = DoubleBuffer.wrap(new double[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Double.compare(x, y)) { + + + + + if (x == 0.0 && y == 0.0) continue; + + fail("Incorrect results for DoubleBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for DoubleBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b); diff --git a/jdk/test/java/nio/Buffer/BasicFloat.java b/jdk/test/java/nio/Buffer/BasicFloat.java index 730dcbeac956a4eb296dced253c73c37d2932819..46bdfe163cb29d3debe3cb36aa2c259ecd75ef58 100644 --- a/jdk/test/java/nio/Buffer/BasicFloat.java +++ b/jdk/test/java/nio/Buffer/BasicFloat.java @@ -38,6 +38,26 @@ public class BasicFloat extends Basic { + private static final float[] VALUES = { + Float.MIN_VALUE, + (float) -1, + (float) 0, + (float) 1, + Float.MAX_VALUE, + + Float.NEGATIVE_INFINITY, + Float.POSITIVE_INFINITY, + Float.NaN, + (float) -0.0, + + + + + + + + }; + private static void relGet(FloatBuffer b) { int n = b.capacity(); float v; @@ -308,6 +328,12 @@ public class BasicFloat + + private static void fail(String problem, + FloatBuffer xb, FloatBuffer yb, + float x, float y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; @@ -522,6 +548,42 @@ public class BasicFloat if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (float x : VALUES) { + FloatBuffer xb = FloatBuffer.wrap(new float[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (float y : VALUES) { + FloatBuffer yb = FloatBuffer.wrap(new float[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Float.compare(x, y)) { + + if (x == 0.0 && y == 0.0) continue; + + + + + fail("Incorrect results for FloatBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for FloatBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b); diff --git a/jdk/test/java/nio/Buffer/BasicInt.java b/jdk/test/java/nio/Buffer/BasicInt.java index b20e4bb1056e0329298e6db753f50a71383d9b3c..478debd76e136f615dd3460ac7eeb15a11d605d1 100644 --- a/jdk/test/java/nio/Buffer/BasicInt.java +++ b/jdk/test/java/nio/Buffer/BasicInt.java @@ -38,6 +38,26 @@ public class BasicInt extends Basic { + private static final int[] VALUES = { + Integer.MIN_VALUE, + (int) -1, + (int) 0, + (int) 1, + Integer.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(IntBuffer b) { int n = b.capacity(); int v; @@ -308,6 +328,12 @@ public class BasicInt + + private static void fail(String problem, + IntBuffer xb, IntBuffer yb, + int x, int y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; @@ -522,6 +548,42 @@ public class BasicInt if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (int x : VALUES) { + IntBuffer xb = IntBuffer.wrap(new int[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (int y : VALUES) { + IntBuffer yb = IntBuffer.wrap(new int[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Integer.compare(x, y)) { + + + + + + + fail("Incorrect results for IntBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for IntBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b); diff --git a/jdk/test/java/nio/Buffer/BasicLong.java b/jdk/test/java/nio/Buffer/BasicLong.java index 0d4c568e1e3beeda4560291e88dbd665dd3127be..0abc7cdf2f42f4c70f743319ce329d61db6c6f77 100644 --- a/jdk/test/java/nio/Buffer/BasicLong.java +++ b/jdk/test/java/nio/Buffer/BasicLong.java @@ -38,6 +38,26 @@ public class BasicLong extends Basic { + private static final long[] VALUES = { + Long.MIN_VALUE, + (long) -1, + (long) 0, + (long) 1, + Long.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(LongBuffer b) { int n = b.capacity(); long v; @@ -308,6 +328,12 @@ public class BasicLong + + private static void fail(String problem, + LongBuffer xb, LongBuffer yb, + long x, long y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; @@ -522,6 +548,42 @@ public class BasicLong if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (long x : VALUES) { + LongBuffer xb = LongBuffer.wrap(new long[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (long y : VALUES) { + LongBuffer yb = LongBuffer.wrap(new long[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Long.compare(x, y)) { + + + + + + + fail("Incorrect results for LongBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for LongBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b); diff --git a/jdk/test/java/nio/Buffer/BasicShort.java b/jdk/test/java/nio/Buffer/BasicShort.java index 58e5a3e6d6851c3f758113cf8f3c12aea0833927..861d356b6df5fb4bb6d7afec0c85904601c51d15 100644 --- a/jdk/test/java/nio/Buffer/BasicShort.java +++ b/jdk/test/java/nio/Buffer/BasicShort.java @@ -38,6 +38,26 @@ public class BasicShort extends Basic { + private static final short[] VALUES = { + Short.MIN_VALUE, + (short) -1, + (short) 0, + (short) 1, + Short.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(ShortBuffer b) { int n = b.capacity(); short v; @@ -308,6 +328,12 @@ public class BasicShort + + private static void fail(String problem, + ShortBuffer xb, ShortBuffer yb, + short x, short y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; @@ -522,6 +548,42 @@ public class BasicShort if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (short x : VALUES) { + ShortBuffer xb = ShortBuffer.wrap(new short[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (short y : VALUES) { + ShortBuffer yb = ShortBuffer.wrap(new short[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Short.compare(x, y)) { + + + + + + + fail("Incorrect results for ShortBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for ShortBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b); diff --git a/jdk/test/java/nio/Buffer/genBasic.sh b/jdk/test/java/nio/Buffer/genBasic.sh index da5fca5df33e7776f35008177ddfa1cdda53890f..009cf2dbb1b8c2ca7b83697b34e44530b09444b0 100644 --- a/jdk/test/java/nio/Buffer/genBasic.sh +++ b/jdk/test/java/nio/Buffer/genBasic.sh @@ -36,5 +36,3 @@ gen int Int Integer gen long Long Long gen float Float Float gen double Double Double - -rm -rf build diff --git a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java index 13881966d327b267dc6582776867ef348ecfdf52..1ed649cd83ad7afc3a474d62e5286612cb543498 100644 --- a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java +++ b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java @@ -23,7 +23,7 @@ /** * @test - * @bug 4635230 6283345 6303830 6824440 + * @bug 4635230 6283345 6303830 6824440 6867348 * @summary Basic unit tests for generating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java GenerationTests.java @@ -126,13 +126,14 @@ public class GenerationTests { test_create_signature_x509_is(); test_create_signature_x509_ski(); test_create_signature_x509_sn(); -// test_create_signature(); + test_create_signature(); test_create_exc_signature(); test_create_sign_spec(); test_create_signature_enveloping_sha256_dsa(); test_create_signature_enveloping_sha384_rsa_sha256(); test_create_signature_enveloping_sha512_rsa_sha384(); test_create_signature_enveloping_sha512_rsa_sha512(); + test_create_signature_reference_dependency(); } private static void setup() throws Exception { @@ -410,6 +411,55 @@ public class GenerationTests { System.out.println(); } + static void test_create_signature_reference_dependency() throws Exception { + System.out.println("* Generating signature-reference-dependency.xml"); + // create references + List refs = Collections.singletonList + (fac.newReference("#object-1", sha1)); + + // create SignedInfo + SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha1, refs); + + // create objects + List objs = new ArrayList(); + + // Object 1 + List manRefs = Collections.singletonList + (fac.newReference("#object-2", sha1)); + objs.add(fac.newXMLObject(Collections.singletonList + (fac.newManifest(manRefs, "manifest-1")), "object-1", null, null)); + + // Object 2 + Document doc = db.newDocument(); + Element nc = doc.createElementNS(null, "NonCommentandus"); + nc.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", ""); + nc.appendChild(doc.createComment(" Commentandum ")); + objs.add(fac.newXMLObject(Collections.singletonList + (new DOMStructure(nc)), "object-2", null, null)); + + // create XMLSignature + XMLSignature sig = fac.newXMLSignature(si, rsa, objs, "signature", null); + DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc); + + sig.sign(dsc); + +// dumpDocument(doc, new PrintWriter(System.out)); + + DOMValidateContext dvc = new DOMValidateContext + (kvks, doc.getDocumentElement()); + XMLSignature sig2 = fac.unmarshalXMLSignature(dvc); + + if (sig.equals(sig2) == false) { + throw new Exception + ("Unmarshalled signature is not equal to generated signature"); + } + if (sig2.validate(dvc) == false) { + throw new Exception("Validation of generated signature failed"); + } + + System.out.println(); + } + static void test_create_signature() throws Exception { System.out.println("* Generating signature.xml"); @@ -645,6 +695,7 @@ public class GenerationTests { envDoc.getElementsByTagName("YoursSincerely").item(0); DOMSignContext dsc = new DOMSignContext(signingKey, ys); + dsc.setURIDereferencer(httpUd); sig.sign(dsc); @@ -660,6 +711,7 @@ public class GenerationTests { DOMValidateContext dvc = new DOMValidateContext (new X509KeySelector(ks), sigElement); + dvc.setURIDereferencer(httpUd); File f = new File( System.getProperty("dir.test.vector.baltimore") + System.getProperty("file.separator") + diff --git a/jdk/test/sun/security/util/Oid/S11N.sh b/jdk/test/sun/security/util/Oid/S11N.sh index 081cd52298fc315e08e358b5c4994fc456b9c3d2..82046f360c0520a21bf312d2c389b06de96218ab 100644 --- a/jdk/test/sun/security/util/Oid/S11N.sh +++ b/jdk/test/sun/security/util/Oid/S11N.sh @@ -1,5 +1,5 @@ # -# Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2004-2009 Sun Microsystems, Inc. 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 @@ -21,8 +21,8 @@ # have any questions. # # @test -# @bug 4811968 -# @summary Serialization compatibility with old versions +# @bug 4811968 6908628 +# @summary Serialization compatibility with old versions (and fix) # @author Weijun Wang # # set a few environment variables so that the shell-script can run stand-alone @@ -99,7 +99,8 @@ esac # the test code -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}SerialTest.java || exit 10 +${TESTJAVA}${FS}bin${FS}javac -target 1.4 -source 1.4 \ + -d . ${TESTSRC}${FS}SerialTest.java || exit 10 OLDJAVA=" /java/re/j2se/1.6.0/latest/binaries/${PF} @@ -161,4 +162,10 @@ rm -f tmp.oid.serial rm -f tmp.oid.serial.old rm -f SerialTest.class +for oldj in ${OLDJAVA}; do + if [ ! -d ${oldj} ]; then + echo WARNING: ${oldj} is missing. Test incomplete! > /dev/stderr + fi +done + exit 0 diff --git a/jdk/test/sun/tools/jhat/HatRun.java b/jdk/test/sun/tools/jhat/HatRun.java index cb1e41b248ec5903ce921060f6e3217f6be0b85d..6d736f83193e3c97f8aedef48e76129cfcabc994 100644 --- a/jdk/test/sun/tools/jhat/HatRun.java +++ b/jdk/test/sun/tools/jhat/HatRun.java @@ -166,8 +166,10 @@ public class HatRun { jre_home ); String cdir = System.getProperty("test.classes", "."); String os_arch = System.getProperty("os.arch"); - boolean d64 = os_arch.equals("sparcv9") || - os_arch.equals("amd64"); + String os_name = System.getProperty("os.name"); + boolean d64 = os_name.equals("SunOS") && ( + os_arch.equals("sparcv9") || + os_arch.equals("amd64")); String isa_dir = d64?(File.separator+os_arch):""; String java = jre_home + File.separator + "bin" + isa_dir