提交 05725320 编写于 作者: M mchung

7026228: Remove make/modules and make/common/Modules.gmk

Reviewed-by: alanb, ohair
上级 ccb1b042
#
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
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. META-INF/services file is not installed.
# 2. Signed jars
# For JDK build, signed jars are copied to the build.
# All jars in the module image are unsigned.
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:: gen-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_DOCFILES = $(IMAGE_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%)
JRE_MODULE_DOCFILES = $(IMAGE_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%)
###### RULES
# JDK files
$(JDK_MODULE_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%
$(process-doc-file)
# JRE files
$(JRE_MODULE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%
$(process-doc-file)
ifeq ($(PLATFORM), windows)
$(JRE_MODULE_IMAGE_DIR)/README.txt: $(SHARE_JRE_DOC_SRC)/README
$(process-doc-file)
endif
######################################################
# JRE Image
######################################################
MODULES_LIST = $(MODULES_TEMPDIR)/classlist/modules.list
# Modules in the jre/lib/security directory
POLICY_MODULES = US_export_policy local_policy
# Modules in the modules/ext directory
EXT_MODULES = localedata security-sunec security-sunjce
# Build PKCS#11 on all platforms except 64-bit Windows.
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
# Modules for JDK only
JDK_MODULES = tools
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
@# 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_MODULE_DOCFILES) \
$(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
@#
for m in `$(NAWK) '{print $$1}' $(MODULES_LIST)` ; do \
$(CP) $(MODULES_DIR)/$$m/lib/$$m.jar $(JRE_MODULE_IMAGE_DIR)/lib ; \
done
$(MKDIR) -p $(JRE_MODULE_IMAGE_DIR)/lib/ext
for m in $(EXT_MODULES) ; do \
$(MV) $(JRE_MODULE_IMAGE_DIR)/lib/$$m.jar $(JRE_MODULE_IMAGE_DIR)/lib/ext ; \
done
for m in $(POLICY_MODULES) ; do \
$(MV) $(JRE_MODULE_IMAGE_DIR)/lib/$$m.jar $(JRE_MODULE_IMAGE_DIR)/lib/security; \
done
@# Remove jdk modules
for m in $(JDK_MODULES) ; do \
$(RM) $(JRE_MODULE_IMAGE_DIR)/lib/$$m.jar ; \
done
@# 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) \
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
# 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_DOCFILES)
$(MKDIR) $(JDK_MODULE_IMAGE_DIR)/lib
@#
@# copy jdk modules to jdk/lib
@#
$(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/lib
for m in $(JDK_MODULES) ; do \
$(CP) $(MODULES_DIR)/$$m/lib/$$m.jar $(JDK_MODULE_IMAGE_DIR)/lib ; \
done
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 ($(COMPILER_VERSION), VS2010)
$(CP) $(BINDIR)/msvc*100.$(LIBRARY_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/bin
endif
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); \
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:
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
BUILDDIR = ../../..
MODULE = management
PACKAGE = java.nio
PRODUCT = java
include $(BUILDDIR)/common/Defs.gmk
FILES_java = java/nio/BufferPoolMXBean.java
include $(BUILDDIR)/common/Classes.gmk
#
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
BUILDDIR = ..
include $(BUILDDIR)/common/Defs.gmk
#
# Modularizing the JDK
# - Post jdk build process until the source tree is restructured
# for modules build
# - <outputdir>/modules/<module> will be created for each module.
#
# Steps:
# 0. During jdk build before this makefile is invoked, classes,
# resource files, and other non-class files such as native libraries,
# properties file, images, etc are created.
#
# Non-class files are copied to <outputdir>/tmp/modules/<MODULE>
# directory in this step to prepare for the post-build modularization.
#
# The MODULE variable defined in other makefiles specifies
# the lowest-level module that the non-class files belong to.
# The name might or might not be the same as the name of the modules
# in the resulting <outputdir>/modules directory.
#
# 1. Unpack all jars in the <builddir>/lib directory to a temporary
# location (<outputdir>/tmp/modules/classes) to prepare for modules
# creation.
#
# 2. Run ClassAnalyzer tool to analyze all jdk classes and generate
# class list for all modules and also perform dependency analysis.
#
# Input configuration files :-
#
# modules.config : defines the low-level modules and specifies
# what classes and resource files each module includes.
# modules.group : defines the module groups and its members.
# jdk7.depconfig : lists the dynamic dependencies including
# use of reflection Class.forName and JNI FindClass and
# service provider.
# optional.depconfig : lists the optional dependencies
#
# 3. Create one directory for each module (<outputdir>/modules/<module>)
# based on the output files from (2).
#
# modules.list lists the modules to be created for the modules
# build and its members. For each module (m) in modules.list,
# a. create $m/lib/$m.jar with all classes and resource files
# listed in $m.classlist and $m.resources respectively.
# b. copy all non-class files from its members to
# <outputdir>/modules/$m.
MAINMANIFEST=$(JDK_TOPDIR)/make/tools/manifest.mf
MODULE_JAR_MANIFEST_FILE=$(ABS_TEMPDIR)/manifest.tmp
TMP = $(ABS_MODULES_TEMPDIR)
MODULE_CLASSLIST = $(ABS_MODULES_TEMPDIR)/classlist
MODULE_CLASSES = $(ABS_MODULES_TEMPDIR)/classes
MODULES_LIST = $(MODULE_CLASSLIST)/modules.list
all:: unpack-jars gen-classlist modularize
JAR_LIST := $(shell $(FIND) $(ABS_OUTPUTDIR)/lib -name \*.jar -print)
unpack-jars:
@$(ECHO) ">>>Making "$@" @ `$(DATE)` ..."
$(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
@$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..."
gen-classlist:
$(CD) tools && $(MAKE) all
modularize: $(MODULE_JAR_MANIFEST_FILE)
@$(ECHO) ">>>Making "$@" @ `$(DATE)` ..."
@$(RM) -rf $(MODULES_DIR)
@# create jar file for modules and
@# copy other files from all members of this module
for m in `$(NAWK) '{print $$1}' $(MODULES_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 ; \
$(MKDIR) -p $(ABS_MODULES_DIR)/$$m/lib; \
$(CD) $(MODULE_CLASSES) && \
$(BOOT_JAR_CMD) c0mf $(MODULE_JAR_MANIFEST_FILE) \
$(ABS_MODULES_DIR)/$$m/lib/$$m.jar \
@$(TMP)/tmp.cf \
$(BOOT_JAR_JFLAGS); \
for s in `$(GREP) "^$$m" $(MODULES_LIST)` ; do \
if [ -d $(TMP)/$$s ] ; then \
$(CP) -rf $(TMP)/$$s/* $(ABS_MODULES_DIR)/$$m; \
$(RM) -rf $(ABS_MODULES_DIR)/$$m/classes; \
fi \
done \
done
@$(CD) $(MODULE_CLASSES) && $(java-vm-cleanup)
@$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..."
$(MODULE_JAR_MANIFEST_FILE):
$(SED) -e "s/@@RELEASE@@/$(RELEASE)/" $(MAINMANIFEST) > $@
clean clobber::
$(RM) -rf $(MODULE_CLASSLIST)
$(RM) -rf $(MODULES_DIR)
$(RM) $(MODULE_JAR_MANIFEST_FILE)
#
# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# List of root classes/methods, each line of the following syntax:
# <class name>
# <method name> <signature>|*
# exclude <class>|<method>
# 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.<init> ()V
sun.net.www.protocol.jar.Handler.<init> ()V
sun.net.www.protocol.file.Handler.openConnection *
sun.net.www.protocol.jar.Handler.openConnection *
sun.misc.URLClassPath$JarLoader.<init> (Ljava/net/URL;Ljava/net/URLStreamHandler;Ljava/util/HashMap;)V
sun.misc.URLClassPath$FileLoader.<init> (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.<init> ()V
java.io.UnixFileSystem.canonicalize *
java.io.Win32FileSystem
java.io.Win32FileSystem.<init> ()V
java.io.Win32FileSystem.canonicalize *
java.io.WinNTFileSystem
java.io.WinNTFileSystem.<init> ()V
java.io.WinNTFileSystem.canonicalize *
# missing
java.util.HashMap.<init> ()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 <init>
java.security.SecureClassLoader.<init> ()V
exclude sun.security.provider.PolicyFile.<init>
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.<init>
# 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
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Example:
* module jdbc {
* include jdbc-base, jdbc-enterprise, jdbc-odbc;
* }
*/
#
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# 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
#
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building the classanalyzer tool
#
BUILDDIR = ../..
include $(BUILDDIR)/common/Defs.gmk
PKGDIR = com/sun/classanalyzer
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)/classanalyzer_manifest.mf
FILES_java := $(shell $(CD) $(BUILDTOOL_SOURCE_ROOT) \
&& $(FIND) $(PKGDIR) -type f -print)
FILES_class = $(FILES_java:%.java=$(BUILDTOOLCLASSDIR)/%.class)
CLASSANALYZER_JAR_FILE = $(BUILDTOOLJARDIR)/classanalyzer.jar
#
# ClassAnalyzer depends on the com.sun.tools.classfile API.
# The tool is compiled with the latest version of the classfile
# library in the langtools repo to make sure that synchronized
# change is made if the classfile API is changed.
#
# If langtools repo exists, build its own copy of the
# classfile library and use it for compile time and runtime.
# If not exist (the top level repo is not a forest), use
# the built jdk tools that imports tools.jar from the latest
# promoted build.
#
# If the classfile API is changed but not yet in a promoted build,
# the build might fail and the tool would need the langtools repo
# to build in that case.
#
ifndef LANGTOOLS_TOPDIR
LANGTOOLS_TOPDIR=$(JDK_TOPDIR)/../langtools
endif
LANGTOOLS_TOPDIR_EXISTS := $(shell \
if [ -d $(LANGTOOLS_TOPDIR) ] ; then \
echo true; \
else \
echo false; \
fi)
CLASSFILE_SRC = $(LANGTOOLS_TOPDIR)/src/share/classes
CLASSFILE_PKGDIR = com/sun/tools/classfile
ifeq ($(LANGTOOLS_TOPDIR_EXISTS), true)
FILES_classfile_java := $(shell \
$(CD) $(CLASSFILE_SRC) && \
$(FIND) $(CLASSFILE_PKGDIR) -name '*.java' -print)
FILES_classfile_class = $(FILES_classfile_java:%.java=$(BUILDTOOLCLASSDIR)/%.class)
CLASSFILE_JAR_FILE = $(BUILDTOOLJARDIR)/classfile.jar
BUILDTOOL_JAVAC = $(BOOT_JAVAC_CMD) $(JAVAC_JVM_FLAGS) \
$(BOOT_JAVACFLAGS) -classpath $(CLASSFILE_JAR_FILE)
BUILDTOOL_JAVA = $(BOOT_JAVA_CMD) $(JAVA_TOOLS_FLAGS) \
-Xbootclasspath/p:$(CLASSFILE_JAR_FILE)
else
# if langtools doesn't exist, use tools from the built jdk
BUILDTOOL_JAVAC = $(BINDIR)/javac $(JAVAC_JVM_FLAGS) \
$(BOOT_JAVACFLAGS)
BUILDTOOL_JAVA = $(BINDIR)/java $(JAVA_TOOLS_FLAGS)
endif
# Location of the output modules.list, <module>.classlist
# and other output files generated by the class analyzer tool.
#
MODULE_CLASSLIST = $(MODULES_TEMPDIR)/classlist
all build: classanalyzer gen-classlist
classanalyzer: $(CLASSFILE_JAR_FILE) $(CLASSANALYZER_JAR_FILE)
gen-classlist:
@$(ECHO) ">>>Making "$@" @ `$(DATE)` ..."
@$(RM) -rf $(MODULE_CLASSLIST)
@$(MKDIR) -p $(MODULE_CLASSLIST)
$(BUILDTOOL_JAVA) \
-Dclassanalyzer.debug \
-jar $(CLASSANALYZER_JAR_FILE) \
-jdkhome $(OUTPUTDIR) \
-config ../modules.config \
-config ../modules.group \
-depconfig ../jdk7.depconfig \
-depconfig ../optional.depconfig \
-showdynamic \
-output $(MODULE_CLASSLIST)
@$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..."
$(BUILDTOOL_MANIFEST_FILE): $(BUILDTOOL_MAIN_SOURCE_FILE)
@$(prep-target)
$(ECHO) "Main-Class: $(BUILTTOOL_MAINCLASS)" > $@
$(BUILDTOOLCLASSDIR)/$(CLASSFILE_PKGDIR)/%.class : $(CLASSFILE_SRC)/$(CLASSFILE_PKGDIR)/%.java
@$(prep-target)
@$(BUILDTOOL_JAVAC) \
-sourcepath $(CLASSFILE_SRC) \
-d $(BUILDTOOLCLASSDIR) $<
$(BUILDTOOLCLASSDIR)/%.class : $(BUILDTOOL_SOURCE_ROOT)/%.java
@$(prep-target)
$(BUILDTOOL_JAVAC) \
-sourcepath $(BUILDTOOL_SOURCE_ROOT) \
-d $(BUILDTOOLCLASSDIR) $<
$(CLASSANALYZER_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)
$(BUILDTOOLJARDIR)/classfile.jar: $(FILES_classfile_class)
@$(prep-target)
$(CD) $(BUILDTOOLCLASSDIR) && \
$(BOOT_JAR_CMD) cf $@ \
$(CLASSFILE_PKGDIR) $(BOOT_JAR_JFLAGS) || $(RM) $@
@$(java-vm-cleanup)
clean clobber::
@$(RM) -rf $(BUILDTOOLCLASSDIR)/$(PKGDIR)
@$(RM) -rf $(BUILDTOOLCLASSDIR)/$(CLASSFILE_PKGDIR)
@$(RM) $(BUILDTOOL_MANIFEST_FILE)
@$(RM) $(CLASSANALYZER_JAR_FILE)
@$(RM) $(CLASSFILE_JAR_FILE)
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation. Oracle designates this
particular file as subject to the "Classpath" exception as provided
by Oracle in the LICENSE file that accompanied this code.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<project name="classanalyzer" default="build" basedir=".">
</project>
#
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
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}
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation. Oracle designates this
particular file as subject to the "Classpath" exception as provided
by Oracle in the LICENSE file that accompanied this code.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>classanalyzer</name>
<explicit-platform explicit-source-supported="true"/>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots/>
</data>
</configuration>
</project>
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.classanalyzer;
import com.sun.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<String> value;
Element(String name) {
this.name = name;
this.value = new ArrayList<String>();
}
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<Void, Element> {
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<String, Set<Klass.Method>> 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 <options>");
System.out.println("Options: ");
System.out.println("\t-jdkhome <JDK home> where all jars will be parsed");
System.out.println("\t-depconfig <output file for annotated dependencies>");
System.out.println("\t-optional <output file for optional dependencies>");
System.exit(-1);
}
}
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.classanalyzer;
import java.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<String,List<DependencyTail>> expected =
new HashMap<String,List<DependencyTail>>();
// 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<DependencyTail> list = expected.get(module);
if (list == null) {
list = new ArrayList<DependencyTail>();
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<DependencyTail> 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");
}
}
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.classanalyzer;
import com.sun.classanalyzer.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<String> configs = new ArrayList<String>();
List<String> depconfigs = new ArrayList<String>();
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<Module> modules = new ArrayList<Module>();
static void buildModules(List<String> configs,
List<String> 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<String, Set<Module>> packages = new TreeMap<String, Set<Module>>();
Set<String> splitPackages = new TreeSet<String>();
for (Module m : modules) {
if (m.group() == m) {
for (PackageInfo info : m.getPackageInfos()) {
Set<Module> value = packages.get(info.pkgName);
if (value == null) {
value = new TreeSet<Module>();
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 <options>");
System.out.println("Options: ");
System.out.println("\t-jdkhome <JDK home> where all jars will be parsed");
System.out.println("\t-cpath <classpath> where classes and jars will be parsed");
System.out.println("\t Either -jdkhome or -cpath option can be used.");
System.out.println("\t-config <module config file>");
System.out.println("\t This option can be repeated for multiple module config files");
System.out.println("\t-output <output dir>");
System.out.println("\t-nomerge specify not to merge modules");
System.out.println("\t-showdynamic show dynamic dependencies in the reports");
System.exit(-1);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册