Merge
This commit is contained in:
commit
3ceaec158c
@ -1 +1,2 @@
|
||||
37a05a11f281b4d238e2f9e7ebb67c63f64d0e77 jdk7-b24
|
||||
75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2007-2008 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
|
||||
@ -87,8 +87,7 @@
|
||||
# sign Alias for sign-jar
|
||||
# sign-jar Builds/signs sunjce_provider.jar (no install)
|
||||
#
|
||||
# obfus Builds/obfuscates/signs/installs
|
||||
# sunjce_provider.jar
|
||||
# obfus Builds/obfuscates/signs sunjce_provider.jar
|
||||
#
|
||||
# release Builds all targets in preparation
|
||||
# for workspace integration.
|
||||
@ -101,8 +100,25 @@
|
||||
BUILDDIR = ../../../..
|
||||
PACKAGE = com.sun.crypto.provider
|
||||
PRODUCT = sun
|
||||
|
||||
#
|
||||
# The following is for when we need to do postprocessing
|
||||
# (signing/obfuscation) against a read-only build. If the OUTPUTDIR
|
||||
# isn't writable, the build currently crashes out.
|
||||
#
|
||||
ifndef OPENJDK
|
||||
ifdef ALT_JCE_BUILD_DIR
|
||||
# =====================================================
|
||||
# Where to place the output, in case we're building from a read-only
|
||||
# build area. (e.g. a release engineering build.)
|
||||
JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
|
||||
IGNORE_WRITABLE_OUTPUTDIR_TEST=true
|
||||
else
|
||||
JCE_BUILD_DIR=${TEMPDIR}
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
|
||||
|
||||
#
|
||||
# Location for the newly built classfiles.
|
||||
@ -147,6 +163,8 @@ endif # OPENJDK
|
||||
#
|
||||
UNSIGNED_DIR = $(TEMPDIR)/unsigned
|
||||
|
||||
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
|
||||
|
||||
|
||||
# =====================================================
|
||||
# Build the unsigned sunjce_provider.jar file.
|
||||
@ -184,44 +202,66 @@ ifndef OPENJDK
|
||||
# Sign the provider jar file. Not needed for OpenJDK.
|
||||
#
|
||||
|
||||
SIGNED_DIR = $(TEMPDIR)/signed
|
||||
SIGNED_DIR = $(JCE_BUILD_DIR)/signed
|
||||
|
||||
sign: sign-jar
|
||||
|
||||
sign-jar: $(SIGNED_DIR)/sunjce_provider.jar
|
||||
|
||||
ifndef ALT_JCE_BUILD_DIR
|
||||
$(SIGNED_DIR)/sunjce_provider.jar: $(UNSIGNED_DIR)/sunjce_provider.jar
|
||||
$(sign-file)
|
||||
else
|
||||
#
|
||||
# We have to remove the build dependency, otherwise, we'll try to rebuild it
|
||||
# which we can't do on a read-only filesystem.
|
||||
#
|
||||
$(SIGNED_DIR)/sunjce_provider.jar:
|
||||
@if [ ! -r $(UNSIGNED_DIR)/sunjce_provider.jar ] ; then \
|
||||
$(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunjce_provider.jar"; \
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
$(call sign-file, $(UNSIGNED_DIR)/sunjce_provider.jar)
|
||||
|
||||
# =====================================================
|
||||
# Obfuscate/sign/install the JDK build. Not needed for OpenJDK.
|
||||
#
|
||||
|
||||
OBFUS_DIR = $(TEMPDIR)/obfus
|
||||
OBFUS_DIR = $(JCE_BUILD_DIR)/obfus/sunjce
|
||||
|
||||
CLOSED_DIR = $(BUILDDIR)/closed/com/sun/crypto/provider
|
||||
|
||||
obfus: $(OBFUS_DIR)/sunjce_provider.jar
|
||||
$(release-warning)
|
||||
|
||||
$(OBFUS_DIR)/sunjce_provider.jar: build-jar $(JCE_MANIFEST_FILE)
|
||||
ifndef ALT_JCE_BUILD_DIR
|
||||
$(OBFUS_DIR)/sunjce_provider.jar: build-jar $(JCE_MANIFEST_FILE) \
|
||||
$(OBFUS_DIR)/sunjce.dox
|
||||
else
|
||||
$(OBFUS_DIR)/sunjce_provider.jar: $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/sunjce.dox
|
||||
@if [ ! -d $(CLASSDESTDIR) ] ; then \
|
||||
$(ECHO) "Couldn't find $(CLASSDESTDIR)"; \
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
@$(ECHO) ">>>Obfuscating SunJCE Provider..."
|
||||
$(presign)
|
||||
$(preobfus)
|
||||
@$(ECHO) ">>>Obfuscating Sun JCE Provider..."
|
||||
$(prep-target)
|
||||
$(CD) $(OBFUS_DIR); \
|
||||
$(OBFUSCATOR) -fv \
|
||||
$(CURRENT_DIRECTORY)/$(CLOSED_DIR)/obfus/sunjce.dox
|
||||
$(OBFUSCATOR) -fv sunjce.dox
|
||||
@$(CD) $(OBFUS_DIR); $(java-vm-cleanup)
|
||||
$(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \
|
||||
-C $(OBFUS_DIR)/build com \
|
||||
$(JAR_JFLAGS)
|
||||
$(sign-target)
|
||||
$(MKDIR) -p $(dir $(JAR_DESTFILE))
|
||||
$(RM) $(JAR_DESTFILE)
|
||||
$(CP) $@ $(JAR_DESTFILE)
|
||||
@$(java-vm-cleanup)
|
||||
|
||||
$(OBFUS_DIR)/sunjce.dox: $(CLOSED_DIR)/obfus/sunjce.dox
|
||||
@$(ECHO) ">>>Creating sunjce.dox"
|
||||
$(prep-target)
|
||||
$(SED) "s:@@TEMPDIR@@:$(ABS_TEMPDIR):" $< > $@
|
||||
|
||||
#
|
||||
# The current obfuscator has a limitation in that it currently only
|
||||
# supports up to v49 class file format. Force v49 classfiles in our
|
||||
@ -235,9 +275,9 @@ TARGET_CLASS_VERSION = 5
|
||||
#
|
||||
|
||||
release: $(OBFUS_DIR)/sunjce_provider.jar
|
||||
$(RM) $(RELEASE_DIR)/sunjce_provider.jar
|
||||
$(MKDIR) -p $(RELEASE_DIR)
|
||||
$(CP) $(OBFUS_DIR)/sunjce_provider.jar $(RELEASE_DIR)
|
||||
$(RM) $(JCE_BUILD_DIR)/release/sunjce_provider.jar
|
||||
$(MKDIR) -p $(JCE_BUILD_DIR)/release
|
||||
$(CP) $(OBFUS_DIR)/sunjce_provider.jar $(JCE_BUILD_DIR)/release
|
||||
$(release-warning)
|
||||
|
||||
endif # OPENJDK
|
||||
@ -275,7 +315,7 @@ endif
|
||||
#
|
||||
|
||||
clobber clean::
|
||||
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR)
|
||||
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
|
||||
|
||||
.PHONY: build-jar jar install-jar
|
||||
ifndef OPENJDK
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2005-2008 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
|
||||
@ -451,11 +451,20 @@ endif
|
||||
# Check for spaces and null value
|
||||
OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR)
|
||||
OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR)
|
||||
|
||||
#
|
||||
# When signing the JCE framework and provider, we could be using built
|
||||
# bits on a read-only filesystem. If so, this test will fail and crash
|
||||
# the build.
|
||||
#
|
||||
ifndef IGNORE_WRITABLE_OUTPUTDIR_TEST
|
||||
# Create the output directory and make sure it exists and is writable
|
||||
_create_outputdir:=$(shell $(MKDIR) -p "$(OUTPUTDIR)" > $(DEV_NULL) 2>&1)
|
||||
ifeq ($(call WriteDirExists,$(OUTPUTDIR),/dev/null),/dev/null)
|
||||
_outputdir_error:=$(error "ERROR: OUTPUTDIR '$(OUTPUTDIR)' not created or not writable")
|
||||
endif
|
||||
endif
|
||||
|
||||
# Define absolute path if needed and check for spaces and null value
|
||||
ifndef ABS_OUTPUTDIR
|
||||
ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR))
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2007-2008 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
|
||||
@ -31,7 +31,7 @@ include $(BUILDDIR)/common/Release.gmk
|
||||
JCE_MANIFEST_FILE = $(TEMPDIR)/manifest.mf
|
||||
$(JCE_MANIFEST_FILE): $(MAINMANIFEST)
|
||||
$(prep-target)
|
||||
( $(SED) "s/@@RELEASE@@/$(RELEASE)/" $(MAINMANIFEST); \
|
||||
( $(SED) "s/@@RELEASE@@/$(RELEASE)/" $<; \
|
||||
$(ECHO) "Extension-Name: javax.crypto"; \
|
||||
$(ECHO) "Implementation-Vendor-Id: com.sun"; ) > $@
|
||||
|
||||
@ -75,6 +75,7 @@ endef
|
||||
define sign-target
|
||||
$(BOOT_JARSIGNER_CMD) -keystore $(SIGNING_KEYSTORE) \
|
||||
$@ $(SIGNING_ALIAS) < $(SIGNING_PASSPHRASE)
|
||||
@$(java-vm-cleanup)
|
||||
@$(ECHO) "\nJar codesigning finished."
|
||||
endef
|
||||
|
||||
@ -88,13 +89,15 @@ define release-warning
|
||||
endef
|
||||
|
||||
#
|
||||
# Convenience macro for steps needed to sign a jar file.
|
||||
# Convenience macros for signing a jar file.
|
||||
#
|
||||
# Call through $(call sign-file, target file)
|
||||
#
|
||||
define sign-file
|
||||
$(presign)
|
||||
$(install-file)
|
||||
$(prep-target)
|
||||
$(CP) $1 $@
|
||||
$(sign-target)
|
||||
@$(java-vm-cleanup)
|
||||
endef
|
||||
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2007-2008 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
|
||||
@ -96,7 +96,7 @@
|
||||
# sign-jar Builds/signs jce.jar file (no install)
|
||||
# sign-policy Builds/signs policy files (no install)
|
||||
#
|
||||
# obfus Builds/obfuscates/signs/installs jce.jar
|
||||
# obfus Builds/obfuscates/signs jce.jar
|
||||
#
|
||||
# release Builds all targets in preparation
|
||||
# for workspace integration.
|
||||
@ -110,8 +110,24 @@ BUILDDIR = ../..
|
||||
PACKAGE = javax.crypto
|
||||
PRODUCT = sun
|
||||
|
||||
#
|
||||
# The following is for when we need to do postprocessing
|
||||
# (signing/obfuscation) against a read-only build. If the OUTPUTDIR
|
||||
# isn't writable, the build currently crashes out.
|
||||
#
|
||||
ifndef OPENJDK
|
||||
ifdef ALT_JCE_BUILD_DIR
|
||||
# =====================================================
|
||||
# Where to place the output, in case we're building from a read-only
|
||||
# build area. (e.g. a release engineering build.)
|
||||
JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
|
||||
IGNORE_WRITABLE_OUTPUTDIR_TEST=true
|
||||
else
|
||||
JCE_BUILD_DIR=${TEMPDIR}
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
include Defs-jce.gmk
|
||||
|
||||
#
|
||||
# Location for the newly built classfiles.
|
||||
@ -158,6 +174,8 @@ endif # OPENJDK
|
||||
#
|
||||
UNSIGNED_DIR = $(TEMPDIR)/unsigned
|
||||
|
||||
include Defs-jce.gmk
|
||||
|
||||
|
||||
# =====================================================
|
||||
# Build the unsigned jce.jar file. Signing/obfuscation comes later.
|
||||
@ -299,7 +317,7 @@ ifndef OPENJDK
|
||||
# Sign the various jar files. Not needed for OpenJDK.
|
||||
#
|
||||
|
||||
SIGNED_DIR = $(TEMPDIR)/signed
|
||||
SIGNED_DIR = $(JCE_BUILD_DIR)/signed
|
||||
SIGNED_POLICY_BUILDDIR = $(SIGNED_DIR)/policy
|
||||
|
||||
SIGNED_POLICY_FILES = \
|
||||
@ -312,61 +330,87 @@ sign-jar: $(SIGNED_DIR)/jce.jar
|
||||
|
||||
sign-policy: $(SIGNED_POLICY_FILES)
|
||||
|
||||
ifndef ALT_JCE_BUILD_DIR
|
||||
$(SIGNED_DIR)/jce.jar: $(UNSIGNED_DIR)/jce.jar
|
||||
$(sign-file)
|
||||
else
|
||||
#
|
||||
# We have to remove the build dependency, otherwise, we'll try to rebuild it
|
||||
# which we can't do on a read-only filesystem.
|
||||
#
|
||||
$(SIGNED_DIR)/jce.jar:
|
||||
@if [ ! -r $(UNSIGNED_DIR)/jce.jar ] ; then \
|
||||
$(ECHO) "Couldn't find $(UNSIGNED_DIR)/jce.jar"; \
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
$(call sign-file, $(UNSIGNED_DIR)/jce.jar)
|
||||
|
||||
$(SIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar: \
|
||||
$(UNSIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar
|
||||
$(sign-file)
|
||||
$(UNSIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar
|
||||
$(call sign-file, $<)
|
||||
|
||||
$(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar: \
|
||||
$(UNSIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar
|
||||
$(sign-file)
|
||||
$(UNSIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar
|
||||
$(call sign-file, $<)
|
||||
|
||||
$(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar: \
|
||||
$(UNSIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar
|
||||
$(sign-file)
|
||||
$(UNSIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar
|
||||
$(call sign-file, $<)
|
||||
|
||||
$(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar: \
|
||||
$(UNSIGNED_POLICY_BUILDDIR)/limited/local_policy.jar
|
||||
$(sign-file)
|
||||
$(UNSIGNED_POLICY_BUILDDIR)/limited/local_policy.jar
|
||||
$(call sign-file, $<)
|
||||
|
||||
|
||||
# =====================================================
|
||||
# Obfuscate/sign/install the JDK build. Not needed for OpenJDK.
|
||||
#
|
||||
|
||||
OBFUS_DIR = $(TEMPDIR)/obfus
|
||||
OBFUS_DIR = $(JCE_BUILD_DIR)/obfus/jce
|
||||
|
||||
CLOSED_DIR = $(BUILDDIR)/closed/javax/crypto
|
||||
|
||||
obfus: $(OBFUS_DIR)/jce.jar
|
||||
$(release-warning)
|
||||
|
||||
$(OBFUS_DIR)/jce.jar: build-jar $(JCE_MANIFEST_FILE)
|
||||
ifndef ALT_JCE_BUILD_DIR
|
||||
$(OBFUS_DIR)/jce.jar: build-jar $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/framework.dox
|
||||
else
|
||||
#
|
||||
# We have to remove the build dependency, otherwise, we'll try to rebuild it
|
||||
# which we can't do on a read-only filesystem.
|
||||
#
|
||||
$(OBFUS_DIR)/jce.jar: $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/framework.dox
|
||||
@if [ ! -d $(CLASSDESTDIR) ] ; then \
|
||||
$(ECHO) "Couldn't find $(CLASSDESTDIR)"; \
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
@$(ECHO) ">>>Obfuscating JCE framework..."
|
||||
$(presign)
|
||||
$(preobfus)
|
||||
@$(ECHO) ">>>Obfuscating JCE framework..."
|
||||
$(prep-target)
|
||||
$(CD) $(OBFUS_DIR); \
|
||||
$(OBFUSCATOR) -fv \
|
||||
$(CURRENT_DIRECTORY)/$(CLOSED_DIR)/obfus/framework.dox
|
||||
$(OBFUSCATOR) -fv framework.dox
|
||||
@$(CD) $(OBFUS_DIR); $(java-vm-cleanup)
|
||||
@#
|
||||
@# The sun.security.internal classes are currently not obfuscated
|
||||
@# due to an obfus problem. Manually copy them to the build directory
|
||||
@# so that they are included in the jce.jar file.
|
||||
@#
|
||||
$(CP) -r $(CLASSDESTDIR)/sun $(OBFUS_DIR)/build
|
||||
$(RM) $(UNSIGNED_DIR)/jce.jar
|
||||
$(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \
|
||||
-C $(OBFUS_DIR)/build javax \
|
||||
-C $(OBFUS_DIR)/build sun \
|
||||
$(JAR_JFLAGS)
|
||||
$(sign-target)
|
||||
$(MKDIR) -p $(dir $(JAR_DESTFILE))
|
||||
$(RM) $(JAR_DESTFILE)
|
||||
$(CP) $@ $(JAR_DESTFILE)
|
||||
@$(java-vm-cleanup)
|
||||
|
||||
$(OBFUS_DIR)/framework.dox: $(CLOSED_DIR)/obfus/framework.dox
|
||||
@$(ECHO) ">>>Creating framework.dox"
|
||||
$(prep-target)
|
||||
$(SED) "s:@@TEMPDIR@@:$(ABS_TEMPDIR):" $< > $@
|
||||
|
||||
#
|
||||
# The current obfuscator has a limitation in that it currently only
|
||||
# supports up to v49 class file format. Force v49 classfiles in our
|
||||
@ -380,26 +424,27 @@ TARGET_CLASS_VERSION = 5
|
||||
# unlimited policy file distribution, etc.
|
||||
#
|
||||
|
||||
release: $(OBFUS_DIR)/jce.jar sign-policy
|
||||
release: $(OBFUS_DIR)/jce.jar sign-policy $(CLOSED_DIR)/doc/COPYRIGHT.html \
|
||||
$(CLOSED_DIR)/doc/README.txt
|
||||
$(RM) -r \
|
||||
$(RELEASE_DIR)/UnlimitedJCEPolicy \
|
||||
$(RELEASE_DIR)/jce.jar \
|
||||
$(RELEASE_DIR)/US_export_policy.jar \
|
||||
$(RELEASE_DIR)/local_policy.jar \
|
||||
$(RELEASE_DIR)/UnlimitedJCEPolicy.zip
|
||||
$(MKDIR) -p $(RELEASE_DIR)/UnlimitedJCEPolicy
|
||||
$(CP) $(OBFUS_DIR)/jce.jar $(RELEASE_DIR)
|
||||
$(CP) -r \
|
||||
$(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar \
|
||||
$(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar \
|
||||
$(RELEASE_DIR)
|
||||
$(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy \
|
||||
$(JCE_BUILD_DIR)/release/jce.jar \
|
||||
$(JCE_BUILD_DIR)/release/US_export_policy.jar \
|
||||
$(JCE_BUILD_DIR)/release/local_policy.jar \
|
||||
$(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy.zip
|
||||
$(MKDIR) -p $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy
|
||||
$(CP) $(OBFUS_DIR)/jce.jar $(JCE_BUILD_DIR)/release
|
||||
$(CP) \
|
||||
$(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar \
|
||||
$(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar \
|
||||
$(JCE_BUILD_DIR)/release
|
||||
$(CP) \
|
||||
$(SIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar \
|
||||
$(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar \
|
||||
$(RELEASE_DIR)/UnlimitedJCEPolicy
|
||||
$(CP) $(CLOSED_DIR)/doc/COPYRIGHT.html \
|
||||
$(CLOSED_DIR)/doc/README.txt $(RELEASE_DIR)/UnlimitedJCEPolicy
|
||||
cd $(RELEASE_DIR) ; \
|
||||
$(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar \
|
||||
$(CLOSED_DIR)/doc/COPYRIGHT.html \
|
||||
$(CLOSED_DIR)/doc/README.txt \
|
||||
$(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy
|
||||
cd $(JCE_BUILD_DIR)/release ; \
|
||||
$(ZIPEXE) -qr UnlimitedJCEPolicy.zip UnlimitedJCEPolicy
|
||||
$(release-warning)
|
||||
|
||||
@ -478,7 +523,8 @@ endif
|
||||
|
||||
clobber clean::
|
||||
$(RM) -r $(JAR_DESTFILE) $(POLICY_DESTDIR)/US_export_policy.jar \
|
||||
$(POLICY_DESTDIR)/local_policy.jar $(DELETE_DIRS) $(TEMPDIR)
|
||||
$(POLICY_DESTDIR)/local_policy.jar $(DELETE_DIRS) $(TEMPDIR) \
|
||||
$(JCE_BUILD_DIR)
|
||||
|
||||
.PHONY: build-jar jar build-policy unlimited limited install-jar \
|
||||
install-limited install-unlimited
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2005-2008 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
|
||||
@ -92,8 +92,25 @@ BUILDDIR = ../../..
|
||||
PACKAGE = sun.security.mscapi
|
||||
LIBRARY = sunmscapi
|
||||
PRODUCT = sun
|
||||
|
||||
#
|
||||
# The following is for when we need to do postprocessing
|
||||
# (signing/obfuscation) against a read-only build. If the OUTPUTDIR
|
||||
# isn't writable, the build currently crashes out.
|
||||
#
|
||||
ifndef OPENJDK
|
||||
ifdef ALT_JCE_BUILD_DIR
|
||||
# =====================================================
|
||||
# Where to place the output, in case we're building from a read-only
|
||||
# build area. (e.g. a release engineering build.)
|
||||
JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
|
||||
IGNORE_WRITABLE_OUTPUTDIR_TEST=true
|
||||
else
|
||||
JCE_BUILD_DIR=${TEMPDIR}
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
|
||||
|
||||
CPLUSPLUSLIBRARY=true
|
||||
|
||||
@ -163,6 +180,8 @@ all: build-jar install-prebuilt
|
||||
$(build-warning)
|
||||
endif
|
||||
|
||||
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
|
||||
|
||||
|
||||
# =====================================================
|
||||
# Build the unsigned sunmscapi.jar file.
|
||||
@ -200,14 +219,26 @@ ifndef OPENJDK
|
||||
# Sign the provider jar file. Not needed for OpenJDK.
|
||||
#
|
||||
|
||||
SIGNED_DIR = $(TEMPDIR)/signed
|
||||
SIGNED_DIR = $(JCE_BUILD_DIR)/signed
|
||||
|
||||
sign: sign-jar
|
||||
|
||||
sign-jar: $(SIGNED_DIR)/sunmscapi.jar
|
||||
|
||||
ifndef ALT_JCE_BUILD_DIR
|
||||
$(SIGNED_DIR)/sunmscapi.jar: $(UNSIGNED_DIR)/sunmscapi.jar
|
||||
$(sign-file)
|
||||
else
|
||||
#
|
||||
# We have to remove the build dependency, otherwise, we'll try to rebuild it
|
||||
# which we can't do on a read-only filesystem.
|
||||
#
|
||||
$(SIGNED_DIR)/sunmscapi.jar:
|
||||
@if [ ! -r $(UNSIGNED_DIR)/sunmscapi.jar ] ; then \
|
||||
$(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunmscapi.jar"; \
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
$(call sign-file, $(UNSIGNED_DIR)/sunmscapi.jar)
|
||||
|
||||
|
||||
# =====================================================
|
||||
@ -215,9 +246,9 @@ $(SIGNED_DIR)/sunmscapi.jar: $(UNSIGNED_DIR)/sunmscapi.jar
|
||||
#
|
||||
|
||||
release: $(SIGNED_DIR)/sunmscapi.jar
|
||||
$(RM) $(RELEASE_DIR)/sunmscapi.jar
|
||||
$(MKDIR) -p $(RELEASE_DIR)
|
||||
$(CP) $(SIGNED_DIR)/sunmscapi.jar $(RELEASE_DIR)
|
||||
$(RM) $(JCE_BUILD_DIR)/release/sunmscapi.jar
|
||||
$(MKDIR) -p $(JCE_BUILD_DIR)/release
|
||||
$(CP) $(SIGNED_DIR)/sunmscapi.jar $(JCE_BUILD_DIR)/release
|
||||
$(release-warning)
|
||||
|
||||
endif # OPENJDK
|
||||
@ -255,7 +286,7 @@ endif
|
||||
#
|
||||
|
||||
clobber clean::
|
||||
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR)
|
||||
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
|
||||
|
||||
.PHONY: build-jar jar install-jar
|
||||
ifndef OPENJDK
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2008 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
|
||||
@ -92,8 +92,25 @@ BUILDDIR = ../../..
|
||||
PACKAGE = sun.security.pkcs11
|
||||
LIBRARY = j2pkcs11
|
||||
PRODUCT = sun
|
||||
|
||||
#
|
||||
# The following is for when we need to do postprocessing
|
||||
# (signing/obfuscation) against a read-only build. If the OUTPUTDIR
|
||||
# isn't writable, the build currently crashes out.
|
||||
#
|
||||
ifndef OPENJDK
|
||||
ifdef ALT_JCE_BUILD_DIR
|
||||
# =====================================================
|
||||
# Where to place the output, in case we're building from a read-only
|
||||
# build area. (e.g. a release engineering build.)
|
||||
JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
|
||||
IGNORE_WRITABLE_OUTPUTDIR_TEST=true
|
||||
else
|
||||
JCE_BUILD_DIR=${TEMPDIR}
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
|
||||
|
||||
#
|
||||
# C and Java Files
|
||||
@ -163,6 +180,8 @@ all: build-jar install-prebuilt
|
||||
$(build-warning)
|
||||
endif
|
||||
|
||||
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
|
||||
|
||||
|
||||
# =====================================================
|
||||
# Build the unsigned sunpkcs11.jar file.
|
||||
@ -200,14 +219,26 @@ ifndef OPENJDK
|
||||
# Sign the provider jar file. Not needed for OpenJDK.
|
||||
#
|
||||
|
||||
SIGNED_DIR = $(TEMPDIR)/signed
|
||||
SIGNED_DIR = $(JCE_BUILD_DIR)/signed
|
||||
|
||||
sign: sign-jar
|
||||
|
||||
sign-jar: $(SIGNED_DIR)/sunpkcs11.jar
|
||||
|
||||
ifndef ALT_JCE_BUILD_DIR
|
||||
$(SIGNED_DIR)/sunpkcs11.jar: $(UNSIGNED_DIR)/sunpkcs11.jar
|
||||
$(sign-file)
|
||||
else
|
||||
#
|
||||
# We have to remove the build dependency, otherwise, we'll try to rebuild it
|
||||
# which we can't do on a read-only filesystem.
|
||||
#
|
||||
$(SIGNED_DIR)/sunpkcs11.jar:
|
||||
@if [ ! -r $(UNSIGNED_DIR)/sunpkcs11.jar ] ; then \
|
||||
$(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunpkcs11.jar"; \
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
$(call sign-file, $(UNSIGNED_DIR)/sunpkcs11.jar)
|
||||
|
||||
|
||||
# =====================================================
|
||||
@ -215,9 +246,9 @@ $(SIGNED_DIR)/sunpkcs11.jar: $(UNSIGNED_DIR)/sunpkcs11.jar
|
||||
#
|
||||
|
||||
release: $(SIGNED_DIR)/sunpkcs11.jar
|
||||
$(RM) $(RELEASE_DIR)/sunpkcs11.jar
|
||||
$(MKDIR) -p $(RELEASE_DIR)
|
||||
$(CP) $(SIGNED_DIR)/sunpkcs11.jar $(RELEASE_DIR)
|
||||
$(RM) $(JCE_BUILD_DIR)/release/sunpkcs11.jar
|
||||
$(MKDIR) -p $(JCE_BUILD_DIR)/release
|
||||
$(CP) $(SIGNED_DIR)/sunpkcs11.jar $(JCE_BUILD_DIR)/release
|
||||
$(release-warning)
|
||||
|
||||
endif # OPENJDK
|
||||
@ -255,7 +286,7 @@ endif
|
||||
#
|
||||
|
||||
clobber clean::
|
||||
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR)
|
||||
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
|
||||
|
||||
.PHONY: build-jar jar install-jar
|
||||
ifndef OPENJDK
|
||||
|
@ -34,8 +34,6 @@ import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.WeakHashMap;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.Permission;
|
||||
import java.security.ProtectionDomain;
|
||||
@ -51,7 +49,6 @@ import javax.management.InstanceAlreadyExistsException;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.IntrospectionException;
|
||||
import javax.management.InvalidAttributeValueException;
|
||||
import javax.management.JMException;
|
||||
import javax.management.JMRuntimeException;
|
||||
import javax.management.ListenerNotFoundException;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
@ -84,11 +81,10 @@ import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
|
||||
import com.sun.jmx.mbeanserver.DynamicMBean2;
|
||||
import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository;
|
||||
import com.sun.jmx.mbeanserver.MBeanInstantiator;
|
||||
import com.sun.jmx.mbeanserver.MXBeanSupport;
|
||||
import com.sun.jmx.mbeanserver.Repository;
|
||||
import com.sun.jmx.mbeanserver.NamedObject;
|
||||
import com.sun.jmx.defaults.ServiceName;
|
||||
import com.sun.jmx.mbeanserver.Introspector;
|
||||
import com.sun.jmx.mbeanserver.Util;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
|
||||
/**
|
||||
@ -623,18 +619,9 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
|
||||
List<String> result = new ArrayList<String>(domains.length);
|
||||
for (int i = 0; i < domains.length; i++) {
|
||||
try {
|
||||
ObjectName domain = new ObjectName(domains[i] + ":x=x");
|
||||
ObjectName domain = Util.newObjectName(domains[i] + ":x=x");
|
||||
checkMBeanPermission((String) null, null, domain, "getDomains");
|
||||
result.add(domains[i]);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
// Should never occur... But let's log it just in case.
|
||||
if (MBEANSERVER_LOGGER.isLoggable(Level.SEVERE)) {
|
||||
MBEANSERVER_LOGGER.logp(Level.SEVERE,
|
||||
DefaultMBeanServerInterceptor.class.getName(),
|
||||
"getDomains",
|
||||
"Failed to check permission for domain = " +
|
||||
domains[i], e);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
// OK: Do not add this domain to the list
|
||||
}
|
||||
|
@ -107,10 +107,7 @@ class MBeanAnalyzer<M> {
|
||||
private MBeanAnalyzer(Class<?> mbeanInterface,
|
||||
MBeanIntrospector<M> introspector)
|
||||
throws NotCompliantMBeanException {
|
||||
if (!mbeanInterface.isInterface()) {
|
||||
throw new NotCompliantMBeanException("Not an interface: " +
|
||||
mbeanInterface.getName());
|
||||
}
|
||||
introspector.checkCompliance(mbeanInterface);
|
||||
|
||||
try {
|
||||
initMaps(mbeanInterface, introspector);
|
||||
@ -121,11 +118,10 @@ class MBeanAnalyzer<M> {
|
||||
|
||||
// Introspect the mbeanInterface and initialize this object's maps.
|
||||
//
|
||||
private void initMaps(Class<?> mbeanInterface,
|
||||
private void initMaps(Class<?> mbeanType,
|
||||
MBeanIntrospector<M> introspector) throws Exception {
|
||||
final Method[] methodArray = mbeanInterface.getMethods();
|
||||
|
||||
final List<Method> methods = eliminateCovariantMethods(methodArray);
|
||||
final List<Method> methods1 = introspector.getMethods(mbeanType);
|
||||
final List<Method> methods = eliminateCovariantMethods(methods1);
|
||||
|
||||
/* Run through the methods to detect inconsistencies and to enable
|
||||
us to give getter and setter together to visitAttribute. */
|
||||
@ -234,13 +230,13 @@ class MBeanAnalyzer<M> {
|
||||
but existing code may depend on it and users may be used to seeing
|
||||
operations or attributes appear in a particular order. */
|
||||
static List<Method>
|
||||
eliminateCovariantMethods(Method[] methodArray) {
|
||||
eliminateCovariantMethods(List<Method> startMethods) {
|
||||
// We are assuming that you never have very many methods with the
|
||||
// same name, so it is OK to use algorithms that are quadratic
|
||||
// in the number of methods with the same name.
|
||||
|
||||
final int len = methodArray.length;
|
||||
final Method[] sorted = methodArray.clone();
|
||||
final int len = startMethods.size();
|
||||
final Method[] sorted = startMethods.toArray(new Method[len]);
|
||||
Arrays.sort(sorted,MethodOrder.instance);
|
||||
final Set<Method> overridden = newSet();
|
||||
for (int i=1;i<len;i++) {
|
||||
@ -259,7 +255,7 @@ class MBeanAnalyzer<M> {
|
||||
}
|
||||
}
|
||||
|
||||
final List<Method> methods = newList(Arrays.asList(methodArray));
|
||||
final List<Method> methods = newList(startMethods);
|
||||
methods.removeAll(overridden);
|
||||
return methods;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
@ -169,6 +170,19 @@ abstract class MBeanIntrospector<M> {
|
||||
*/
|
||||
abstract Descriptor getMBeanDescriptor(Class<?> resourceClass);
|
||||
|
||||
void checkCompliance(Class<?> mbeanType) throws NotCompliantMBeanException {
|
||||
if (!mbeanType.isInterface()) {
|
||||
throw new NotCompliantMBeanException("Not an interface: " +
|
||||
mbeanType.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the methods to be analyzed to build the MBean interface.
|
||||
*/
|
||||
List<Method> getMethods(final Class<?> mbeanType) throws Exception {
|
||||
return Arrays.asList(mbeanType.getMethods());
|
||||
}
|
||||
|
||||
final PerInterface<M> getPerInterface(Class<?> mbeanInterface)
|
||||
throws NotCompliantMBeanException {
|
||||
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
package com.sun.jmx.mbeanserver;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.management.NotCompliantMBeanException;
|
||||
import javax.management.Notification;
|
||||
|
||||
/**
|
||||
* <p>A variant of {@code StandardMBeanSupport} where the only
|
||||
* methods included are public getters. This is used by
|
||||
* {@code QueryNotificationFilter} to pretend that a Notification is
|
||||
* an MBean so it can have a query evaluated on it. Standard queries
|
||||
* never set attributes or invoke methods but custom queries could and
|
||||
* we don't want to allow that. Also we don't want to fail if a
|
||||
* Notification happens to have inconsistent types in a pair of getX and
|
||||
* setX methods, and we want to include the Object.getClass() method.
|
||||
*/
|
||||
public class NotificationMBeanSupport extends StandardMBeanSupport {
|
||||
public <T extends Notification> NotificationMBeanSupport(T n)
|
||||
throws NotCompliantMBeanException {
|
||||
super(n, Util.<Class<T>>cast(n.getClass()));
|
||||
}
|
||||
|
||||
@Override
|
||||
MBeanIntrospector<Method> getMBeanIntrospector() {
|
||||
return introspector;
|
||||
}
|
||||
|
||||
private static class Introspector extends StandardMBeanIntrospector {
|
||||
@Override
|
||||
void checkCompliance(Class<?> mbeanType) {}
|
||||
|
||||
@Override
|
||||
List<Method> getMethods(final Class<?> mbeanType)
|
||||
throws Exception {
|
||||
List<Method> methods = new ArrayList<Method>();
|
||||
for (Method m : mbeanType.getMethods()) {
|
||||
String name = m.getName();
|
||||
Class<?> ret = m.getReturnType();
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
if ((name.startsWith("is") && name.length() > 2 &&
|
||||
ret == boolean.class) ||
|
||||
(name.startsWith("get") && name.length() > 3 &&
|
||||
ret != void.class)) {
|
||||
methods.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
}
|
||||
private static final MBeanIntrospector<Method> introspector =
|
||||
new Introspector();
|
||||
}
|
@ -438,7 +438,7 @@ public abstract class OpenConverter {
|
||||
c.getClassLoader() == null);
|
||||
|
||||
final List<Method> methods =
|
||||
MBeanAnalyzer.eliminateCovariantMethods(c.getMethods());
|
||||
MBeanAnalyzer.eliminateCovariantMethods(Arrays.asList(c.getMethods()));
|
||||
final SortedMap<String,Method> getterMap = newSortedMap();
|
||||
|
||||
/* Select public methods that look like "T getX()" or "boolean
|
||||
@ -1118,11 +1118,11 @@ public abstract class OpenConverter {
|
||||
final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
|
||||
|
||||
Class targetClass = getTargetClass();
|
||||
Constructor[] constrs = targetClass.getConstructors();
|
||||
Constructor<?>[] constrs = targetClass.getConstructors();
|
||||
|
||||
// Applicable if and only if there are any annotated constructors
|
||||
List<Constructor> annotatedConstrList = newList();
|
||||
for (Constructor constr : constrs) {
|
||||
List<Constructor<?>> annotatedConstrList = newList();
|
||||
for (Constructor<?> constr : constrs) {
|
||||
if (Modifier.isPublic(constr.getModifiers())
|
||||
&& constr.getAnnotation(propertyNamesClass) != null)
|
||||
annotatedConstrList.add(constr);
|
||||
@ -1152,7 +1152,7 @@ public abstract class OpenConverter {
|
||||
// Also remember the set of properties in that constructor
|
||||
// so we can test unambiguity.
|
||||
Set<BitSet> getterIndexSets = newSet();
|
||||
for (Constructor constr : annotatedConstrList) {
|
||||
for (Constructor<?> constr : annotatedConstrList) {
|
||||
String[] propertyNames =
|
||||
constr.getAnnotation(propertyNamesClass).value();
|
||||
|
||||
@ -1309,10 +1309,10 @@ public abstract class OpenConverter {
|
||||
}
|
||||
|
||||
private static class Constr {
|
||||
final Constructor constructor;
|
||||
final Constructor<?> constructor;
|
||||
final int[] paramIndexes;
|
||||
final BitSet presentParams;
|
||||
Constr(Constructor constructor, int[] paramIndexes,
|
||||
Constr(Constructor<?> constructor, int[] paramIndexes,
|
||||
BitSet presentParams) {
|
||||
this.constructor = constructor;
|
||||
this.paramIndexes = paramIndexes;
|
||||
|
@ -415,17 +415,8 @@ public class Repository {
|
||||
boolean to_default_domain = false;
|
||||
|
||||
// Set domain to default if domain is empty and not already set
|
||||
if (dom.length() == 0) {
|
||||
try {
|
||||
name = new ObjectName(domain + name.toString());
|
||||
} catch (MalformedObjectNameException e) {
|
||||
if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {
|
||||
MBEANSERVER_LOGGER.logp(Level.FINEST,
|
||||
Repository.class.getName(), "addMBean",
|
||||
"Unexpected MalformedObjectNameException", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dom.length() == 0)
|
||||
name = Util.newObjectName(domain + name.toString());
|
||||
|
||||
// Do we have default domain ?
|
||||
if (dom == domain) {
|
||||
|
@ -38,6 +38,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public class Util {
|
||||
static <K, V> Map<K, V> newMap() {
|
||||
@ -85,6 +87,14 @@ public class Util {
|
||||
return new ArrayList<E>(c);
|
||||
}
|
||||
|
||||
public static ObjectName newObjectName(String s) {
|
||||
try {
|
||||
return new ObjectName(s);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* This method can be used by code that is deliberately violating the
|
||||
* allowed checked casts. Rather than marking the whole method containing
|
||||
* the code with @SuppressWarnings, you can use a call to this method for
|
||||
|
@ -1,4 +1,4 @@
|
||||
CTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
|
@ -1553,7 +1553,7 @@ class MetaData {
|
||||
private static String[] getConstructorProperties(Class type) {
|
||||
String[] names = null;
|
||||
int length = 0;
|
||||
for (Constructor constructor : type.getConstructors()) {
|
||||
for (Constructor<?> constructor : type.getConstructors()) {
|
||||
String[] value = getAnnotationValue(constructor);
|
||||
if ((value != null) && (length < value.length) && isValid(constructor, value)) {
|
||||
names = value;
|
||||
@ -1563,14 +1563,14 @@ class MetaData {
|
||||
return names;
|
||||
}
|
||||
|
||||
private static String[] getAnnotationValue(Constructor constructor) {
|
||||
private static String[] getAnnotationValue(Constructor<?> constructor) {
|
||||
ConstructorProperties annotation = constructor.getAnnotation(ConstructorProperties.class);
|
||||
return (annotation != null)
|
||||
? annotation.value()
|
||||
: null;
|
||||
}
|
||||
|
||||
private static boolean isValid(Constructor constructor, String[] names) {
|
||||
private static boolean isValid(Constructor<?> constructor, String[] names) {
|
||||
Class[] parameters = constructor.getParameterTypes();
|
||||
if (names.length != parameters.length) {
|
||||
return false;
|
||||
|
@ -636,7 +636,11 @@ public interface Instrumentation {
|
||||
* @param transformer
|
||||
* The ClassFileTransformer which wraps using this prefix.
|
||||
* @param prefix
|
||||
* The prefix which has been applied to wrapped native methods.
|
||||
* The prefix to apply to wrapped native methods when
|
||||
* retrying a failed native method resolution. If prefix
|
||||
* is either <code>null</code> or the empty string, then
|
||||
* failed native method resolutions are not retried for
|
||||
* this transformer.
|
||||
* @throws java.lang.NullPointerException if passed a <code>null</code> transformer.
|
||||
* @throws java.lang.UnsupportedOperationException if the current configuration of
|
||||
* the JVM does not allow setting a native method prefix
|
||||
|
@ -50,7 +50,7 @@ import javax.management.loading.ClassLoaderRepository;
|
||||
* server. A Java object cannot be registered in the MBean server
|
||||
* unless it is a JMX compliant MBean.</p>
|
||||
*
|
||||
* <p>When an MBean is registered or unregistered in the MBean server
|
||||
* <p id="notif">When an MBean is registered or unregistered in the MBean server
|
||||
* a {@link javax.management.MBeanServerNotification
|
||||
* MBeanServerNotification} Notification is emitted. To register an
|
||||
* object as listener to MBeanServerNotifications you should call the
|
||||
@ -258,27 +258,43 @@ import javax.management.loading.ClassLoaderRepository;
|
||||
*/
|
||||
public interface MBeanServer extends MBeanServerConnection {
|
||||
|
||||
// doc comment inherited from MBeanServerConnection
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>If this method successfully creates an MBean, a notification
|
||||
* is sent as described <a href="#notif">above</a>.</p>
|
||||
*/
|
||||
public ObjectInstance createMBean(String className, ObjectName name)
|
||||
throws ReflectionException, InstanceAlreadyExistsException,
|
||||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException;
|
||||
|
||||
// doc comment inherited from MBeanServerConnection
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>If this method successfully creates an MBean, a notification
|
||||
* is sent as described <a href="#notif">above</a>.</p>
|
||||
*/
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
ObjectName loaderName)
|
||||
throws ReflectionException, InstanceAlreadyExistsException,
|
||||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException, InstanceNotFoundException;
|
||||
|
||||
// doc comment inherited from MBeanServerConnection
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>If this method successfully creates an MBean, a notification
|
||||
* is sent as described <a href="#notif">above</a>.</p>
|
||||
*/
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
Object params[], String signature[])
|
||||
throws ReflectionException, InstanceAlreadyExistsException,
|
||||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException;
|
||||
|
||||
// doc comment inherited from MBeanServerConnection
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>If this method successfully creates an MBean, a notification
|
||||
* is sent as described <a href="#notif">above</a>.</p>
|
||||
*/
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
ObjectName loaderName, Object params[],
|
||||
String signature[])
|
||||
@ -287,12 +303,15 @@ public interface MBeanServer extends MBeanServerConnection {
|
||||
NotCompliantMBeanException, InstanceNotFoundException;
|
||||
|
||||
/**
|
||||
* Registers a pre-existing object as an MBean with the MBean
|
||||
* <p>Registers a pre-existing object as an MBean with the MBean
|
||||
* server. If the object name given is null, the MBean must
|
||||
* provide its own name by implementing the {@link
|
||||
* javax.management.MBeanRegistration MBeanRegistration} interface
|
||||
* and returning the name from the {@link
|
||||
* MBeanRegistration#preRegister preRegister} method.
|
||||
* MBeanRegistration#preRegister preRegister} method.</p>
|
||||
*
|
||||
* <p>If this method successfully registers an MBean, a notification
|
||||
* is sent as described <a href="#notif">above</a>.</p>
|
||||
*
|
||||
* @param object The MBean to be registered as an MBean.
|
||||
* @param name The object name of the MBean. May be null.
|
||||
@ -319,7 +338,12 @@ public interface MBeanServer extends MBeanServerConnection {
|
||||
throws InstanceAlreadyExistsException, MBeanRegistrationException,
|
||||
NotCompliantMBeanException;
|
||||
|
||||
// doc comment inherited from MBeanServerConnection
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>If this method successfully unregisters an MBean, a notification
|
||||
* is sent as described <a href="#notif">above</a>.</p>
|
||||
*/
|
||||
public void unregisterMBean(ObjectName name)
|
||||
throws InstanceNotFoundException, MBeanRegistrationException;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
package javax.management;
|
||||
|
||||
import com.sun.jmx.mbeanserver.GetPropertyAction;
|
||||
import com.sun.jmx.mbeanserver.Util;
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
@ -1386,12 +1387,7 @@ public class ObjectName extends ToQueryString
|
||||
throws NullPointerException {
|
||||
if (name.getClass().equals(ObjectName.class))
|
||||
return name;
|
||||
try {
|
||||
return new ObjectName(name.getSerializedNameString());
|
||||
} catch (MalformedObjectNameException e) {
|
||||
throw new IllegalArgumentException("Unexpected: " + e);
|
||||
// can't happen
|
||||
}
|
||||
return Util.newObjectName(name.getSerializedNameString());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1950,14 +1946,7 @@ public class ObjectName extends ToQueryString
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static final ObjectName WILDCARD;
|
||||
static {
|
||||
try {
|
||||
WILDCARD = new ObjectName("*:*");
|
||||
} catch (MalformedObjectNameException e) {
|
||||
throw new Error("Can't initialize wildcard name", e);
|
||||
}
|
||||
}
|
||||
public static final ObjectName WILDCARD = Util.newObjectName("*:*");
|
||||
|
||||
// Category : Utilities <===================================
|
||||
|
||||
|
@ -0,0 +1,417 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
package javax.management;
|
||||
|
||||
import com.sun.jmx.mbeanserver.NotificationMBeanSupport;
|
||||
import com.sun.jmx.mbeanserver.Util;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>General-purpose notification filter. This filter can be used to
|
||||
* filter notifications from a possibly-remote MBean. Most filtering
|
||||
* decisions can be coded using this filter, which avoids having to
|
||||
* write a custom implementation of the {@link NotificationFilter}
|
||||
* class. Writing a custom implementation requires you to deploy it
|
||||
* on both the client and the server in the remote case, so using this class
|
||||
* instead is recommended where possible.</p>
|
||||
*
|
||||
* <!-- <p>Because this class was introduced in version 2.0 of the JMX API,
|
||||
* it may not be present on a remote JMX agent that is running an earlier
|
||||
* version. The method {@link JMX#addListenerWithFilter JMX.addListenerWithFilter}
|
||||
* can be used when you cannot be sure whether this class is present in the
|
||||
* agent you are connecting to.</p> -->
|
||||
*
|
||||
* <p>This class uses the {@linkplain Query Query API} to specify the
|
||||
* filtering logic. For example, to select only notifications where the
|
||||
* {@linkplain Notification#getType() type} is {@code "com.example.mytype"},
|
||||
* you could use</p>
|
||||
*
|
||||
* <pre>
|
||||
* NotificationFilter filter =
|
||||
* new QueryNotificationFilter("Type = 'com.example.mytype'");
|
||||
* </pre>
|
||||
*
|
||||
* <p>or equivalently</p>
|
||||
*
|
||||
* <pre>
|
||||
* NotificationFilter filter =
|
||||
* new QueryNotificationFilter(
|
||||
* Query.eq(Query.attr("Type"), Query.value("com.example.mytype")));
|
||||
* </pre>
|
||||
*
|
||||
* <p>(This particular example could also use
|
||||
* {@link NotificationFilterSupport}.)</p>
|
||||
*
|
||||
* <p>Here are some other examples of filters you can specify with this class.</p>
|
||||
*
|
||||
* <dl>
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter("Type = 'com.example.type1' or
|
||||
* Type = 'com.example.type2'")}
|
||||
* <dd>Notifications where the type is either of the given strings.
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter("Type in ('com.example.type1',
|
||||
* 'com.example.type2')")}
|
||||
* <dd>Another way to write the previous example.
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter("SequenceNumber > 1000")}
|
||||
* <dd>Notifications where the {@linkplain Notification#getSequenceNumber()
|
||||
* sequence number} is greater than 1000.
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class, null)}
|
||||
* <dd>Notifications where the notification class is
|
||||
* {@link AttributeChangeNotification} or a subclass of it.
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class,
|
||||
* "AttributeName = 'Size'")}
|
||||
* <dd>Notifications where the notification class is
|
||||
* {@link AttributeChangeNotification} or a subclass, and where the
|
||||
* {@linkplain AttributeChangeNotification#getAttributeName() name of the
|
||||
* changed attribute} is {@code Size}.
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class,
|
||||
* "AttributeName = 'Size' and NewValue - OldValue > 100")}
|
||||
* <dd>As above, but the difference between the
|
||||
* {@linkplain AttributeChangeNotification#getNewValue() new value} and the
|
||||
* {@linkplain AttributeChangeNotification#getOldValue() old value} must be
|
||||
* greater than 100.
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter("like 'com.example.mydomain:*'")}
|
||||
* <dd>Notifications where the {@linkplain Notification#getSource() source}
|
||||
* is an ObjectName that matches the pattern.
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter("Source.canonicalName like
|
||||
* 'com.example.mydomain:%'")}
|
||||
* <dd>Another way to write the previous example.
|
||||
*
|
||||
* <dt>{@code QueryNotificationFilter(MBeanServerNotification.class,
|
||||
* "Type = 'JMX.mbean.registered' and MBeanName.canonicalName like
|
||||
* 'com.example.mydomain:%'")}
|
||||
* <dd>Notifications of class {@link MBeanServerNotification} representing
|
||||
* an object registered in the domain {@code com.example.mydomain}.
|
||||
*
|
||||
* </dl>
|
||||
*
|
||||
* <h4>How it works</h4>
|
||||
*
|
||||
* <p>Although the examples above are clear, looking closely at the
|
||||
* Query API reveals a subtlety. A {@link QueryExp} is evaluated on
|
||||
* an {@link ObjectName}, not a {@code Notification}.</p>
|
||||
*
|
||||
* <p>Every time a {@code Notification} is to be filtered by a
|
||||
* {@code QueryNotificationFilter}, a special {@link MBeanServer} is created.
|
||||
* This {@code MBeanServer} contains exactly one MBean, which represents the
|
||||
* {@code Notification}. If the {@linkplain Notification#getSource()
|
||||
* source} of the notification is an {@code ObjectName}, which is
|
||||
* recommended practice, then the name of the MBean representing the
|
||||
* {@code Notification} will be this {@code ObjectName}. Otherwise the
|
||||
* name is unspecified.</p>
|
||||
*
|
||||
* <p>The query specified in the {@code QueryNotificationFilter} constructor
|
||||
* is evaluated against this {@code MBeanServer} and {@code ObjectName},
|
||||
* and the filter returns true if and only if the query does. If the
|
||||
* query throws an exception, then the filter will return false.</p>
|
||||
*
|
||||
* <p>The MBean representing the {@code Notification} has one attribute for
|
||||
* every property of the {@code Notification}. Specifically, for every public
|
||||
* method {@code T getX()} in the {@code NotificationClass}, the MBean will
|
||||
* have an attribute called {@code X} of type {@code T}. For example, if the
|
||||
* {@code Notification} is an {@code AttributeChangeNotification}, then the
|
||||
* MBean will have an attribute called {@code AttributeName} of type
|
||||
* {@code "java.lang.String"}, corresponding to the method {@link
|
||||
* AttributeChangeNotification#getAttributeName}.</p>
|
||||
*
|
||||
* <p>Query evaluation usually involves calls to the methods of {@code
|
||||
* MBeanServer}. The methods have the following behavior:</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>The {@link MBeanServer#getAttribute getAttribute} method returns the
|
||||
* value of the corresponding property.
|
||||
* <li>The {@link MBeanServer#getObjectInstance getObjectInstance}
|
||||
* method returns an {@link ObjectInstance} where the {@link
|
||||
* ObjectInstance#getObjectName ObjectName} is the name of the MBean and the
|
||||
* {@link ObjectInstance#getClassName ClassName} is the class name of the
|
||||
* {@code Notification}.
|
||||
* <li>The {@link MBeanServer#isInstanceOf isInstanceOf} method returns true
|
||||
* if and only if the {@code Notification}'s {@code ClassLoader} can load the
|
||||
* named class, and the {@code Notification} is an {@linkplain Class#isInstance
|
||||
* instance} of that class.
|
||||
* </ul>
|
||||
*
|
||||
* <p>These are the only {@code MBeanServer} methods that are needed to
|
||||
* evaluate standard queries. The behavior of the other {@code MBeanServer}
|
||||
* methods is unspecified.</p>
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public class QueryNotificationFilter implements NotificationFilter {
|
||||
private static final long serialVersionUID = -8408613922660635231L;
|
||||
|
||||
private static final ObjectName DEFAULT_NAME =
|
||||
Util.newObjectName(":type=Notification");
|
||||
private static final QueryExp trueQuery;
|
||||
static {
|
||||
ValueExp zero = Query.value(0);
|
||||
trueQuery = Query.eq(zero, zero);
|
||||
}
|
||||
|
||||
private final QueryExp query;
|
||||
|
||||
/**
|
||||
* Construct a {@code QueryNotificationFilter} that evaluates the given
|
||||
* {@code QueryExp} to determine whether to accept a notification.
|
||||
*
|
||||
* @param query the {@code QueryExp} to evaluate. Can be null,
|
||||
* in which case all notifications are accepted.
|
||||
*/
|
||||
public QueryNotificationFilter(QueryExp query) {
|
||||
if (query == null)
|
||||
this.query = trueQuery;
|
||||
else
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@code QueryNotificationFilter} that evaluates the query
|
||||
* in the given string to determine whether to accept a notification.
|
||||
* The string is converted into a {@code QueryExp} using
|
||||
* {@link Query#fromString Query.fromString}.
|
||||
*
|
||||
* @param query the string specifying the query to evaluate. Can be null,
|
||||
* in which case all notifications are accepted.
|
||||
*
|
||||
* @throws IllegalArgumentException if the string is not a valid
|
||||
* query string.
|
||||
*/
|
||||
public QueryNotificationFilter(String query) {
|
||||
this(Query.fromString(query));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Construct a {@code QueryNotificationFilter} that evaluates the query
|
||||
* in the given string to determine whether to accept a notification,
|
||||
* and where the notification must also be an instance of the given class.
|
||||
* The string is converted into a {@code QueryExp} using
|
||||
* {@link Query#fromString Query.fromString}.</p>
|
||||
*
|
||||
* @param notifClass the class that the notification must be an instance of.
|
||||
* Cannot be null.
|
||||
*
|
||||
* @param query the string specifying the query to evaluate. Can be null,
|
||||
* in which case all notifications are accepted.
|
||||
*
|
||||
* @throws IllegalArgumentException if the string is not a valid
|
||||
* query string, or if {@code notifClass} is null.
|
||||
*/
|
||||
public QueryNotificationFilter(
|
||||
Class<? extends Notification> notifClass, String query) {
|
||||
this(Query.and(Query.isInstanceOf(Query.value(notNull(notifClass).getName())),
|
||||
Query.fromString(query)));
|
||||
}
|
||||
|
||||
private static <T> T notNull(T x) {
|
||||
if (x == null)
|
||||
throw new IllegalArgumentException("Null argument");
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the query that this notification filter will evaluate for
|
||||
* each notification.
|
||||
*
|
||||
* @return the query.
|
||||
*/
|
||||
public QueryExp getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public boolean isNotificationEnabled(Notification notification) {
|
||||
ObjectName name;
|
||||
|
||||
Object source = notification.getSource();
|
||||
if (source instanceof ObjectName)
|
||||
name = (ObjectName) source;
|
||||
else
|
||||
name = DEFAULT_NAME;
|
||||
|
||||
MBS mbsImpl = new MBS(notification, name);
|
||||
MBeanServer mbs = (MBeanServer) Proxy.newProxyInstance(
|
||||
MBeanServer.class.getClassLoader(),
|
||||
new Class<?>[] {MBeanServer.class},
|
||||
new ForwardIH(mbsImpl));
|
||||
return evalQuery(query, mbs, name);
|
||||
}
|
||||
|
||||
private static boolean evalQuery(
|
||||
QueryExp query, MBeanServer mbs, ObjectName name) {
|
||||
MBeanServer oldMBS = QueryEval.getMBeanServer();
|
||||
try {
|
||||
if (mbs != null)
|
||||
query.setMBeanServer(mbs);
|
||||
return query.apply(name);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
} finally {
|
||||
query.setMBeanServer(oldMBS);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ForwardIH implements InvocationHandler {
|
||||
private final MBS mbs;
|
||||
|
||||
ForwardIH(MBS mbs) {
|
||||
this.mbs = mbs;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
Method forward;
|
||||
try {
|
||||
forward = MBS.class.getMethod(
|
||||
method.getName(), method.getParameterTypes());
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new UnsupportedOperationException(method.getName());
|
||||
}
|
||||
try {
|
||||
return forward.invoke(mbs, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MBS {
|
||||
private final Notification notification;
|
||||
private final ObjectName objectName;
|
||||
private final ObjectInstance objectInstance;
|
||||
private volatile DynamicMBean mbean;
|
||||
|
||||
MBS(Notification n, ObjectName name) {
|
||||
this.notification = n;
|
||||
this.objectName = name;
|
||||
this.objectInstance = new ObjectInstance(name, n.getClass().getName());
|
||||
}
|
||||
|
||||
private void checkName(ObjectName name) throws InstanceNotFoundException {
|
||||
if (!objectName.equals(name))
|
||||
throw new InstanceNotFoundException(String.valueOf(name));
|
||||
}
|
||||
|
||||
private DynamicMBean mbean(ObjectName name)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
if (mbean == null) {
|
||||
try {
|
||||
mbean = new NotificationMBeanSupport(notification);
|
||||
} catch (NotCompliantMBeanException e) {
|
||||
throw new ReflectionException(e);
|
||||
}
|
||||
}
|
||||
return mbean;
|
||||
}
|
||||
|
||||
public ObjectInstance getObjectInstance(ObjectName name)
|
||||
throws InstanceNotFoundException {
|
||||
checkName(name);
|
||||
return objectInstance;
|
||||
}
|
||||
|
||||
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
|
||||
Set<ObjectName> names = queryNames(name, query);
|
||||
switch (names.size()) {
|
||||
case 0:
|
||||
return Collections.emptySet();
|
||||
case 1:
|
||||
return Collections.singleton(objectInstance);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Internal error");
|
||||
}
|
||||
}
|
||||
|
||||
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
|
||||
if ((name != null && !name.apply(objectName)) ||
|
||||
(query != null && !evalQuery(query, null, name)))
|
||||
return Collections.emptySet();
|
||||
return Collections.singleton(objectName);
|
||||
}
|
||||
|
||||
public boolean isRegistered(ObjectName name) {
|
||||
return objectName.equals(name);
|
||||
}
|
||||
|
||||
public Integer getMBeanCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Object getAttribute(ObjectName name, String attribute)
|
||||
throws MBeanException, AttributeNotFoundException,
|
||||
InstanceNotFoundException, ReflectionException {
|
||||
return mbean(name).getAttribute(attribute);
|
||||
}
|
||||
|
||||
public AttributeList getAttributes(ObjectName name, String[] attributes)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
return mbean(name).getAttributes(attributes);
|
||||
}
|
||||
|
||||
public String getDefaultDomain() {
|
||||
return objectName.getDomain();
|
||||
}
|
||||
|
||||
public String[] getDomains() {
|
||||
return new String[] {objectName.getDomain()};
|
||||
}
|
||||
|
||||
public MBeanInfo getMBeanInfo(ObjectName name)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
return mbean(name).getMBeanInfo();
|
||||
}
|
||||
|
||||
public boolean isInstanceOf(ObjectName name, String className)
|
||||
throws InstanceNotFoundException {
|
||||
try {
|
||||
mbean(name);
|
||||
ClassLoader loader = notification.getClass().getClassLoader();
|
||||
Class<?> c = Class.forName(className, false, loader);
|
||||
return c.isInstance(notification);
|
||||
} catch (ReflectionException e) {
|
||||
return false;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoaderFor(ObjectName mbeanName)
|
||||
throws InstanceNotFoundException {
|
||||
checkName(mbeanName);
|
||||
return notification.getClass().getClassLoader();
|
||||
}
|
||||
}
|
||||
}
|
@ -48,6 +48,7 @@ import java.util.logging.Level;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.Vector;
|
||||
import javax.management.Attribute;
|
||||
import javax.management.AttributeChangeNotification;
|
||||
import javax.management.AttributeChangeNotificationFilter;
|
||||
@ -132,8 +133,6 @@ public class RequiredModelMBean
|
||||
* and operations will be executed */
|
||||
private Object managedResource = null;
|
||||
|
||||
private static final String currClass = "RequiredModelMBean";
|
||||
|
||||
/* records the registering in MBeanServer */
|
||||
private boolean registered = false;
|
||||
private transient MBeanServer server = null;
|
||||
@ -2488,10 +2487,13 @@ public class RequiredModelMBean
|
||||
}
|
||||
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
|
||||
Vector<String> enabledAttrs = currFilter.getEnabledAttributes();
|
||||
String s = (enabledAttrs.size() > 1) ?
|
||||
"[" + enabledAttrs.firstElement() + ", ...]" :
|
||||
enabledAttrs.toString();
|
||||
MODELMBEAN_LOGGER.logp(Level.FINER,
|
||||
RequiredModelMBean.class.getName(), mth,
|
||||
"Set attribute change filter to " +
|
||||
currFilter.getEnabledAttributes().firstElement());
|
||||
"Set attribute change filter to " + s);
|
||||
}
|
||||
|
||||
attributeBroadcaster.addNotificationListener(inlistener,currFilter,
|
||||
|
@ -303,39 +303,78 @@ public class InstrumentationImpl implements Instrumentation {
|
||||
NoSuchMethodException firstExc = null;
|
||||
boolean twoArgAgent = false;
|
||||
|
||||
// The agent class has a premain or agentmain method that has 1 or 2
|
||||
// arguments. We first check for a signature of (String, Instrumentation),
|
||||
// and if not found we check for (String). If neither is found then we
|
||||
// throw the NoSuchMethodException from the first attempt so that the
|
||||
// exception text indicates the lookup failed for the 2-arg method
|
||||
// (same as JDK5.0).
|
||||
// The agent class must have a premain or agentmain method that
|
||||
// has 1 or 2 arguments. We check in the following order:
|
||||
//
|
||||
// 1) declared with a signature of (String, Instrumentation)
|
||||
// 2) declared with a signature of (String)
|
||||
// 3) inherited with a signature of (String, Instrumentation)
|
||||
// 4) inherited with a signature of (String)
|
||||
//
|
||||
// So the declared version of either 1-arg or 2-arg always takes
|
||||
// primary precedence over an inherited version. After that, the
|
||||
// 2-arg version takes precedence over the 1-arg version.
|
||||
//
|
||||
// If no method is found then we throw the NoSuchMethodException
|
||||
// from the first attempt so that the exception text indicates
|
||||
// the lookup failed for the 2-arg method (same as JDK5.0).
|
||||
|
||||
try {
|
||||
m = javaAgentClass.getMethod( methodname,
|
||||
new Class[] {
|
||||
String.class,
|
||||
java.lang.instrument.Instrumentation.class
|
||||
}
|
||||
);
|
||||
m = javaAgentClass.getDeclaredMethod( methodname,
|
||||
new Class[] {
|
||||
String.class,
|
||||
java.lang.instrument.Instrumentation.class
|
||||
}
|
||||
);
|
||||
twoArgAgent = true;
|
||||
} catch (NoSuchMethodException x) {
|
||||
// remember the NoSuchMethodException
|
||||
firstExc = x;
|
||||
}
|
||||
|
||||
// check for the 1-arg method
|
||||
if (m == null) {
|
||||
// now try the declared 1-arg method
|
||||
try {
|
||||
m = javaAgentClass.getMethod(methodname, new Class[] { String.class });
|
||||
m = javaAgentClass.getDeclaredMethod(methodname,
|
||||
new Class[] { String.class });
|
||||
} catch (NoSuchMethodException x) {
|
||||
// Neither method exists so we throw the first NoSuchMethodException
|
||||
// as per 5.0
|
||||
// ignore this exception because we'll try
|
||||
// two arg inheritance next
|
||||
}
|
||||
}
|
||||
|
||||
if (m == null) {
|
||||
// now try the inherited 2-arg method
|
||||
try {
|
||||
m = javaAgentClass.getMethod( methodname,
|
||||
new Class[] {
|
||||
String.class,
|
||||
java.lang.instrument.Instrumentation.class
|
||||
}
|
||||
);
|
||||
twoArgAgent = true;
|
||||
} catch (NoSuchMethodException x) {
|
||||
// ignore this exception because we'll try
|
||||
// one arg inheritance next
|
||||
}
|
||||
}
|
||||
|
||||
if (m == null) {
|
||||
// finally try the inherited 1-arg method
|
||||
try {
|
||||
m = javaAgentClass.getMethod(methodname,
|
||||
new Class[] { String.class });
|
||||
} catch (NoSuchMethodException x) {
|
||||
// none of the methods exists so we throw the
|
||||
// first NoSuchMethodException as per 5.0
|
||||
throw firstExc;
|
||||
}
|
||||
}
|
||||
|
||||
// the premain method should not be required to be public,
|
||||
// make it accessible so we can call it
|
||||
// Note: The spec says the following:
|
||||
// The agent class must implement a public static premain method...
|
||||
setAccessible(m, true);
|
||||
|
||||
// invoke the 1 or 2-arg method
|
||||
|
@ -64,7 +64,8 @@ class Flag {
|
||||
}
|
||||
|
||||
VMOption getVMOption() {
|
||||
return new VMOption(name, value.toString(), writeable, origin);
|
||||
String val = value == null ? "" : value.toString();
|
||||
return new VMOption(name, val, writeable, origin);
|
||||
}
|
||||
|
||||
static Flag getFlag(String name) {
|
||||
|
@ -91,9 +91,10 @@ public class NegotiatorImpl extends Negotiator {
|
||||
GSSManagerImpl manager = new GSSManagerImpl(
|
||||
GSSUtil.CALLER_HTTP_NEGOTIATE);
|
||||
|
||||
String peerName = "HTTP/" + hostname;
|
||||
String peerName = "HTTP@" + hostname;
|
||||
|
||||
GSSName serverName = manager.createName(peerName, null);
|
||||
GSSName serverName = manager.createName(peerName,
|
||||
GSSName.NT_HOSTBASED_SERVICE);
|
||||
context = manager.createContext(serverName,
|
||||
oid,
|
||||
null,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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
|
||||
@ -22,10 +22,10 @@
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package sun.security.pkcs11;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
@ -34,7 +34,6 @@ import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import sun.security.pkcs11.wrapper.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
|
||||
@ -43,8 +42,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
* DES, DESede, AES, ARCFOUR, and Blowfish.
|
||||
*
|
||||
* This class is designed to support ECB and CBC with NoPadding and
|
||||
* PKCS5Padding for both. However, currently only CBC/NoPadding (and
|
||||
* ECB/NoPadding for stream ciphers) is functional.
|
||||
* PKCS5Padding for both. It will use its own padding impl if the
|
||||
* native mechanism does not support padding.
|
||||
*
|
||||
* Note that PKCS#11 current only supports ECB and CBC. There are no
|
||||
* provisions for other modes such as CFB, OFB, PCBC, or CTR mode.
|
||||
@ -62,10 +61,59 @@ final class P11Cipher extends CipherSpi {
|
||||
private final static int MODE_CBC = 4;
|
||||
|
||||
// padding constant for NoPadding
|
||||
private final static int PAD_NONE = 5;
|
||||
private final static int PAD_NONE = 5;
|
||||
// padding constant for PKCS5Padding
|
||||
private final static int PAD_PKCS5 = 6;
|
||||
|
||||
private static interface Padding {
|
||||
// ENC: format the specified buffer with padding bytes and return the
|
||||
// actual padding length
|
||||
int setPaddingBytes(byte[] paddingBuffer, int padLen);
|
||||
|
||||
// DEC: return the length of trailing padding bytes given the specified
|
||||
// padded data
|
||||
int unpad(byte[] paddedData, int len)
|
||||
throws BadPaddingException;
|
||||
}
|
||||
|
||||
private static class PKCS5Padding implements Padding {
|
||||
|
||||
private final int blockSize;
|
||||
|
||||
PKCS5Padding(int blockSize)
|
||||
throws NoSuchPaddingException {
|
||||
if (blockSize == 0) {
|
||||
throw new NoSuchPaddingException
|
||||
("PKCS#5 padding not supported with stream ciphers");
|
||||
}
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
|
||||
public int setPaddingBytes(byte[] paddingBuffer, int padLen) {
|
||||
Arrays.fill(paddingBuffer, 0, padLen, (byte) (padLen & 0x007f));
|
||||
return padLen;
|
||||
}
|
||||
|
||||
public int unpad(byte[] paddedData, int len)
|
||||
throws BadPaddingException {
|
||||
if (len < 1 || len > paddedData.length) {
|
||||
throw new BadPaddingException("Invalid pad array length!");
|
||||
}
|
||||
byte padValue = paddedData[len - 1];
|
||||
if (padValue < 1 || padValue > blockSize) {
|
||||
throw new BadPaddingException("Invalid pad value!");
|
||||
}
|
||||
// sanity check padding bytes
|
||||
int padStartIndex = len - padValue;
|
||||
for (int i = padStartIndex; i < len; i++) {
|
||||
if (paddedData[i] != padValue) {
|
||||
throw new BadPaddingException("Invalid pad bytes!");
|
||||
}
|
||||
}
|
||||
return padValue;
|
||||
}
|
||||
}
|
||||
|
||||
// token instance
|
||||
private final Token token;
|
||||
|
||||
@ -99,65 +147,93 @@ final class P11Cipher extends CipherSpi {
|
||||
// padding type, on of PAD_* above (PAD_NONE for stream ciphers)
|
||||
private int paddingType;
|
||||
|
||||
// when the padding is requested but unsupported by the native mechanism,
|
||||
// we use the following to do padding and necessary data buffering.
|
||||
// padding object which generate padding and unpad the decrypted data
|
||||
private Padding paddingObj;
|
||||
// buffer for holding back the block which contains padding bytes
|
||||
private byte[] padBuffer;
|
||||
private int padBufferLen;
|
||||
|
||||
// original IV, if in MODE_CBC
|
||||
private byte[] iv;
|
||||
|
||||
// total number of bytes processed
|
||||
private int bytesProcessed;
|
||||
// number of bytes buffered internally by the native mechanism and padBuffer
|
||||
// if we do the padding
|
||||
private int bytesBuffered;
|
||||
|
||||
P11Cipher(Token token, String algorithm, long mechanism)
|
||||
throws PKCS11Exception {
|
||||
throws PKCS11Exception, NoSuchAlgorithmException {
|
||||
super();
|
||||
this.token = token;
|
||||
this.algorithm = algorithm;
|
||||
this.mechanism = mechanism;
|
||||
keyAlgorithm = algorithm.split("/")[0];
|
||||
|
||||
String algoParts[] = algorithm.split("/");
|
||||
keyAlgorithm = algoParts[0];
|
||||
|
||||
if (keyAlgorithm.equals("AES")) {
|
||||
blockSize = 16;
|
||||
blockMode = MODE_CBC;
|
||||
// XXX change default to PKCS5Padding
|
||||
paddingType = PAD_NONE;
|
||||
} else if (keyAlgorithm.equals("RC4") || keyAlgorithm.equals("ARCFOUR")) {
|
||||
} else if (keyAlgorithm.equals("RC4") ||
|
||||
keyAlgorithm.equals("ARCFOUR")) {
|
||||
blockSize = 0;
|
||||
blockMode = MODE_ECB;
|
||||
paddingType = PAD_NONE;
|
||||
} else { // DES, DESede, Blowfish
|
||||
blockSize = 8;
|
||||
blockMode = MODE_CBC;
|
||||
// XXX change default to PKCS5Padding
|
||||
paddingType = PAD_NONE;
|
||||
}
|
||||
this.blockMode =
|
||||
(algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
|
||||
|
||||
String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding");
|
||||
String paddingStr =
|
||||
(algoParts.length > 2 ? algoParts[2] : defPadding);
|
||||
try {
|
||||
engineSetPadding(paddingStr);
|
||||
} catch (NoSuchPaddingException nspe) {
|
||||
// should not happen
|
||||
throw new ProviderException(nspe);
|
||||
}
|
||||
session = token.getOpSession();
|
||||
}
|
||||
|
||||
protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
|
||||
// Disallow change of mode for now since currently it's explicitly
|
||||
// defined in transformation strings
|
||||
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
|
||||
}
|
||||
|
||||
private int parseMode(String mode) throws NoSuchAlgorithmException {
|
||||
mode = mode.toUpperCase();
|
||||
int result;
|
||||
if (mode.equals("ECB")) {
|
||||
this.blockMode = MODE_ECB;
|
||||
result = MODE_ECB;
|
||||
} else if (mode.equals("CBC")) {
|
||||
if (blockSize == 0) {
|
||||
throw new NoSuchAlgorithmException
|
||||
("CBC mode not supported with stream ciphers");
|
||||
}
|
||||
this.blockMode = MODE_CBC;
|
||||
result = MODE_CBC;
|
||||
} else {
|
||||
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
protected void engineSetPadding(String padding)
|
||||
throws NoSuchPaddingException {
|
||||
if (padding.equalsIgnoreCase("NoPadding")) {
|
||||
paddingObj = null;
|
||||
padBuffer = null;
|
||||
padding = padding.toUpperCase();
|
||||
if (padding.equals("NOPADDING")) {
|
||||
paddingType = PAD_NONE;
|
||||
} else if (padding.equalsIgnoreCase("PKCS5Padding")) {
|
||||
if (blockSize == 0) {
|
||||
throw new NoSuchPaddingException
|
||||
("PKCS#5 padding not supported with stream ciphers");
|
||||
}
|
||||
} else if (padding.equals("PKCS5PADDING")) {
|
||||
paddingType = PAD_PKCS5;
|
||||
// XXX PKCS#5 not yet implemented
|
||||
throw new NoSuchPaddingException("pkcs5");
|
||||
if (mechanism != CKM_DES_CBC_PAD && mechanism != CKM_DES3_CBC_PAD &&
|
||||
mechanism != CKM_AES_CBC_PAD) {
|
||||
// no native padding support; use our own padding impl
|
||||
paddingObj = new PKCS5Padding(blockSize);
|
||||
padBuffer = new byte[blockSize];
|
||||
}
|
||||
} else {
|
||||
throw new NoSuchPaddingException("Unsupported padding " + padding);
|
||||
}
|
||||
@ -175,7 +251,7 @@ final class P11Cipher extends CipherSpi {
|
||||
|
||||
// see JCE spec
|
||||
protected byte[] engineGetIV() {
|
||||
return (iv == null) ? null : (byte[])iv.clone();
|
||||
return (iv == null) ? null : (byte[]) iv.clone();
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
@ -185,8 +261,9 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||
try {
|
||||
AlgorithmParameters params = AlgorithmParameters.getInstance
|
||||
(keyAlgorithm, P11Util.getSunJceProvider());
|
||||
AlgorithmParameters params =
|
||||
AlgorithmParameters.getInstance(keyAlgorithm,
|
||||
P11Util.getSunJceProvider());
|
||||
params.init(ivSpec);
|
||||
return params;
|
||||
} catch (GeneralSecurityException e) {
|
||||
@ -210,38 +287,38 @@ final class P11Cipher extends CipherSpi {
|
||||
protected void engineInit(int opmode, Key key,
|
||||
AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
byte[] iv;
|
||||
byte[] ivValue;
|
||||
if (params != null) {
|
||||
if (params instanceof IvParameterSpec == false) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Only IvParameterSpec supported");
|
||||
}
|
||||
IvParameterSpec ivSpec = (IvParameterSpec)params;
|
||||
iv = ivSpec.getIV();
|
||||
IvParameterSpec ivSpec = (IvParameterSpec) params;
|
||||
ivValue = ivSpec.getIV();
|
||||
} else {
|
||||
iv = null;
|
||||
ivValue = null;
|
||||
}
|
||||
implInit(opmode, key, iv, random);
|
||||
implInit(opmode, key, ivValue, random);
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
protected void engineInit(int opmode, Key key, AlgorithmParameters params,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
byte[] iv;
|
||||
byte[] ivValue;
|
||||
if (params != null) {
|
||||
try {
|
||||
IvParameterSpec ivSpec = (IvParameterSpec)
|
||||
params.getParameterSpec(IvParameterSpec.class);
|
||||
iv = ivSpec.getIV();
|
||||
ivValue = ivSpec.getIV();
|
||||
} catch (InvalidParameterSpecException e) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Could not decode IV", e);
|
||||
}
|
||||
} else {
|
||||
iv = null;
|
||||
ivValue = null;
|
||||
}
|
||||
implInit(opmode, key, iv, random);
|
||||
implInit(opmode, key, ivValue, random);
|
||||
}
|
||||
|
||||
// actual init() implementation
|
||||
@ -250,31 +327,31 @@ final class P11Cipher extends CipherSpi {
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
cancelOperation();
|
||||
switch (opmode) {
|
||||
case Cipher.ENCRYPT_MODE:
|
||||
encrypt = true;
|
||||
break;
|
||||
case Cipher.DECRYPT_MODE:
|
||||
encrypt = false;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported mode: " + opmode);
|
||||
case Cipher.ENCRYPT_MODE:
|
||||
encrypt = true;
|
||||
break;
|
||||
case Cipher.DECRYPT_MODE:
|
||||
encrypt = false;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported mode: " + opmode);
|
||||
}
|
||||
if (blockMode == MODE_ECB) { // ECB or stream cipher
|
||||
if (iv != null) {
|
||||
if (blockSize == 0) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("IV not used with stream ciphers");
|
||||
("IV not used with stream ciphers");
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("IV not used in ECB mode");
|
||||
("IV not used in ECB mode");
|
||||
}
|
||||
}
|
||||
} else { // MODE_CBC
|
||||
if (iv == null) {
|
||||
if (encrypt == false) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("IV must be specified for decryption in CBC mode");
|
||||
("IV must be specified for decryption in CBC mode");
|
||||
}
|
||||
// generate random IV
|
||||
if (random == null) {
|
||||
@ -285,7 +362,7 @@ final class P11Cipher extends CipherSpi {
|
||||
} else {
|
||||
if (iv.length != blockSize) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("IV length must match block size");
|
||||
("IV length must match block size");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -331,63 +408,43 @@ final class P11Cipher extends CipherSpi {
|
||||
session = token.getOpSession();
|
||||
}
|
||||
if (encrypt) {
|
||||
token.p11.C_EncryptInit
|
||||
(session.id(), new CK_MECHANISM(mechanism, iv), p11Key.keyID);
|
||||
token.p11.C_EncryptInit(session.id(),
|
||||
new CK_MECHANISM(mechanism, iv), p11Key.keyID);
|
||||
} else {
|
||||
token.p11.C_DecryptInit
|
||||
(session.id(), new CK_MECHANISM(mechanism, iv), p11Key.keyID);
|
||||
token.p11.C_DecryptInit(session.id(),
|
||||
new CK_MECHANISM(mechanism, iv), p11Key.keyID);
|
||||
}
|
||||
bytesProcessed = 0;
|
||||
bytesBuffered = 0;
|
||||
padBufferLen = 0;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
// XXX the calculations below assume the PKCS#11 implementation is smart.
|
||||
// conceivably, not all implementations are and we may need to estimate
|
||||
// more conservatively
|
||||
|
||||
private int bytesBuffered(int totalLen) {
|
||||
if (paddingType == PAD_NONE) {
|
||||
// with NoPadding, buffer only the current unfinished block
|
||||
return totalLen & (blockSize - 1);
|
||||
} else { // PKCS5
|
||||
// with PKCS5Padding in decrypt mode, the buffer must never
|
||||
// be empty. Buffer a full block instead of nothing.
|
||||
int buffered = totalLen & (blockSize - 1);
|
||||
if ((buffered == 0) && (encrypt == false)) {
|
||||
buffered = blockSize;
|
||||
}
|
||||
return buffered;
|
||||
}
|
||||
}
|
||||
|
||||
// if update(inLen) is called, how big does the output buffer have to be?
|
||||
private int updateLength(int inLen) {
|
||||
if (inLen <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (blockSize == 0) {
|
||||
return inLen;
|
||||
} else {
|
||||
// bytes that need to be buffered now
|
||||
int buffered = bytesBuffered(bytesProcessed);
|
||||
// bytes that need to be buffered after this update
|
||||
int newBuffered = bytesBuffered(bytesProcessed + inLen);
|
||||
return inLen + buffered - newBuffered;
|
||||
|
||||
int result = inLen + bytesBuffered;
|
||||
if (blockSize != 0) {
|
||||
// minus the number of bytes in the last incomplete block.
|
||||
result -= (result & (blockSize - 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// if doFinal(inLen) is called, how big does the output buffer have to be?
|
||||
private int doFinalLength(int inLen) {
|
||||
if (paddingType == PAD_NONE) {
|
||||
return updateLength(inLen);
|
||||
}
|
||||
if (inLen < 0) {
|
||||
return 0;
|
||||
}
|
||||
int buffered = bytesBuffered(bytesProcessed);
|
||||
int newProcessed = bytesProcessed + inLen;
|
||||
int paddedProcessed = (newProcessed + blockSize) & ~(blockSize - 1);
|
||||
return paddedProcessed - bytesProcessed + buffered;
|
||||
|
||||
int result = inLen + bytesBuffered;
|
||||
if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
|
||||
// add the number of bytes to make the last block complete.
|
||||
result += (blockSize - (result & (blockSize - 1)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
@ -397,6 +454,7 @@ final class P11Cipher extends CipherSpi {
|
||||
int n = engineUpdate(in, inOfs, inLen, out, 0);
|
||||
return P11Util.convert(out, 0, n);
|
||||
} catch (ShortBufferException e) {
|
||||
// convert since the output length is calculated by updateLength()
|
||||
throw new ProviderException(e);
|
||||
}
|
||||
}
|
||||
@ -409,6 +467,7 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
@Override
|
||||
protected int engineUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
|
||||
throws ShortBufferException {
|
||||
return implUpdate(inBuffer, outBuffer);
|
||||
@ -422,14 +481,15 @@ final class P11Cipher extends CipherSpi {
|
||||
int n = engineDoFinal(in, inOfs, inLen, out, 0);
|
||||
return P11Util.convert(out, 0, n);
|
||||
} catch (ShortBufferException e) {
|
||||
// convert since the output length is calculated by doFinalLength()
|
||||
throw new ProviderException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
|
||||
int outOfs) throws ShortBufferException, IllegalBlockSizeException {
|
||||
// BadPaddingException {
|
||||
int outOfs) throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
int n = 0;
|
||||
if ((inLen != 0) && (in != null)) {
|
||||
n = engineUpdate(in, inOfs, inLen, out, outOfs);
|
||||
@ -440,8 +500,10 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
@Override
|
||||
protected int engineDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
|
||||
throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
|
||||
throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
int n = engineUpdate(inBuffer, outBuffer);
|
||||
n += implDoFinal(outBuffer);
|
||||
return n;
|
||||
@ -454,18 +516,55 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
try {
|
||||
ensureInitialized();
|
||||
int k;
|
||||
int k = 0;
|
||||
if (encrypt) {
|
||||
k = token.p11.C_EncryptUpdate
|
||||
(session.id(), 0, in, inOfs, inLen, 0, out, outOfs, outLen);
|
||||
k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen,
|
||||
0, out, outOfs, outLen);
|
||||
} else {
|
||||
k = token.p11.C_DecryptUpdate
|
||||
(session.id(), 0, in, inOfs, inLen, 0, out, outOfs, outLen);
|
||||
int newPadBufferLen = 0;
|
||||
if (paddingObj != null) {
|
||||
if (padBufferLen != 0) {
|
||||
// NSS throws up when called with data not in multiple
|
||||
// of blocks. Try to work around this by holding the
|
||||
// extra data in padBuffer.
|
||||
if (padBufferLen != padBuffer.length) {
|
||||
int bufCapacity = padBuffer.length - padBufferLen;
|
||||
if (inLen > bufCapacity) {
|
||||
bufferInputBytes(in, inOfs, bufCapacity);
|
||||
inOfs += bufCapacity;
|
||||
inLen -= bufCapacity;
|
||||
} else {
|
||||
bufferInputBytes(in, inOfs, inLen);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
k = token.p11.C_DecryptUpdate(session.id(),
|
||||
0, padBuffer, 0, padBufferLen,
|
||||
0, out, outOfs, outLen);
|
||||
padBufferLen = 0;
|
||||
}
|
||||
newPadBufferLen = inLen & (blockSize - 1);
|
||||
if (newPadBufferLen == 0) {
|
||||
newPadBufferLen = padBuffer.length;
|
||||
}
|
||||
inLen -= newPadBufferLen;
|
||||
}
|
||||
if (inLen > 0) {
|
||||
k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
|
||||
inLen, 0, out, (outOfs + k), (outLen - k));
|
||||
}
|
||||
// update 'padBuffer' if using our own padding impl.
|
||||
if (paddingObj != null) {
|
||||
bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
|
||||
}
|
||||
}
|
||||
bytesProcessed += inLen;
|
||||
bytesBuffered += (inLen - k);
|
||||
return k;
|
||||
} catch (PKCS11Exception e) {
|
||||
// XXX throw correct exception
|
||||
if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
|
||||
throw (ShortBufferException)
|
||||
(new ShortBufferException().initCause(e));
|
||||
}
|
||||
throw new ProviderException("update() failed", e);
|
||||
}
|
||||
}
|
||||
@ -481,101 +580,167 @@ final class P11Cipher extends CipherSpi {
|
||||
if (outLen < updateLength(inLen)) {
|
||||
throw new ShortBufferException();
|
||||
}
|
||||
boolean inPosChanged = false;
|
||||
int origPos = inBuffer.position();
|
||||
try {
|
||||
ensureInitialized();
|
||||
|
||||
long inAddr = 0;
|
||||
int inOfs = inBuffer.position();
|
||||
int inOfs = 0;
|
||||
byte[] inArray = null;
|
||||
|
||||
if (inBuffer instanceof DirectBuffer) {
|
||||
inAddr = ((DirectBuffer)inBuffer).address();
|
||||
} else {
|
||||
if (inBuffer.hasArray()) {
|
||||
inArray = inBuffer.array();
|
||||
inOfs += inBuffer.arrayOffset();
|
||||
} else {
|
||||
inArray = new byte[inLen];
|
||||
inBuffer.get(inArray);
|
||||
inOfs = 0;
|
||||
inPosChanged = true;
|
||||
}
|
||||
inAddr = ((DirectBuffer) inBuffer).address();
|
||||
inOfs = origPos;
|
||||
} else if (inBuffer.hasArray()) {
|
||||
inArray = inBuffer.array();
|
||||
inOfs = (origPos + inBuffer.arrayOffset());
|
||||
}
|
||||
|
||||
long outAddr = 0;
|
||||
int outOfs = outBuffer.position();
|
||||
int outOfs = 0;
|
||||
byte[] outArray = null;
|
||||
if (outBuffer instanceof DirectBuffer) {
|
||||
outAddr = ((DirectBuffer)outBuffer).address();
|
||||
outAddr = ((DirectBuffer) outBuffer).address();
|
||||
outOfs = outBuffer.position();
|
||||
} else {
|
||||
if (outBuffer.hasArray()) {
|
||||
outArray = outBuffer.array();
|
||||
outOfs += outBuffer.arrayOffset();
|
||||
outOfs = (outBuffer.position() + outBuffer.arrayOffset());
|
||||
} else {
|
||||
outArray = new byte[outLen];
|
||||
outOfs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int k;
|
||||
int k = 0;
|
||||
if (encrypt) {
|
||||
k = token.p11.C_EncryptUpdate
|
||||
(session.id(), inAddr, inArray, inOfs, inLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
if (inAddr == 0 && inArray == null) {
|
||||
inArray = new byte[inLen];
|
||||
inBuffer.get(inArray);
|
||||
} else {
|
||||
inBuffer.position(origPos + inLen);
|
||||
}
|
||||
k = token.p11.C_EncryptUpdate(session.id(),
|
||||
inAddr, inArray, inOfs, inLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
} else {
|
||||
k = token.p11.C_DecryptUpdate
|
||||
(session.id(), inAddr, inArray, inOfs, inLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
}
|
||||
bytesProcessed += inLen;
|
||||
if (!inPosChanged) {
|
||||
inBuffer.position(inBuffer.position() + inLen);
|
||||
int newPadBufferLen = 0;
|
||||
if (paddingObj != null) {
|
||||
if (padBufferLen != 0) {
|
||||
// NSS throws up when called with data not in multiple
|
||||
// of blocks. Try to work around this by holding the
|
||||
// extra data in padBuffer.
|
||||
if (padBufferLen != padBuffer.length) {
|
||||
int bufCapacity = padBuffer.length - padBufferLen;
|
||||
if (inLen > bufCapacity) {
|
||||
bufferInputBytes(inBuffer, bufCapacity);
|
||||
inOfs += bufCapacity;
|
||||
inLen -= bufCapacity;
|
||||
} else {
|
||||
bufferInputBytes(inBuffer, inLen);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
k = token.p11.C_DecryptUpdate(session.id(), 0,
|
||||
padBuffer, 0, padBufferLen, outAddr, outArray,
|
||||
outOfs, outLen);
|
||||
padBufferLen = 0;
|
||||
}
|
||||
newPadBufferLen = inLen & (blockSize - 1);
|
||||
if (newPadBufferLen == 0) {
|
||||
newPadBufferLen = padBuffer.length;
|
||||
}
|
||||
inLen -= newPadBufferLen;
|
||||
}
|
||||
if (inLen > 0) {
|
||||
if (inAddr == 0 && inArray == null) {
|
||||
inArray = new byte[inLen];
|
||||
inBuffer.get(inArray);
|
||||
} else {
|
||||
inBuffer.position(inBuffer.position() + inLen);
|
||||
}
|
||||
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
|
||||
inArray, inOfs, inLen, outAddr, outArray,
|
||||
(outOfs + k), (outLen - k));
|
||||
}
|
||||
// update 'padBuffer' if using our own padding impl.
|
||||
if (paddingObj != null && newPadBufferLen != 0) {
|
||||
bufferInputBytes(inBuffer, newPadBufferLen);
|
||||
}
|
||||
}
|
||||
bytesBuffered += (inLen - k);
|
||||
if (!(outBuffer instanceof DirectBuffer) &&
|
||||
!outBuffer.hasArray()) {
|
||||
!outBuffer.hasArray()) {
|
||||
outBuffer.put(outArray, outOfs, k);
|
||||
} else {
|
||||
outBuffer.position(outBuffer.position() + k);
|
||||
}
|
||||
return k;
|
||||
} catch (PKCS11Exception e) {
|
||||
// Un-read the bytes back to input buffer
|
||||
if (inPosChanged) {
|
||||
inBuffer.position(inBuffer.position() - inLen);
|
||||
// Reset input buffer to its original position for
|
||||
inBuffer.position(origPos);
|
||||
if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
|
||||
throw (ShortBufferException)
|
||||
(new ShortBufferException().initCause(e));
|
||||
}
|
||||
// XXX throw correct exception
|
||||
throw new ProviderException("update() failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
private int implDoFinal(byte[] out, int outOfs, int outLen)
|
||||
throws ShortBufferException, IllegalBlockSizeException {
|
||||
if (outLen < doFinalLength(0)) {
|
||||
throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
int requiredOutLen = doFinalLength(0);
|
||||
if (outLen < requiredOutLen) {
|
||||
throw new ShortBufferException();
|
||||
}
|
||||
try {
|
||||
ensureInitialized();
|
||||
int k = 0;
|
||||
if (encrypt) {
|
||||
return token.p11.C_EncryptFinal
|
||||
(session.id(), 0, out, outOfs, outLen);
|
||||
if (paddingObj != null) {
|
||||
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
|
||||
requiredOutLen - bytesBuffered);
|
||||
k = token.p11.C_EncryptUpdate(session.id(),
|
||||
0, padBuffer, 0, actualPadLen,
|
||||
0, out, outOfs, outLen);
|
||||
}
|
||||
k += token.p11.C_EncryptFinal(session.id(),
|
||||
0, out, (outOfs + k), (outLen - k));
|
||||
} else {
|
||||
return token.p11.C_DecryptFinal
|
||||
(session.id(), 0, out, outOfs, outLen);
|
||||
if (paddingObj != null) {
|
||||
if (padBufferLen != 0) {
|
||||
k = token.p11.C_DecryptUpdate(session.id(), 0,
|
||||
padBuffer, 0, padBufferLen, 0, padBuffer, 0,
|
||||
padBuffer.length);
|
||||
}
|
||||
k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
|
||||
padBuffer.length - k);
|
||||
int actualPadLen = paddingObj.unpad(padBuffer, k);
|
||||
k -= actualPadLen;
|
||||
System.arraycopy(padBuffer, 0, out, outOfs, k);
|
||||
} else {
|
||||
k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
|
||||
outLen);
|
||||
}
|
||||
}
|
||||
return k;
|
||||
} catch (PKCS11Exception e) {
|
||||
handleException(e);
|
||||
throw new ProviderException("doFinal() failed", e);
|
||||
} finally {
|
||||
initialized = false;
|
||||
bytesProcessed = 0;
|
||||
bytesBuffered = 0;
|
||||
padBufferLen = 0;
|
||||
session = token.releaseSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
private int implDoFinal(ByteBuffer outBuffer)
|
||||
throws ShortBufferException, IllegalBlockSizeException {
|
||||
throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
int outLen = outBuffer.remaining();
|
||||
if (outLen < doFinalLength(0)) {
|
||||
int requiredOutLen = doFinalLength(0);
|
||||
if (outLen < requiredOutLen) {
|
||||
throw new ShortBufferException();
|
||||
}
|
||||
|
||||
@ -583,30 +748,54 @@ final class P11Cipher extends CipherSpi {
|
||||
ensureInitialized();
|
||||
|
||||
long outAddr = 0;
|
||||
int outOfs = outBuffer.position();
|
||||
byte[] outArray = null;
|
||||
int outOfs = 0;
|
||||
if (outBuffer instanceof DirectBuffer) {
|
||||
outAddr = ((DirectBuffer)outBuffer).address();
|
||||
outAddr = ((DirectBuffer) outBuffer).address();
|
||||
outOfs = outBuffer.position();
|
||||
} else {
|
||||
if (outBuffer.hasArray()) {
|
||||
outArray = outBuffer.array();
|
||||
outOfs += outBuffer.arrayOffset();
|
||||
outOfs = outBuffer.position() + outBuffer.arrayOffset();
|
||||
} else {
|
||||
outArray = new byte[outLen];
|
||||
outOfs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int k;
|
||||
int k = 0;
|
||||
|
||||
if (encrypt) {
|
||||
k = token.p11.C_EncryptFinal
|
||||
(session.id(), outAddr, outArray, outOfs, outLen);
|
||||
if (paddingObj != null) {
|
||||
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
|
||||
requiredOutLen - bytesBuffered);
|
||||
k = token.p11.C_EncryptUpdate(session.id(),
|
||||
0, padBuffer, 0, actualPadLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
}
|
||||
k += token.p11.C_EncryptFinal(session.id(),
|
||||
outAddr, outArray, (outOfs + k), (outLen - k));
|
||||
} else {
|
||||
k = token.p11.C_DecryptFinal
|
||||
(session.id(), outAddr, outArray, outOfs, outLen);
|
||||
if (paddingObj != null) {
|
||||
if (padBufferLen != 0) {
|
||||
k = token.p11.C_DecryptUpdate(session.id(),
|
||||
0, padBuffer, 0, padBufferLen,
|
||||
0, padBuffer, 0, padBuffer.length);
|
||||
padBufferLen = 0;
|
||||
}
|
||||
k += token.p11.C_DecryptFinal(session.id(),
|
||||
0, padBuffer, k, padBuffer.length - k);
|
||||
int actualPadLen = paddingObj.unpad(padBuffer, k);
|
||||
k -= actualPadLen;
|
||||
outArray = padBuffer;
|
||||
outOfs = 0;
|
||||
} else {
|
||||
k = token.p11.C_DecryptFinal(session.id(),
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
}
|
||||
}
|
||||
if (!(outBuffer instanceof DirectBuffer) &&
|
||||
!outBuffer.hasArray()) {
|
||||
if ((!encrypt && paddingObj != null) ||
|
||||
(!(outBuffer instanceof DirectBuffer) &&
|
||||
!outBuffer.hasArray())) {
|
||||
outBuffer.put(outArray, outOfs, k);
|
||||
} else {
|
||||
outBuffer.position(outBuffer.position() + k);
|
||||
@ -617,20 +806,22 @@ final class P11Cipher extends CipherSpi {
|
||||
throw new ProviderException("doFinal() failed", e);
|
||||
} finally {
|
||||
initialized = false;
|
||||
bytesProcessed = 0;
|
||||
bytesBuffered = 0;
|
||||
session = token.releaseSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleException(PKCS11Exception e)
|
||||
throws IllegalBlockSizeException {
|
||||
throws ShortBufferException, IllegalBlockSizeException {
|
||||
long errorCode = e.getErrorCode();
|
||||
// XXX better check
|
||||
if (errorCode == CKR_DATA_LEN_RANGE) {
|
||||
throw (IllegalBlockSizeException)new
|
||||
IllegalBlockSizeException(e.toString()).initCause(e);
|
||||
if (errorCode == CKR_BUFFER_TOO_SMALL) {
|
||||
throw (ShortBufferException)
|
||||
(new ShortBufferException().initCause(e));
|
||||
} else if (errorCode == CKR_DATA_LEN_RANGE ||
|
||||
errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
|
||||
throw (IllegalBlockSizeException)
|
||||
(new IllegalBlockSizeException(e.toString()).initCause(e));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
@ -649,12 +840,14 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
@Override
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
int n = P11SecretKeyFactory.convertKey
|
||||
(token, key, keyAlgorithm).keyLength();
|
||||
(token, key, keyAlgorithm).keyLength();
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if ((session != null) && token.isValid()) {
|
||||
@ -666,4 +859,15 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
}
|
||||
|
||||
private final void bufferInputBytes(byte[] in, int inOfs, int len) {
|
||||
System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
|
||||
padBufferLen += len;
|
||||
bytesBuffered += len;
|
||||
}
|
||||
|
||||
private final void bufferInputBytes(ByteBuffer inBuffer, int len) {
|
||||
inBuffer.get(padBuffer, padBufferLen, len);
|
||||
padBufferLen += len;
|
||||
bytesBuffered += len;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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
|
||||
@ -65,10 +65,86 @@ final class P11KeyGenerator extends KeyGeneratorSpi {
|
||||
// are supported.
|
||||
private boolean supportBothKeySizes;
|
||||
|
||||
// min and max key sizes (in bits) for variable-key-length
|
||||
// algorithms, e.g. RC4 and Blowfish
|
||||
private int minKeySize;
|
||||
private int maxKeySize;
|
||||
/**
|
||||
* Utility method for checking if the specified key size is valid
|
||||
* and within the supported range. Return the significant key size
|
||||
* upon successful validation.
|
||||
* @param keyGenMech the PKCS#11 key generation mechanism.
|
||||
* @param keySize the to-be-checked key size for this mechanism.
|
||||
* @param token token which provides this mechanism.
|
||||
* @return the significant key size (in bits) corresponding to the
|
||||
* specified key size.
|
||||
* @throws InvalidParameterException if the specified key size is invalid.
|
||||
* @throws ProviderException if this mechanism isn't supported by SunPKCS11
|
||||
* or underlying native impl.
|
||||
*/
|
||||
static int checkKeySize(long keyGenMech, int keySize, Token token)
|
||||
throws InvalidAlgorithmParameterException, ProviderException {
|
||||
int sigKeySize;
|
||||
switch ((int)keyGenMech) {
|
||||
case (int)CKM_DES_KEY_GEN:
|
||||
if ((keySize != 64) && (keySize != 56)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("DES key length must be 56 bits");
|
||||
}
|
||||
sigKeySize = 56;
|
||||
break;
|
||||
case (int)CKM_DES2_KEY_GEN:
|
||||
case (int)CKM_DES3_KEY_GEN:
|
||||
if ((keySize == 112) || (keySize == 128)) {
|
||||
sigKeySize = 112;
|
||||
} else if ((keySize == 168) || (keySize == 192)) {
|
||||
sigKeySize = 168;
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("DESede key length must be 112, or 168 bits");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Handle all variable-key-length algorithms here
|
||||
CK_MECHANISM_INFO info = null;
|
||||
try {
|
||||
info = token.getMechanismInfo(keyGenMech);
|
||||
} catch (PKCS11Exception p11e) {
|
||||
// Should never happen
|
||||
throw new ProviderException
|
||||
("Cannot retrieve mechanism info", p11e);
|
||||
}
|
||||
if (info == null) {
|
||||
// XXX Unable to retrieve the supported key length from
|
||||
// the underlying native impl. Skip the checking for now.
|
||||
return keySize;
|
||||
}
|
||||
// PKCS#11 defines these to be in number of bytes except for
|
||||
// RC4 which is in bits. However, some PKCS#11 impls still use
|
||||
// bytes for all mechs, e.g. NSS. We try to detect this
|
||||
// inconsistency if the minKeySize seems unreasonably small.
|
||||
int minKeySize = (int)info.ulMinKeySize;
|
||||
int maxKeySize = (int)info.ulMaxKeySize;
|
||||
if (keyGenMech != CKM_RC4_KEY_GEN || minKeySize < 8) {
|
||||
minKeySize = (int)info.ulMinKeySize << 3;
|
||||
maxKeySize = (int)info.ulMaxKeySize << 3;
|
||||
}
|
||||
// Explicitly disallow keys shorter than 40-bits for security
|
||||
if (minKeySize < 40) minKeySize = 40;
|
||||
if (keySize < minKeySize || keySize > maxKeySize) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Key length must be between " + minKeySize +
|
||||
" and " + maxKeySize + " bits");
|
||||
}
|
||||
if (keyGenMech == CKM_AES_KEY_GEN) {
|
||||
if ((keySize != 128) && (keySize != 192) &&
|
||||
(keySize != 256)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("AES key length must be " + minKeySize +
|
||||
(maxKeySize >= 192? ", 192":"") +
|
||||
(maxKeySize >= 256? ", or 256":"") + " bits");
|
||||
}
|
||||
}
|
||||
sigKeySize = keySize;
|
||||
}
|
||||
return sigKeySize;
|
||||
}
|
||||
|
||||
P11KeyGenerator(Token token, String algorithm, long mechanism)
|
||||
throws PKCS11Exception {
|
||||
@ -85,72 +161,44 @@ final class P11KeyGenerator extends KeyGeneratorSpi {
|
||||
supportBothKeySizes =
|
||||
(token.provider.config.isEnabled(CKM_DES2_KEY_GEN) &&
|
||||
(token.getMechanismInfo(CKM_DES2_KEY_GEN) != null));
|
||||
} else if (this.mechanism == CKM_RC4_KEY_GEN) {
|
||||
CK_MECHANISM_INFO info = token.getMechanismInfo(mechanism);
|
||||
// Although PKCS#11 spec documented that these are in bits,
|
||||
// NSS, for one, uses bytes. Multiple by 8 if the number seems
|
||||
// unreasonably small.
|
||||
if (info.ulMinKeySize < 8) {
|
||||
minKeySize = (int)info.ulMinKeySize << 3;
|
||||
maxKeySize = (int)info.ulMaxKeySize << 3;
|
||||
} else {
|
||||
minKeySize = (int)info.ulMinKeySize;
|
||||
maxKeySize = (int)info.ulMaxKeySize;
|
||||
}
|
||||
// Explicitly disallow keys shorter than 40-bits for security
|
||||
if (minKeySize < 40) minKeySize = 40;
|
||||
} else if (this.mechanism == CKM_BLOWFISH_KEY_GEN) {
|
||||
CK_MECHANISM_INFO info = token.getMechanismInfo(mechanism);
|
||||
maxKeySize = (int)info.ulMaxKeySize << 3;
|
||||
minKeySize = (int)info.ulMinKeySize << 3;
|
||||
// Explicitly disallow keys shorter than 40-bits for security
|
||||
if (minKeySize < 40) minKeySize = 40;
|
||||
}
|
||||
|
||||
setDefaultKeySize();
|
||||
}
|
||||
|
||||
// set default keysize and also initialize keyType
|
||||
private void setDefaultKeySize() {
|
||||
// whether to check default key size against the min and max value
|
||||
boolean validateKeySize = false;
|
||||
switch ((int)mechanism) {
|
||||
case (int)CKM_DES_KEY_GEN:
|
||||
keySize = 64;
|
||||
significantKeySize = 56;
|
||||
keyType = CKK_DES;
|
||||
break;
|
||||
case (int)CKM_DES2_KEY_GEN:
|
||||
keySize = 128;
|
||||
significantKeySize = 112;
|
||||
keyType = CKK_DES2;
|
||||
break;
|
||||
case (int)CKM_DES3_KEY_GEN:
|
||||
keySize = 192;
|
||||
significantKeySize = 168;
|
||||
keyType = CKK_DES3;
|
||||
break;
|
||||
case (int)CKM_AES_KEY_GEN:
|
||||
keyType = CKK_AES;
|
||||
keySize = 128;
|
||||
significantKeySize = 128;
|
||||
keyType = CKK_AES;
|
||||
break;
|
||||
case (int)CKM_RC4_KEY_GEN:
|
||||
keyType = CKK_RC4;
|
||||
keySize = 128;
|
||||
validateKeySize = true;
|
||||
keyType = CKK_RC4;
|
||||
break;
|
||||
case (int)CKM_BLOWFISH_KEY_GEN:
|
||||
keyType = CKK_BLOWFISH;
|
||||
keySize = 128;
|
||||
validateKeySize = true;
|
||||
keyType = CKK_BLOWFISH;
|
||||
break;
|
||||
default:
|
||||
throw new ProviderException("Unknown mechanism " + mechanism);
|
||||
}
|
||||
if (validateKeySize &&
|
||||
((keySize > maxKeySize) || (keySize < minKeySize))) {
|
||||
throw new ProviderException("Unsupported key size");
|
||||
try {
|
||||
significantKeySize = checkKeySize(mechanism, keySize, token);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new ProviderException("Unsupported default key size", iape);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,57 +218,32 @@ final class P11KeyGenerator extends KeyGeneratorSpi {
|
||||
// see JCE spec
|
||||
protected void engineInit(int keySize, SecureRandom random) {
|
||||
token.ensureValid();
|
||||
switch ((int)mechanism) {
|
||||
case (int)CKM_DES_KEY_GEN:
|
||||
if ((keySize != this.keySize) &&
|
||||
(keySize != this.significantKeySize)) {
|
||||
throw new InvalidParameterException
|
||||
("DES key length must be 56 bits");
|
||||
}
|
||||
break;
|
||||
case (int)CKM_DES2_KEY_GEN:
|
||||
case (int)CKM_DES3_KEY_GEN:
|
||||
long newMechanism;
|
||||
if ((keySize == 112) || (keySize == 128)) {
|
||||
newMechanism = CKM_DES2_KEY_GEN;
|
||||
} else if ((keySize == 168) || (keySize == 192)) {
|
||||
newMechanism = CKM_DES3_KEY_GEN;
|
||||
} else {
|
||||
throw new InvalidParameterException
|
||||
("DESede key length must be 112, or 168 bits");
|
||||
}
|
||||
int newSignificantKeySize;
|
||||
try {
|
||||
newSignificantKeySize = checkKeySize(mechanism, keySize, token);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw (InvalidParameterException)
|
||||
(new InvalidParameterException().initCause(iape));
|
||||
}
|
||||
if ((mechanism == CKM_DES2_KEY_GEN) ||
|
||||
(mechanism == CKM_DES3_KEY_GEN)) {
|
||||
long newMechanism = (newSignificantKeySize == 112 ?
|
||||
CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN);
|
||||
if (mechanism != newMechanism) {
|
||||
if (supportBothKeySizes) {
|
||||
mechanism = newMechanism;
|
||||
setDefaultKeySize();
|
||||
// Adjust keyType to reflect the mechanism change
|
||||
keyType = (mechanism == CKM_DES2_KEY_GEN ?
|
||||
CKK_DES2 : CKK_DES3);
|
||||
} else {
|
||||
throw new InvalidParameterException
|
||||
("Only " + significantKeySize +
|
||||
"-bit DESede key length is supported");
|
||||
("Only " + significantKeySize +
|
||||
"-bit DESede is supported");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (int)CKM_AES_KEY_GEN:
|
||||
if ((keySize != 128) && (keySize != 192) && (keySize != 256)) {
|
||||
throw new InvalidParameterException
|
||||
("AES key length must be 128, 192, or 256 bits");
|
||||
}
|
||||
this.keySize = keySize;
|
||||
significantKeySize = keySize;
|
||||
break;
|
||||
case (int)CKM_RC4_KEY_GEN:
|
||||
case (int)CKM_BLOWFISH_KEY_GEN:
|
||||
if ((keySize < minKeySize) || (keySize > maxKeySize)) {
|
||||
throw new InvalidParameterException
|
||||
(algorithm + " key length must be between " +
|
||||
minKeySize + " and " + maxKeySize + " bits");
|
||||
}
|
||||
this.keySize = keySize;
|
||||
this.significantKeySize = keySize;
|
||||
break;
|
||||
default:
|
||||
throw new ProviderException("Unknown mechanism " + mechanism);
|
||||
}
|
||||
this.keySize = keySize;
|
||||
this.significantKeySize = newSignificantKeySize;
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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
|
||||
@ -156,10 +156,10 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
// CKA_CLASS - entry type
|
||||
private CK_ATTRIBUTE type = null;
|
||||
|
||||
// CKA_LABEL of cert
|
||||
// CKA_LABEL of cert and secret key
|
||||
private String label = null;
|
||||
|
||||
// CKA_ID - of private key/cert
|
||||
// CKA_ID of the private key/cert pair
|
||||
private byte[] id = null;
|
||||
|
||||
// CKA_TRUSTED - true if cert is trusted
|
||||
@ -871,10 +871,8 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
|
||||
token.provider.login(null, handler);
|
||||
} else {
|
||||
|
||||
// token supports protected authentication path
|
||||
// (external pin-pad, for example)
|
||||
|
||||
if (handler != null &&
|
||||
!token.config.getKeyStoreCompatibilityMode()) {
|
||||
throw new LoginException("can not specify password if token " +
|
||||
@ -1130,19 +1128,14 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
SecretKey skey = ske.getSecretKey();
|
||||
|
||||
try {
|
||||
// first see if the key already exists.
|
||||
// if so, update the CKA_LABEL
|
||||
if (!updateSkey(alias)) {
|
||||
|
||||
// key entry does not exist.
|
||||
// delete existing entry for alias and
|
||||
// create new secret key entry
|
||||
// (new entry might be a secret key
|
||||
// session object converted into a token object)
|
||||
// first check if the key already exists
|
||||
AliasInfo aliasInfo = aliasMap.get(alias);
|
||||
|
||||
if (aliasInfo != null) {
|
||||
engineDeleteEntry(alias);
|
||||
storeSkey(alias, ske);
|
||||
}
|
||||
storeSkey(alias, ske);
|
||||
|
||||
} catch (PKCS11Exception pe) {
|
||||
throw new KeyStoreException(pe);
|
||||
}
|
||||
@ -1396,41 +1389,6 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if update occurred
|
||||
*/
|
||||
private boolean updateSkey(String alias)
|
||||
throws KeyStoreException, PKCS11Exception {
|
||||
|
||||
Session session = null;
|
||||
try {
|
||||
session = token.getOpSession();
|
||||
|
||||
// first update existing secret key CKA_LABEL
|
||||
|
||||
THandle h = getTokenObject(session, ATTR_CLASS_SKEY, null, alias);
|
||||
if (h.type != ATTR_CLASS_SKEY) {
|
||||
if (debug != null) {
|
||||
debug.println("did not find secret key " +
|
||||
"with CKA_LABEL [" + alias + "]");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
|
||||
new CK_ATTRIBUTE(CKA_LABEL, alias) };
|
||||
token.p11.C_SetAttributeValue(session.id(), h.handle, attrs);
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("updateSkey set new alias [" +
|
||||
alias +
|
||||
"] for secret key entry");
|
||||
}
|
||||
|
||||
return true;
|
||||
} finally {
|
||||
token.releaseSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX On ibutton, when you C_SetAttribute(CKA_ID) for a private key
|
||||
@ -1532,30 +1490,6 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateP11Skey(String alias, P11Key key)
|
||||
throws PKCS11Exception {
|
||||
|
||||
Session session = null;
|
||||
try {
|
||||
session = token.getOpSession();
|
||||
|
||||
// session key - convert to token key and set CKA_LABEL
|
||||
|
||||
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
|
||||
ATTR_TOKEN_TRUE,
|
||||
new CK_ATTRIBUTE(CKA_LABEL, alias) };
|
||||
token.p11.C_CopyObject(session.id(), key.keyID, attrs);
|
||||
if (debug != null) {
|
||||
debug.println("updateP11Skey copied secret session key " +
|
||||
"for [" +
|
||||
alias +
|
||||
"] to token entry");
|
||||
}
|
||||
} finally {
|
||||
token.releaseSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateP11Pkey(String alias, CK_ATTRIBUTE attribute, P11Key key)
|
||||
throws PKCS11Exception {
|
||||
|
||||
@ -1689,48 +1623,26 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
throws PKCS11Exception, KeyStoreException {
|
||||
|
||||
SecretKey skey = ske.getSecretKey();
|
||||
long keyType = CKK_GENERIC_SECRET;
|
||||
|
||||
if (skey instanceof P11Key && this.token == ((P11Key)skey).token) {
|
||||
updateP11Skey(alias, (P11Key)skey);
|
||||
return;
|
||||
}
|
||||
|
||||
if ("AES".equalsIgnoreCase(skey.getAlgorithm())) {
|
||||
keyType = CKK_AES;
|
||||
} else if ("Blowfish".equalsIgnoreCase(skey.getAlgorithm())) {
|
||||
keyType = CKK_BLOWFISH;
|
||||
} else if ("DES".equalsIgnoreCase(skey.getAlgorithm())) {
|
||||
keyType = CKK_DES;
|
||||
} else if ("DESede".equalsIgnoreCase(skey.getAlgorithm())) {
|
||||
keyType = CKK_DES3;
|
||||
} else if ("RC4".equalsIgnoreCase(skey.getAlgorithm()) ||
|
||||
"ARCFOUR".equalsIgnoreCase(skey.getAlgorithm())) {
|
||||
keyType = CKK_RC4;
|
||||
}
|
||||
|
||||
// No need to specify CKA_CLASS, CKA_KEY_TYPE, CKA_VALUE since
|
||||
// they are handled in P11SecretKeyFactory.createKey() method.
|
||||
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
|
||||
ATTR_SKEY_TOKEN_TRUE,
|
||||
ATTR_CLASS_SKEY,
|
||||
ATTR_PRIVATE_TRUE,
|
||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
|
||||
new CK_ATTRIBUTE(CKA_LABEL, alias),
|
||||
new CK_ATTRIBUTE(CKA_VALUE, skey.getEncoded()) };
|
||||
attrs = token.getAttributes
|
||||
(TemplateManager.O_IMPORT, CKO_SECRET_KEY, keyType, attrs);
|
||||
|
||||
// create the new entry
|
||||
Session session = null;
|
||||
ATTR_SKEY_TOKEN_TRUE,
|
||||
ATTR_PRIVATE_TRUE,
|
||||
new CK_ATTRIBUTE(CKA_LABEL, alias),
|
||||
};
|
||||
try {
|
||||
session = token.getOpSession();
|
||||
token.p11.C_CreateObject(session.id(), attrs);
|
||||
if (debug != null) {
|
||||
debug.println("storeSkey created token secret key for [" +
|
||||
alias +
|
||||
"]");
|
||||
}
|
||||
} finally {
|
||||
token.releaseSession(session);
|
||||
P11SecretKeyFactory.convertKey(token, skey, null, attrs);
|
||||
} catch (InvalidKeyException ike) {
|
||||
// re-throw KeyStoreException to match javadoc
|
||||
throw new KeyStoreException("Cannot convert to PKCS11 keys", ike);
|
||||
}
|
||||
|
||||
// update global alias map
|
||||
aliasMap.put(alias, new AliasInfo(alias));
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("storeSkey created token secret key for [" +
|
||||
alias + "]");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2492,7 +2404,8 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
// if there are duplicates (either between secret keys,
|
||||
// or between a secret key and another object),
|
||||
// throw an exception
|
||||
HashSet<String> sKeySet = new HashSet<String>();
|
||||
HashMap<String, AliasInfo> sKeyMap =
|
||||
new HashMap<String, AliasInfo>();
|
||||
|
||||
attrs = new CK_ATTRIBUTE[] {
|
||||
ATTR_SKEY_TOKEN_TRUE,
|
||||
@ -2507,8 +2420,8 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
|
||||
// there is a CKA_LABEL
|
||||
String cka_label = new String(attrs[0].getCharArray());
|
||||
if (!sKeySet.contains(cka_label)) {
|
||||
sKeySet.add(cka_label);
|
||||
if (sKeyMap.get(cka_label) == null) {
|
||||
sKeyMap.put(cka_label, new AliasInfo(cka_label));
|
||||
} else {
|
||||
throw new KeyStoreException("invalid KeyStore state: " +
|
||||
"found multiple secret keys sharing same " +
|
||||
@ -2523,7 +2436,7 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
ArrayList<AliasInfo> matchedCerts =
|
||||
mapPrivateKeys(pkeyIDs, certMap);
|
||||
boolean sharedLabel = mapCerts(matchedCerts, certMap);
|
||||
mapSecretKeys(sKeySet);
|
||||
mapSecretKeys(sKeyMap);
|
||||
|
||||
return sharedLabel;
|
||||
|
||||
@ -2547,7 +2460,7 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
HashMap<String, HashSet<AliasInfo>> certMap)
|
||||
throws PKCS11Exception, CertificateException {
|
||||
|
||||
// global alias map
|
||||
// reset global alias map
|
||||
aliasMap = new HashMap<String, AliasInfo>();
|
||||
|
||||
// list of matched certs that we will return
|
||||
@ -2722,18 +2635,17 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||
* If the secret key shares a CKA_LABEL with another entry,
|
||||
* throw an exception
|
||||
*/
|
||||
private void mapSecretKeys(HashSet<String> sKeySet)
|
||||
private void mapSecretKeys(HashMap<String, AliasInfo> sKeyMap)
|
||||
throws KeyStoreException {
|
||||
for (String label : sKeySet) {
|
||||
if (!aliasMap.containsKey(label)) {
|
||||
aliasMap.put(label, new AliasInfo(label));
|
||||
} else {
|
||||
for (String label : sKeyMap.keySet()) {
|
||||
if (aliasMap.containsKey(label)) {
|
||||
throw new KeyStoreException("invalid KeyStore state: " +
|
||||
"found secret key sharing CKA_LABEL [" +
|
||||
label +
|
||||
"] with another token object");
|
||||
}
|
||||
}
|
||||
aliasMap.putAll(sKeyMap);
|
||||
}
|
||||
|
||||
private void dumpTokenMap() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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
|
||||
@ -98,7 +98,6 @@ final class P11RSACipher extends CipherSpi {
|
||||
this.token = token;
|
||||
this.algorithm = "RSA";
|
||||
this.mechanism = mechanism;
|
||||
session = token.getOpSession();
|
||||
}
|
||||
|
||||
// modes do not make sense for RSA, but allow ECB
|
||||
@ -184,7 +183,8 @@ final class P11RSACipher extends CipherSpi {
|
||||
throw new InvalidKeyException
|
||||
("Wrap has to be used with public keys");
|
||||
}
|
||||
// No further setup needed for C_Wrap(). We remain uninitialized.
|
||||
// No further setup needed for C_Wrap(). We'll initialize later if
|
||||
// we can't use C_Wrap().
|
||||
return;
|
||||
} else if (opmode == Cipher.UNWRAP_MODE) {
|
||||
if (p11Key.isPrivate() == false) {
|
||||
@ -383,7 +383,8 @@ final class P11RSACipher extends CipherSpi {
|
||||
return implDoFinal(out, outOfs, out.length - outOfs);
|
||||
}
|
||||
|
||||
private byte[] doFinal() throws BadPaddingException, IllegalBlockSizeException {
|
||||
private byte[] doFinal() throws BadPaddingException,
|
||||
IllegalBlockSizeException {
|
||||
byte[] t = new byte[2048];
|
||||
int n = implDoFinal(t, 0, t.length);
|
||||
byte[] out = new byte[n];
|
||||
@ -394,20 +395,37 @@ final class P11RSACipher extends CipherSpi {
|
||||
// see JCE spec
|
||||
protected byte[] engineWrap(Key key) throws InvalidKeyException,
|
||||
IllegalBlockSizeException {
|
||||
// XXX Note that if we cannot convert key to a key on this token,
|
||||
// we will fail. For example, trying a wrap an AES key on a token that
|
||||
// does not support AES.
|
||||
// We could implement a fallback that just encrypts the encoding
|
||||
// (assuming the key is not sensitive). For now, we are operating under
|
||||
// the assumption that this is not necessary.
|
||||
String keyAlg = key.getAlgorithm();
|
||||
P11Key secretKey = P11SecretKeyFactory.convertKey(token, key, keyAlg);
|
||||
P11Key sKey = null;
|
||||
try {
|
||||
// The conversion may fail, e.g. trying to wrap an AES key on
|
||||
// a token that does not support AES, or when the key size is
|
||||
// not within the range supported by the token.
|
||||
sKey = P11SecretKeyFactory.convertKey(token, key, keyAlg);
|
||||
} catch (InvalidKeyException ike) {
|
||||
byte[] toBeWrappedKey = key.getEncoded();
|
||||
if (toBeWrappedKey == null) {
|
||||
throw new InvalidKeyException
|
||||
("wrap() failed, no encoding available", ike);
|
||||
}
|
||||
// Directly encrypt the key encoding when key conversion failed
|
||||
implInit(Cipher.ENCRYPT_MODE, p11Key);
|
||||
implUpdate(toBeWrappedKey, 0, toBeWrappedKey.length);
|
||||
try {
|
||||
return doFinal();
|
||||
} catch (BadPaddingException bpe) {
|
||||
// should not occur
|
||||
throw new InvalidKeyException("wrap() failed", bpe);
|
||||
} finally {
|
||||
// Restore original mode
|
||||
implInit(Cipher.WRAP_MODE, p11Key);
|
||||
}
|
||||
}
|
||||
Session s = null;
|
||||
try {
|
||||
s = token.getOpSession();
|
||||
byte[] b = token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism),
|
||||
p11Key.keyID, secretKey.keyID);
|
||||
return b;
|
||||
return token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism),
|
||||
p11Key.keyID, sKey.keyID);
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new InvalidKeyException("wrap() failed", e);
|
||||
} finally {
|
||||
@ -431,11 +449,13 @@ final class P11RSACipher extends CipherSpi {
|
||||
};
|
||||
attributes = token.getAttributes
|
||||
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
|
||||
long keyID = token.p11.C_UnwrapKey(s.id(), new CK_MECHANISM(mechanism),
|
||||
p11Key.keyID, wrappedKey, attributes);
|
||||
return P11Key.secretKey(session, keyID, algorithm, 48 << 3, attributes);
|
||||
long keyID = token.p11.C_UnwrapKey(s.id(),
|
||||
new CK_MECHANISM(mechanism), p11Key.keyID, wrappedKey,
|
||||
attributes);
|
||||
return P11Key.secretKey(session, keyID, algorithm, 48 << 3,
|
||||
attributes);
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new InvalidKeyException("wrap() failed", e);
|
||||
throw new InvalidKeyException("unwrap() failed", e);
|
||||
} finally {
|
||||
token.releaseSession(s);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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
|
||||
@ -104,9 +104,20 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
|
||||
|
||||
/**
|
||||
* Convert an arbitrary key of algorithm into a P11Key of provider.
|
||||
* Used engineTranslateKey(), P11Cipher.init(), and P11Mac.init().
|
||||
* Used in engineTranslateKey(), P11Cipher.init(), and P11Mac.init().
|
||||
*/
|
||||
static P11Key convertKey(Token token, Key key, String algorithm)
|
||||
static P11Key convertKey(Token token, Key key, String algo)
|
||||
throws InvalidKeyException {
|
||||
return convertKey(token, key, algo, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an arbitrary key of algorithm w/ custom attributes into a
|
||||
* P11Key of provider.
|
||||
* Used in P11KeyStore.storeSkey.
|
||||
*/
|
||||
static P11Key convertKey(Token token, Key key, String algo,
|
||||
CK_ATTRIBUTE[] extraAttrs)
|
||||
throws InvalidKeyException {
|
||||
token.ensureValid();
|
||||
if (key == null) {
|
||||
@ -115,25 +126,41 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
|
||||
if (key instanceof SecretKey == false) {
|
||||
throw new InvalidKeyException("Key must be a SecretKey");
|
||||
}
|
||||
long algorithmType;
|
||||
if (algorithm == null) {
|
||||
algorithm = key.getAlgorithm();
|
||||
algorithmType = getKeyType(algorithm);
|
||||
long algoType;
|
||||
if (algo == null) {
|
||||
algo = key.getAlgorithm();
|
||||
algoType = getKeyType(algo);
|
||||
} else {
|
||||
algorithmType = getKeyType(algorithm);
|
||||
algoType = getKeyType(algo);
|
||||
long keyAlgorithmType = getKeyType(key.getAlgorithm());
|
||||
if (algorithmType != keyAlgorithmType) {
|
||||
if ((algorithmType == PCKK_HMAC) || (algorithmType == PCKK_SSLMAC)) {
|
||||
if (algoType != keyAlgorithmType) {
|
||||
if ((algoType == PCKK_HMAC) || (algoType == PCKK_SSLMAC)) {
|
||||
// ignore key algorithm for MACs
|
||||
} else {
|
||||
throw new InvalidKeyException
|
||||
("Key algorithm must be " + algorithm);
|
||||
("Key algorithm must be " + algo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key instanceof P11Key) {
|
||||
P11Key p11Key = (P11Key)key;
|
||||
if (p11Key.token == token) {
|
||||
if (extraAttrs != null) {
|
||||
Session session = null;
|
||||
try {
|
||||
session = token.getObjSession();
|
||||
long newKeyID = token.p11.C_CopyObject(session.id(),
|
||||
p11Key.keyID, extraAttrs);
|
||||
p11Key = (P11Key) (P11Key.secretKey(p11Key.session,
|
||||
newKeyID, p11Key.algorithm, p11Key.keyLength,
|
||||
extraAttrs));
|
||||
} catch (PKCS11Exception p11e) {
|
||||
throw new InvalidKeyException
|
||||
("Cannot duplicate the PKCS11 key", p11e);
|
||||
} finally {
|
||||
token.releaseSession(session);
|
||||
}
|
||||
}
|
||||
return p11Key;
|
||||
}
|
||||
}
|
||||
@ -141,11 +168,11 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
|
||||
if (p11Key != null) {
|
||||
return p11Key;
|
||||
}
|
||||
if ("RAW".equals(key.getFormat()) == false) {
|
||||
if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
|
||||
throw new InvalidKeyException("Encoded format must be RAW");
|
||||
}
|
||||
byte[] encoded = key.getEncoded();
|
||||
p11Key = createKey(token, encoded, algorithm, algorithmType);
|
||||
p11Key = createKey(token, encoded, algo, algoType, extraAttrs);
|
||||
token.secretCache.put(key, p11Key);
|
||||
return p11Key;
|
||||
}
|
||||
@ -159,79 +186,79 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
|
||||
}
|
||||
|
||||
private static P11Key createKey(Token token, byte[] encoded,
|
||||
String algorithm, long keyType) throws InvalidKeyException {
|
||||
int n = encoded.length;
|
||||
int keyLength;
|
||||
switch ((int)keyType) {
|
||||
case (int)CKK_RC4:
|
||||
if ((n < 5) || (n > 128)) {
|
||||
throw new InvalidKeyException
|
||||
("ARCFOUR key length must be between 5 and 128 bytes");
|
||||
String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs)
|
||||
throws InvalidKeyException {
|
||||
int n = encoded.length << 3;
|
||||
int keyLength = n;
|
||||
try {
|
||||
switch ((int)keyType) {
|
||||
case (int)CKK_DES:
|
||||
keyLength =
|
||||
P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token);
|
||||
fixDESParity(encoded, 0);
|
||||
break;
|
||||
case (int)CKK_DES3:
|
||||
keyLength =
|
||||
P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token);
|
||||
fixDESParity(encoded, 0);
|
||||
fixDESParity(encoded, 8);
|
||||
if (keyLength == 112) {
|
||||
keyType = CKK_DES2;
|
||||
} else {
|
||||
keyType = CKK_DES3;
|
||||
fixDESParity(encoded, 16);
|
||||
}
|
||||
break;
|
||||
case (int)CKK_AES:
|
||||
keyLength =
|
||||
P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token);
|
||||
break;
|
||||
case (int)CKK_RC4:
|
||||
keyLength =
|
||||
P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token);
|
||||
break;
|
||||
case (int)CKK_BLOWFISH:
|
||||
keyLength =
|
||||
P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n,
|
||||
token);
|
||||
break;
|
||||
case (int)CKK_GENERIC_SECRET:
|
||||
case (int)PCKK_TLSPREMASTER:
|
||||
case (int)PCKK_TLSRSAPREMASTER:
|
||||
case (int)PCKK_TLSMASTER:
|
||||
keyType = CKK_GENERIC_SECRET;
|
||||
break;
|
||||
case (int)PCKK_SSLMAC:
|
||||
case (int)PCKK_HMAC:
|
||||
if (n == 0) {
|
||||
throw new InvalidKeyException
|
||||
("MAC keys must not be empty");
|
||||
}
|
||||
keyType = CKK_GENERIC_SECRET;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidKeyException("Unknown algorithm " +
|
||||
algorithm);
|
||||
}
|
||||
keyLength = n << 3;
|
||||
break;
|
||||
case (int)CKK_DES:
|
||||
if (n != 8) {
|
||||
throw new InvalidKeyException
|
||||
("DES key length must be 8 bytes");
|
||||
}
|
||||
keyLength = 56;
|
||||
fixDESParity(encoded, 0);
|
||||
break;
|
||||
case (int)CKK_DES3:
|
||||
if (n == 16) {
|
||||
keyType = CKK_DES2;
|
||||
} else if (n == 24) {
|
||||
keyType = CKK_DES3;
|
||||
fixDESParity(encoded, 16);
|
||||
} else {
|
||||
throw new InvalidKeyException
|
||||
("DESede key length must be 16 or 24 bytes");
|
||||
}
|
||||
fixDESParity(encoded, 0);
|
||||
fixDESParity(encoded, 8);
|
||||
keyLength = n * 7;
|
||||
break;
|
||||
case (int)CKK_AES:
|
||||
if ((n != 16) && (n != 24) && (n != 32)) {
|
||||
throw new InvalidKeyException
|
||||
("AES key length must be 16, 24, or 32 bytes");
|
||||
}
|
||||
keyLength = n << 3;
|
||||
break;
|
||||
case (int)CKK_BLOWFISH:
|
||||
if ((n < 5) || (n > 56)) {
|
||||
throw new InvalidKeyException
|
||||
("Blowfish key length must be between 5 and 56 bytes");
|
||||
}
|
||||
keyLength = n << 3;
|
||||
break;
|
||||
case (int)CKK_GENERIC_SECRET:
|
||||
case (int)PCKK_TLSPREMASTER:
|
||||
case (int)PCKK_TLSRSAPREMASTER:
|
||||
case (int)PCKK_TLSMASTER:
|
||||
keyType = CKK_GENERIC_SECRET;
|
||||
keyLength = n << 3;
|
||||
break;
|
||||
case (int)PCKK_SSLMAC:
|
||||
case (int)PCKK_HMAC:
|
||||
if (n == 0) {
|
||||
throw new InvalidKeyException
|
||||
("MAC keys must not be empty");
|
||||
}
|
||||
keyType = CKK_GENERIC_SECRET;
|
||||
keyLength = n << 3;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidKeyException("Unknown algorithm " + algorithm);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidKeyException("Invalid key for " + algorithm,
|
||||
iape);
|
||||
} catch (ProviderException pe) {
|
||||
throw new InvalidKeyException("Could not create key", pe);
|
||||
}
|
||||
Session session = null;
|
||||
try {
|
||||
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
|
||||
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
|
||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
|
||||
new CK_ATTRIBUTE(CKA_VALUE, encoded),
|
||||
};
|
||||
CK_ATTRIBUTE[] attributes;
|
||||
if (extraAttrs != null) {
|
||||
attributes = new CK_ATTRIBUTE[3 + extraAttrs.length];
|
||||
System.arraycopy(extraAttrs, 0, attributes, 3,
|
||||
extraAttrs.length);
|
||||
} else {
|
||||
attributes = new CK_ATTRIBUTE[3];
|
||||
}
|
||||
attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
|
||||
attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType);
|
||||
attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
|
||||
attributes = token.getAttributes
|
||||
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
|
||||
session = token.getObjSession();
|
||||
@ -280,7 +307,7 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
|
||||
private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException {
|
||||
try {
|
||||
key = engineTranslateKey(key);
|
||||
if ("RAW".equals(key.getFormat()) == false) {
|
||||
if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
|
||||
throw new InvalidKeySpecException
|
||||
("Could not obtain key bytes");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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
|
||||
@ -601,14 +601,26 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
// XXX attributes for Ciphers (supported modes, padding)
|
||||
d(CIP, "ARCFOUR", P11Cipher, s("RC4"),
|
||||
m(CKM_RC4));
|
||||
// XXX only CBC/NoPadding for block ciphers
|
||||
d(CIP, "DES/CBC/NoPadding", P11Cipher,
|
||||
m(CKM_DES_CBC));
|
||||
d(CIP, "DES/CBC/PKCS5Padding", P11Cipher,
|
||||
m(CKM_DES_CBC_PAD, CKM_DES_CBC));
|
||||
d(CIP, "DES/ECB", P11Cipher, s("DES"),
|
||||
m(CKM_DES_ECB));
|
||||
|
||||
d(CIP, "DESede/CBC/NoPadding", P11Cipher,
|
||||
m(CKM_DES3_CBC));
|
||||
d(CIP, "DESede/CBC/PKCS5Padding", P11Cipher,
|
||||
m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
|
||||
d(CIP, "DESede/ECB", P11Cipher, s("DESede"),
|
||||
m(CKM_DES3_ECB));
|
||||
d(CIP, "AES/CBC/NoPadding", P11Cipher,
|
||||
m(CKM_AES_CBC));
|
||||
d(CIP, "Blowfish/CBC/NoPadding", P11Cipher,
|
||||
d(CIP, "AES/CBC/PKCS5Padding", P11Cipher,
|
||||
m(CKM_AES_CBC_PAD, CKM_AES_CBC));
|
||||
d(CIP, "AES/ECB", P11Cipher, s("AES"),
|
||||
m(CKM_AES_ECB));
|
||||
d(CIP, "Blowfish/CBC", P11Cipher,
|
||||
m(CKM_BLOWFISH_CBC));
|
||||
|
||||
// XXX RSA_X_509, RSA_OAEP not yet supported
|
||||
|
@ -87,6 +87,9 @@ class EndEntityChecker {
|
||||
// the Microsoft Server-Gated-Cryptography EKU extension OID
|
||||
private final static String OID_EKU_MS_SGC = "1.3.6.1.4.1.311.10.3.3";
|
||||
|
||||
// the recognized extension OIDs
|
||||
private final static String OID_SUBJECT_ALT_NAME = "2.5.29.17";
|
||||
|
||||
private final static String NSCT_SSL_CLIENT =
|
||||
NetscapeCertTypeExtension.SSL_CLIENT;
|
||||
|
||||
@ -171,6 +174,13 @@ class EndEntityChecker {
|
||||
throws CertificateException {
|
||||
// basic constraints irrelevant in EE certs
|
||||
exts.remove(SimpleValidator.OID_BASIC_CONSTRAINTS);
|
||||
|
||||
// If the subject field contains an empty sequence, the subjectAltName
|
||||
// extension MUST be marked critical.
|
||||
// We do not check the validity of the critical extension, just mark
|
||||
// it recognizable here.
|
||||
exts.remove(OID_SUBJECT_ALT_NAME);
|
||||
|
||||
if (!exts.isEmpty()) {
|
||||
throw new CertificateException("Certificate contains unsupported "
|
||||
+ "critical extensions: " + exts);
|
||||
|
@ -626,6 +626,7 @@ appendClassPath( JPLISAgent* agent,
|
||||
jvmtiError jvmtierr;
|
||||
|
||||
jvmtierr = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, jarfile);
|
||||
check_phase_ret_1(jvmtierr);
|
||||
|
||||
if (jvmtierr == JVMTI_ERROR_NONE) {
|
||||
return 0;
|
||||
@ -634,6 +635,7 @@ appendClassPath( JPLISAgent* agent,
|
||||
jvmtiError err;
|
||||
|
||||
err = (*jvmtienv)->GetPhase(jvmtienv, &phase);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(err == JVMTI_ERROR_NONE);
|
||||
|
||||
if (phase == JVMTI_PHASE_LIVE) {
|
||||
@ -805,6 +807,8 @@ appendBootClassPath( JPLISAgent* agent,
|
||||
|
||||
/* print warning if boot class path not updated */
|
||||
if (jvmtierr != JVMTI_ERROR_NONE) {
|
||||
check_phase_blob_ret(jvmtierr, free(path));
|
||||
|
||||
fprintf(stderr, "WARNING: %s not added to bootstrap class loader search: ", path);
|
||||
switch (jvmtierr) {
|
||||
case JVMTI_ERROR_ILLEGAL_ARGUMENT :
|
||||
|
@ -179,6 +179,7 @@ getJPLISEnvironment(jvmtiEnv * jvmtienv) {
|
||||
jvmtierror = (*jvmtienv)->GetEnvironmentLocalStorage(
|
||||
jvmtienv,
|
||||
(void**)&environment);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
|
||||
if (jvmtierror == JVMTI_ERROR_NONE) {
|
||||
@ -230,6 +231,7 @@ createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr) {
|
||||
/* don't leak envs */
|
||||
if ( initerror != JPLIS_INIT_ERROR_NONE ) {
|
||||
jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
@ -259,7 +261,7 @@ initializeJPLISAgent( JPLISAgent * agent,
|
||||
agent->mNormalEnvironment.mIsRetransformer = JNI_FALSE;
|
||||
agent->mRetransformEnvironment.mJVMTIEnv = NULL; /* NULL until needed */
|
||||
agent->mRetransformEnvironment.mAgent = agent;
|
||||
agent->mRetransformEnvironment.mIsRetransformer = JNI_TRUE;
|
||||
agent->mRetransformEnvironment.mIsRetransformer = JNI_FALSE; /* JNI_FALSE until mJVMTIEnv is set */
|
||||
agent->mAgentmainCaller = NULL;
|
||||
agent->mInstrumentationImpl = NULL;
|
||||
agent->mPremainCaller = NULL;
|
||||
@ -277,18 +279,25 @@ initializeJPLISAgent( JPLISAgent * agent,
|
||||
jvmtierror = (*jvmtienv)->SetEnvironmentLocalStorage(
|
||||
jvmtienv,
|
||||
&(agent->mNormalEnvironment));
|
||||
/* can be called from any phase */
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
|
||||
/* check what capabilities are available */
|
||||
checkCapabilities(agent);
|
||||
|
||||
/* check phase - if live phase then we don't need the VMInit event */
|
||||
jvmtierror == (*jvmtienv)->GetPhase(jvmtienv, &phase);
|
||||
jvmtierror = (*jvmtienv)->GetPhase(jvmtienv, &phase);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
if (phase == JVMTI_PHASE_LIVE) {
|
||||
return JPLIS_INIT_ERROR_NONE;
|
||||
}
|
||||
|
||||
if (phase != JVMTI_PHASE_ONLOAD) {
|
||||
/* called too early or called too late; either way bail out */
|
||||
return JPLIS_INIT_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* now turn on the VMInit event */
|
||||
if ( jvmtierror == JVMTI_ERROR_NONE ) {
|
||||
jvmtiEventCallbacks callbacks;
|
||||
@ -298,6 +307,7 @@ initializeJPLISAgent( JPLISAgent * agent,
|
||||
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
|
||||
&callbacks,
|
||||
sizeof(callbacks));
|
||||
check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
}
|
||||
|
||||
@ -307,6 +317,7 @@ initializeJPLISAgent( JPLISAgent * agent,
|
||||
JVMTI_ENABLE,
|
||||
JVMTI_EVENT_VM_INIT,
|
||||
NULL /* all threads */);
|
||||
check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
}
|
||||
|
||||
@ -622,6 +633,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
|
||||
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
|
||||
&callbacks,
|
||||
sizeof(callbacks));
|
||||
check_phase_ret_false(jvmtierror);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
|
||||
|
||||
@ -632,6 +644,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
|
||||
JVMTI_DISABLE,
|
||||
JVMTI_EVENT_VM_INIT,
|
||||
NULL /* all threads */);
|
||||
check_phase_ret_false(jvmtierror);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
}
|
||||
|
||||
@ -642,6 +655,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
|
||||
JVMTI_ENABLE,
|
||||
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
|
||||
NULL /* all threads */);
|
||||
check_phase_ret_false(jvmtierror);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
}
|
||||
|
||||
@ -660,6 +674,7 @@ checkCapabilities(JPLISAgent * agent) {
|
||||
memset(&potentialCapabilities, 0, sizeof(potentialCapabilities));
|
||||
|
||||
jvmtierror = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &potentialCapabilities);
|
||||
check_phase_ret(jvmtierror);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
|
||||
if ( jvmtierror == JVMTI_ERROR_NONE ) {
|
||||
@ -681,9 +696,11 @@ enableNativeMethodPrefixCapability(jvmtiEnv * jvmtienv) {
|
||||
jvmtiError jvmtierror;
|
||||
|
||||
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
desiredCapabilities.can_set_native_method_prefix = 1;
|
||||
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
||||
check_phase_ret(jvmtierror);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
}
|
||||
|
||||
@ -715,9 +732,11 @@ addOriginalMethodOrderCapability(JPLISAgent * agent) {
|
||||
jvmtiError jvmtierror;
|
||||
|
||||
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
desiredCapabilities.can_maintain_original_method_order = 1;
|
||||
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
||||
check_phase_ret(jvmtierror);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
}
|
||||
|
||||
@ -732,9 +751,11 @@ addRedefineClassesCapability(JPLISAgent * agent) {
|
||||
|
||||
if (agent->mRedefineAvailable && !agent->mRedefineAdded) {
|
||||
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
desiredCapabilities.can_redefine_classes = 1;
|
||||
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
||||
check_phase_ret(jvmtierror);
|
||||
|
||||
/*
|
||||
* With mixed premain/agentmain agents then it's possible that the
|
||||
@ -998,6 +1019,7 @@ retransformableEnvironment(JPLISAgent * agent) {
|
||||
if (jvmtierror == JVMTI_ERROR_NONE) {
|
||||
// install the retransforming environment
|
||||
agent->mRetransformEnvironment.mJVMTIEnv = retransformerEnv;
|
||||
agent->mRetransformEnvironment.mIsRetransformer = JNI_TRUE;
|
||||
|
||||
// Make it for ClassFileLoadHook handling
|
||||
jvmtierror = (*retransformerEnv)->SetEnvironmentLocalStorage(
|
||||
@ -1025,6 +1047,7 @@ isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz) {
|
||||
jvmtierror = (*jvmtienv)->IsModifiableClass( jvmtienv,
|
||||
clazz,
|
||||
&is_modifiable);
|
||||
check_phase_ret_false(jvmtierror);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
|
||||
return is_modifiable;
|
||||
@ -1032,7 +1055,7 @@ isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz) {
|
||||
|
||||
jboolean
|
||||
isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent) {
|
||||
return retransformableEnvironment(agent) != NULL;
|
||||
return agent->mRetransformEnvironment.mIsRetransformer;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1075,6 +1098,12 @@ retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes) {
|
||||
numClasses = (*jnienv)->GetArrayLength(jnienv, classes);
|
||||
errorOccurred = checkForThrowable(jnienv);
|
||||
jplis_assert(!errorOccurred);
|
||||
|
||||
if (!errorOccurred && numClasses == 0) {
|
||||
jplis_assert(numClasses != 0);
|
||||
errorOccurred = JNI_TRUE;
|
||||
errorCode = JVMTI_ERROR_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
if (!errorOccurred) {
|
||||
@ -1096,6 +1125,13 @@ retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes) {
|
||||
if (errorOccurred) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (classArray[index] == NULL) {
|
||||
jplis_assert(classArray[index] != NULL);
|
||||
errorOccurred = JNI_TRUE;
|
||||
errorCode = JVMTI_ERROR_NULL_POINTER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1217,6 +1253,7 @@ redefineClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitio
|
||||
if (!errorOccurred) {
|
||||
jvmtiError errorCode = JVMTI_ERROR_NONE;
|
||||
errorCode = (*jvmtienv)->RedefineClasses(jvmtienv, numDefs, classDefs);
|
||||
check_phase_blob_ret(errorCode, deallocate(jvmtienv, (void*)classDefs));
|
||||
errorOccurred = (errorCode != JVMTI_ERROR_NONE);
|
||||
if ( errorOccurred ) {
|
||||
createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
|
||||
@ -1250,6 +1287,7 @@ commonGetClassList( JNIEnv * jnienv,
|
||||
classLoader,
|
||||
&classCount,
|
||||
&classes);
|
||||
check_phase_ret_blob(jvmtierror, localArray);
|
||||
errorOccurred = (jvmtierror != JVMTI_ERROR_NONE);
|
||||
jplis_assert(!errorOccurred);
|
||||
|
||||
@ -1311,6 +1349,7 @@ getObjectSize(JNIEnv * jnienv, JPLISAgent * agent, jobject objectToSize) {
|
||||
jvmtiError jvmtierror = JVMTI_ERROR_NONE;
|
||||
|
||||
jvmtierror = (*jvmtienv)->GetObjectSize(jvmtienv, objectToSize, &objectSize);
|
||||
check_phase_ret_0(jvmtierror);
|
||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||
if ( jvmtierror != JVMTI_ERROR_NONE ) {
|
||||
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
|
||||
@ -1360,6 +1399,7 @@ appendToClassLoaderSearch(JNIEnv * jnienv, JPLISAgent * agent, jstring jarFile,
|
||||
} else {
|
||||
jvmtierror = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, platformChars);
|
||||
}
|
||||
check_phase_ret(jvmtierror);
|
||||
|
||||
if ( jvmtierror != JVMTI_ERROR_NONE ) {
|
||||
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
|
||||
@ -1450,6 +1490,7 @@ setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefix
|
||||
}
|
||||
|
||||
err = (*jvmtienv)->SetNativeMethodPrefixes(jvmtienv, inx, (char**)prefixes);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(err == JVMTI_ERROR_NONE);
|
||||
|
||||
for (i = 0; i < inx; i++) {
|
||||
|
@ -266,6 +266,48 @@ setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefix
|
||||
|
||||
#define jvmti(a) a->mNormalEnvironment.mJVMTIEnv
|
||||
|
||||
/*
|
||||
* A set of macros for insulating the JLI method callers from
|
||||
* JVMTI_ERROR_WRONG_PHASE return codes.
|
||||
*/
|
||||
|
||||
/* for a JLI method where "blob" is executed before simply returning */
|
||||
#define check_phase_blob_ret(ret, blob) \
|
||||
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||
blob; \
|
||||
return; \
|
||||
}
|
||||
|
||||
/* for a JLI method where simply returning is benign */
|
||||
#define check_phase_ret(ret) \
|
||||
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||
return; \
|
||||
}
|
||||
|
||||
/* for a JLI method where returning zero (0) is benign */
|
||||
#define check_phase_ret_0(ret) \
|
||||
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
/* for a JLI method where returning one (1) is benign */
|
||||
#define check_phase_ret_1(ret) \
|
||||
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
/* for a case where a specific "blob" must be returned */
|
||||
#define check_phase_ret_blob(ret, blob) \
|
||||
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||
return (blob); \
|
||||
}
|
||||
|
||||
/* for a JLI method where returning false is benign */
|
||||
#define check_phase_ret_false(ret) \
|
||||
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||
return (jboolean) 0; \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
@ -23,6 +23,14 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Win* needs this include. However, Linux and Solaris do not.
|
||||
* Having this include on Solaris SPARC breaks having non US-ASCII
|
||||
* characters in the value of the Premain-Class attribute.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#endif /* _WIN32 */
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -45,11 +53,37 @@ doAttribute(const char* name, const char* value, void* user_data) {
|
||||
if (attribute->name == NULL) {
|
||||
free(attribute);
|
||||
} else {
|
||||
attribute->value = strdup(value);
|
||||
char *begin = (char *)value;
|
||||
char *end;
|
||||
size_t value_len;
|
||||
|
||||
/* skip any leading white space */
|
||||
while (isspace(*begin)) {
|
||||
begin++;
|
||||
}
|
||||
|
||||
/* skip any trailing white space */
|
||||
end = &begin[strlen(begin)];
|
||||
while (end > begin && isspace(end[-1])) {
|
||||
end--;
|
||||
}
|
||||
|
||||
if (begin == end) {
|
||||
/* no value so skip this attribute */
|
||||
free(attribute->name);
|
||||
free(attribute);
|
||||
return;
|
||||
}
|
||||
|
||||
value_len = (size_t)(end - begin);
|
||||
attribute->value = malloc(value_len + 1);
|
||||
if (attribute->value == NULL) {
|
||||
free(attribute->name);
|
||||
free(attribute);
|
||||
} else {
|
||||
/* save the value without leading or trailing whitespace */
|
||||
strncpy(attribute->value, begin, value_len);
|
||||
attribute->value[value_len] = '\0';
|
||||
attribute->next = NULL;
|
||||
if (context->head == NULL) {
|
||||
context->head = attribute;
|
||||
|
@ -74,6 +74,7 @@ confirmingTLSSet( jvmtiEnv * jvmtienv,
|
||||
jvmtienv,
|
||||
thread,
|
||||
newValue);
|
||||
check_phase_ret_blob(error, error);
|
||||
|
||||
#if JPLISASSERT_ENABLEASSERTIONS
|
||||
assertTLSValue( jvmtienv,
|
||||
@ -96,6 +97,7 @@ assertTLSValue( jvmtiEnv * jvmtienv,
|
||||
jvmtienv,
|
||||
thread,
|
||||
&test);
|
||||
check_phase_ret(error);
|
||||
jplis_assert(error == JVMTI_ERROR_NONE);
|
||||
jplis_assert(test == expected);
|
||||
}
|
||||
@ -111,6 +113,7 @@ tryToAcquireReentrancyToken( jvmtiEnv * jvmtienv,
|
||||
jvmtienv,
|
||||
thread,
|
||||
&storedValue);
|
||||
check_phase_ret_false(error);
|
||||
jplis_assert(error == JVMTI_ERROR_NONE);
|
||||
if ( error == JVMTI_ERROR_NONE ) {
|
||||
/* if this thread is already inside, just return false and short-circuit */
|
||||
|
@ -46,6 +46,7 @@ allocate(jvmtiEnv * jvmtienv, size_t bytecount) {
|
||||
error = (*jvmtienv)->Allocate(jvmtienv,
|
||||
bytecount,
|
||||
(unsigned char**) &resultBuffer);
|
||||
/* may be called from any phase */
|
||||
jplis_assert(error == JVMTI_ERROR_NONE);
|
||||
if ( error != JVMTI_ERROR_NONE ) {
|
||||
resultBuffer = NULL;
|
||||
@ -66,6 +67,7 @@ deallocate(jvmtiEnv * jvmtienv, void * buffer) {
|
||||
|
||||
error = (*jvmtienv)->Deallocate(jvmtienv,
|
||||
(unsigned char*)buffer);
|
||||
/* may be called from any phase */
|
||||
jplis_assert_msg(error == JVMTI_ERROR_NONE, "Can't deallocate memory");
|
||||
return;
|
||||
}
|
||||
|
@ -123,7 +123,10 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr);
|
||||
(*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
|
||||
}
|
||||
if ((C_GetFunctionList == NULL) || ((systemErrorMessage = dlerror()) != NULL)){
|
||||
if (C_GetFunctionList == NULL) {
|
||||
throwIOException(env, "ERROR: C_GetFunctionList == NULL");
|
||||
return;
|
||||
} else if ( (systemErrorMessage = dlerror()) != NULL ){
|
||||
throwIOException(env, systemErrorMessage);
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2005 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 6658779
|
||||
* @summary Basic Test for HotSpotDiagnosticMXBean.getDiagnosticOptions()
|
||||
* @author Daniel Fuchs
|
||||
*
|
||||
* @run main GetDiagnosticOptions
|
||||
*/
|
||||
|
||||
import com.sun.management.HotSpotDiagnosticMXBean;
|
||||
import com.sun.management.VMOption;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.List;
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
public class GetDiagnosticOptions {
|
||||
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
|
||||
"com.sun.management:type=HotSpotDiagnostic";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
HotSpotDiagnosticMXBean mbean =
|
||||
sun.management.ManagementFactory.getDiagnosticMXBean();
|
||||
checkDiagnosticOptions(mbean);
|
||||
|
||||
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
||||
mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
|
||||
HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
|
||||
HotSpotDiagnosticMXBean.class);
|
||||
checkDiagnosticOptions(mbean);
|
||||
}
|
||||
|
||||
private static void checkDiagnosticOptions(HotSpotDiagnosticMXBean mbean) {
|
||||
List<VMOption> options = mbean.getDiagnosticOptions();
|
||||
for (VMOption opt : options) {
|
||||
System.out.println("option: "+opt.getName()+"="+opt.getValue());
|
||||
}
|
||||
}
|
||||
}
|
@ -23,8 +23,10 @@
|
||||
|
||||
# @test
|
||||
# @bug 5055293
|
||||
# @summary Test non US-ASCII characters in the value of the Boot-Class-Path
|
||||
# @summary Test non US-ASCII characters in the value of the Boot-Class-Path
|
||||
# attribute.
|
||||
#
|
||||
# @run shell/timeout=240 BootClassPathTest.sh
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
@ -72,7 +74,7 @@ echo "Creating agent jar file..."
|
||||
|
||||
echo "Running test..."
|
||||
|
||||
"${JAVA}" -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
|
||||
"${JAVA}" ${TESTVMOPTS} -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
|
||||
result=$?
|
||||
|
||||
echo "Cleanup..."
|
||||
|
@ -70,9 +70,11 @@ JAR="${TESTJAVA}/bin/jar"
|
||||
cp ${TESTSRC}/${AGENT}.java .
|
||||
cp ${TESTSRC}/${APP}.java .
|
||||
rm -rf ilib
|
||||
cp -r ${TESTSRC}/ilib .
|
||||
mkdir bootpath
|
||||
cp -r ${TESTSRC}/bootreporter bootpath
|
||||
mkdir ilib
|
||||
cp ${TESTSRC}/ilib/*.java ilib
|
||||
rm -rf bootpath
|
||||
mkdir -p bootpath/bootreporter
|
||||
cp ${TESTSRC}/bootreporter/*.java bootpath/bootreporter
|
||||
|
||||
cd bootpath
|
||||
${JAVAC} bootreporter/*.java
|
||||
|
483
jdk/test/java/lang/instrument/ManifestTest.sh
Normal file
483
jdk/test/java/lang/instrument/ManifestTest.sh
Normal file
@ -0,0 +1,483 @@
|
||||
#
|
||||
# Copyright 2008 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 6274276
|
||||
# @summary JLI JAR manifest processing should ignore leading and trailing white space.
|
||||
# @author Daniel D. Daugherty
|
||||
#
|
||||
# @run build ManifestTestApp
|
||||
# @run shell/timeout=900 ManifestTest.sh
|
||||
#
|
||||
|
||||
make_a_JAR() {
|
||||
# version_line and premain_line are required
|
||||
version_line="Manifest-Version: 1.0"
|
||||
premain_line="Premain-Class: ${AGENT}"
|
||||
boot_cp_line=""
|
||||
expect_boot_cp_line="ExampleForBootClassPath was not loaded."
|
||||
can_redef_line=""
|
||||
expect_redef_line="isRedefineClassesSupported()=false"
|
||||
can_retrans_line=""
|
||||
expect_retrans_line="isRetransformClassesSupported()=false"
|
||||
can_set_nmp_line=""
|
||||
expect_set_nmp_line="isNativeMethodPrefixSupported()=false"
|
||||
|
||||
while [ $# != 0 ] ; do
|
||||
case "$1" in
|
||||
defaults)
|
||||
# just use the defaults for the test
|
||||
;;
|
||||
|
||||
boot_cp_line1)
|
||||
boot_cp_line="Boot-Class-Path: no_white_space"
|
||||
expect_boot_cp_line="ExampleForBootClassPath was loaded."
|
||||
mkdir -p no_white_space
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class no_white_space
|
||||
;;
|
||||
|
||||
boot_cp_line2)
|
||||
boot_cp_line="Boot-Class-Path: has_leading_blank"
|
||||
expect_boot_cp_line="ExampleForBootClassPath was loaded."
|
||||
mkdir -p has_leading_blank " has_leading_blank"
|
||||
# the good class is in the directory without the blank
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
|
||||
has_leading_blank
|
||||
# the bad class is in the directory with the blank
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
|
||||
" has_leading_blank"/ExampleForBootClassPath.class
|
||||
;;
|
||||
|
||||
boot_cp_line3)
|
||||
boot_cp_line="Boot-Class-Path: has_trailing_blank "
|
||||
expect_boot_cp_line="ExampleForBootClassPath was loaded."
|
||||
mkdir -p has_trailing_blank "has_trailing_blank "
|
||||
# the good class is in the directory without the blank
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
|
||||
has_trailing_blank
|
||||
# the bad class is in the directory with the blank
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
|
||||
"has_trailing_blank "/ExampleForBootClassPath.class
|
||||
;;
|
||||
|
||||
boot_cp_line4)
|
||||
boot_cp_line="Boot-Class-Path: has_leading_and_trailing_blank "
|
||||
expect_boot_cp_line="ExampleForBootClassPath was loaded."
|
||||
mkdir -p has_leading_and_trailing_blank \
|
||||
" has_leading_and_trailing_blank "
|
||||
# the good class is in the directory without the blanks
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
|
||||
has_leading_and_trailing_blank
|
||||
# the bad class is in the directory with the blanks
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
|
||||
" has_leading_and_trailing_blank "/ExampleForBootClassPath.class
|
||||
;;
|
||||
|
||||
boot_cp_line5)
|
||||
boot_cp_line="Boot-Class-Path: has_embedded blank"
|
||||
expect_boot_cp_line="ExampleForBootClassPath was loaded."
|
||||
mkdir -p has_embedded "has_embedded blank"
|
||||
# the good class is in the first blank separated word
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class has_embedded
|
||||
# the bad class is in the directory with the blank
|
||||
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
|
||||
"has_embedded blank"/ExampleForBootClassPath.class
|
||||
;;
|
||||
|
||||
can_redef_line1)
|
||||
can_redef_line="Can-Redefine-Classes: true"
|
||||
expect_redef_line="isRedefineClassesSupported()=true"
|
||||
;;
|
||||
|
||||
can_redef_line2)
|
||||
can_redef_line="Can-Redefine-Classes: true"
|
||||
expect_redef_line="isRedefineClassesSupported()=true"
|
||||
;;
|
||||
|
||||
can_redef_line3)
|
||||
can_redef_line="Can-Redefine-Classes: true "
|
||||
expect_redef_line="isRedefineClassesSupported()=true"
|
||||
;;
|
||||
|
||||
can_redef_line4)
|
||||
can_redef_line="Can-Redefine-Classes: true "
|
||||
expect_redef_line="isRedefineClassesSupported()=true"
|
||||
;;
|
||||
|
||||
can_redef_line5)
|
||||
can_redef_line="Can-Redefine-Classes: false"
|
||||
;;
|
||||
|
||||
can_redef_line6)
|
||||
can_redef_line="Can-Redefine-Classes: false"
|
||||
;;
|
||||
|
||||
can_redef_line7)
|
||||
can_redef_line="Can-Redefine-Classes: false "
|
||||
;;
|
||||
|
||||
can_redef_line8)
|
||||
can_redef_line="Can-Redefine-Classes: false "
|
||||
;;
|
||||
|
||||
can_redef_line9)
|
||||
# this line makes the jar command unhappy and that's
|
||||
# not what we're testing so skip this case
|
||||
can_redef_line="Can-Redefine-Classes:"
|
||||
;;
|
||||
|
||||
can_redef_line10)
|
||||
can_redef_line="Can-Redefine-Classes: "
|
||||
;;
|
||||
|
||||
can_redef_line11)
|
||||
can_redef_line="Can-Redefine-Classes: "
|
||||
;;
|
||||
|
||||
can_retrans_line1)
|
||||
can_retrans_line="Can-Retransform-Classes: true"
|
||||
expect_retrans_line="isRetransformClassesSupported()=true"
|
||||
;;
|
||||
|
||||
can_retrans_line2)
|
||||
can_retrans_line="Can-Retransform-Classes: true"
|
||||
expect_retrans_line="isRetransformClassesSupported()=true"
|
||||
;;
|
||||
|
||||
can_retrans_line3)
|
||||
can_retrans_line="Can-Retransform-Classes: true "
|
||||
expect_retrans_line="isRetransformClassesSupported()=true"
|
||||
;;
|
||||
|
||||
can_retrans_line4)
|
||||
can_retrans_line="Can-Retransform-Classes: true "
|
||||
expect_retrans_line="isRetransformClassesSupported()=true"
|
||||
;;
|
||||
|
||||
can_retrans_line5)
|
||||
can_retrans_line="Can-Retransform-Classes: false"
|
||||
;;
|
||||
|
||||
can_retrans_line6)
|
||||
can_retrans_line="Can-Retransform-Classes: false"
|
||||
;;
|
||||
|
||||
can_retrans_line7)
|
||||
can_retrans_line="Can-Retransform-Classes: false "
|
||||
;;
|
||||
|
||||
can_retrans_line8)
|
||||
can_retrans_line="Can-Retransform-Classes: false "
|
||||
;;
|
||||
|
||||
can_retrans_line9)
|
||||
# this line makes the jar command unhappy and that's
|
||||
# not what we're testing so skip this case
|
||||
can_retrans_line="Can-Retransform-Classes:"
|
||||
;;
|
||||
|
||||
can_retrans_line10)
|
||||
can_retrans_line="Can-Retransform-Classes: "
|
||||
;;
|
||||
|
||||
can_retrans_line11)
|
||||
can_retrans_line="Can-Retransform-Classes: "
|
||||
;;
|
||||
|
||||
can_set_nmp_line1)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: true"
|
||||
expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
|
||||
;;
|
||||
|
||||
can_set_nmp_line2)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: true"
|
||||
expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
|
||||
;;
|
||||
|
||||
can_set_nmp_line3)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: true "
|
||||
expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
|
||||
;;
|
||||
|
||||
can_set_nmp_line4)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: true "
|
||||
expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
|
||||
;;
|
||||
|
||||
can_set_nmp_line5)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: false"
|
||||
;;
|
||||
|
||||
can_set_nmp_line6)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: false"
|
||||
;;
|
||||
|
||||
can_set_nmp_line7)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: false "
|
||||
;;
|
||||
|
||||
can_set_nmp_line8)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: false "
|
||||
;;
|
||||
|
||||
can_set_nmp_line9)
|
||||
# this line makes the jar command unhappy and that's
|
||||
# not what we're testing so skip this case
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix:"
|
||||
;;
|
||||
|
||||
can_set_nmp_line10)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: "
|
||||
;;
|
||||
|
||||
can_set_nmp_line11)
|
||||
can_set_nmp_line="Can-Set-Native-Method-Prefix: "
|
||||
;;
|
||||
|
||||
premain_line1)
|
||||
premain_line="Premain-Class: ${AGENT}"
|
||||
;;
|
||||
|
||||
premain_line2)
|
||||
premain_line="Premain-Class: ${AGENT} "
|
||||
;;
|
||||
|
||||
premain_line3)
|
||||
premain_line="Premain-Class: ${AGENT} "
|
||||
;;
|
||||
|
||||
version_line1)
|
||||
version_line="Manifest-Version: 1.0"
|
||||
;;
|
||||
|
||||
version_line2)
|
||||
version_line="Manifest-Version: 1.0 "
|
||||
;;
|
||||
|
||||
version_line3)
|
||||
version_line="Manifest-Version: 1.0 "
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "ERROR: invalid test token"
|
||||
exit 1
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
echo "${version_line}" > ${AGENT}.mf
|
||||
echo "${premain_line}" >> ${AGENT}.mf
|
||||
|
||||
if [ -n "$boot_cp_line" ]; then
|
||||
echo "${boot_cp_line}" >> ${AGENT}.mf
|
||||
fi
|
||||
|
||||
if [ -n "$can_redef_line" ]; then
|
||||
echo "${can_redef_line}" >> ${AGENT}.mf
|
||||
fi
|
||||
|
||||
if [ -n "$can_retrans_line" ]; then
|
||||
echo "${can_retrans_line}" >> ${AGENT}.mf
|
||||
fi
|
||||
|
||||
if [ -n "$can_set_nmp_line" ]; then
|
||||
echo "${can_set_nmp_line}" >> ${AGENT}.mf
|
||||
fi
|
||||
|
||||
rm -f ${AGENT}.jar
|
||||
${JAR} cvfm ${AGENT}.jar ${AGENT}.mf ${AGENT}.class
|
||||
|
||||
echo "$expect_boot_cp_line" > expect_boot_cp_line
|
||||
echo "$expect_redef_line" > expect_redef_line
|
||||
echo "$expect_retrans_line" > expect_retrans_line
|
||||
echo "$expect_set_nmp_line" > expect_set_nmp_line
|
||||
}
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAR="${TESTJAVA}/bin/jar"
|
||||
JAVAC="${TESTJAVA}"/bin/javac
|
||||
JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
# Now that ManifestTestApp.class is built, we move
|
||||
# ExampleForBootClassPath.class so that it cannot be found
|
||||
# by default
|
||||
OUT_OF_THE_WAY=out_of_the_way
|
||||
mkdir $OUT_OF_THE_WAY
|
||||
mv "${TESTCLASSES}/ExampleForBootClassPath.class" $OUT_OF_THE_WAY
|
||||
|
||||
# create a bad version of ExampleForBootClassPath.class
|
||||
# so we can tell when the wrong version is run
|
||||
sed 's/return 15/return 42/' "${TESTSRC}"/ExampleForBootClassPath.java \
|
||||
> ExampleForBootClassPath.java
|
||||
"$JAVAC" ExampleForBootClassPath.java
|
||||
mv ExampleForBootClassPath.class \
|
||||
$OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad
|
||||
mv ExampleForBootClassPath.java \
|
||||
$OUT_OF_THE_WAY/ExampleForBootClassPath.java.bad
|
||||
|
||||
AGENT=ManifestTestAgent
|
||||
# We compile the agent in the working directory instead of with
|
||||
# a build task because we construct a different agent JAR file
|
||||
# for each test case.
|
||||
${JAVAC} -d . ${TESTSRC}/${AGENT}.java
|
||||
|
||||
FAIL_MARKER=fail_marker
|
||||
rm -f $FAIL_MARKER
|
||||
|
||||
while read token; do
|
||||
echo
|
||||
echo "===== begin test case: $token ====="
|
||||
make_a_JAR "$token"
|
||||
|
||||
"${JAVA}" ${TESTVMOPTS} -javaagent:${AGENT}.jar \
|
||||
-classpath "${TESTCLASSES}" ManifestTestApp > output.log 2>&1
|
||||
result=$?
|
||||
|
||||
cat output.log
|
||||
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: ManifestTestApp exited with status of 0."
|
||||
else
|
||||
echo "FAIL: ManifestTestApp exited with status of $result"
|
||||
touch $FAIL_MARKER
|
||||
fi
|
||||
|
||||
MESG="Hello from ${AGENT}!"
|
||||
grep -s "$MESG" output.log > /dev/null
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: found '$MESG' in the test output"
|
||||
else
|
||||
echo "FAIL: did NOT find '$MESG' in the test output"
|
||||
touch $FAIL_MARKER
|
||||
fi
|
||||
|
||||
MESG=`cat expect_boot_cp_line`
|
||||
grep -s "$MESG" output.log > /dev/null
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: found '$MESG' in the test output"
|
||||
else
|
||||
echo "FAIL: did NOT find '$MESG' in the test output"
|
||||
touch $FAIL_MARKER
|
||||
fi
|
||||
|
||||
MESG=`cat expect_redef_line`
|
||||
grep -s "$MESG" output.log > /dev/null
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: found '$MESG' in the test output"
|
||||
else
|
||||
echo "FAIL: did NOT find '$MESG' in the test output"
|
||||
touch $FAIL_MARKER
|
||||
fi
|
||||
|
||||
MESG=`cat expect_retrans_line`
|
||||
grep -s "$MESG" output.log > /dev/null
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: found '$MESG' in the test output"
|
||||
else
|
||||
echo "FAIL: did NOT find '$MESG' in the test output"
|
||||
touch $FAIL_MARKER
|
||||
fi
|
||||
|
||||
MESG=`cat expect_set_nmp_line`
|
||||
grep -s "$MESG" output.log > /dev/null
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: found '$MESG' in the test output"
|
||||
else
|
||||
echo "FAIL: did NOT find '$MESG' in the test output"
|
||||
touch $FAIL_MARKER
|
||||
fi
|
||||
|
||||
echo "===== end test case: $token ====="
|
||||
echo
|
||||
done << EOF
|
||||
defaults
|
||||
version_line1
|
||||
version_line2
|
||||
version_line3
|
||||
premain_line1
|
||||
premain_line2
|
||||
premain_line3
|
||||
boot_cp_line1
|
||||
boot_cp_line2
|
||||
boot_cp_line3
|
||||
boot_cp_line4
|
||||
boot_cp_line5
|
||||
can_redef_line1
|
||||
can_redef_line2
|
||||
can_redef_line3
|
||||
can_redef_line4
|
||||
can_redef_line5
|
||||
can_redef_line6
|
||||
can_redef_line7
|
||||
can_redef_line8
|
||||
can_redef_line10
|
||||
can_redef_line11
|
||||
can_retrans_line1
|
||||
can_retrans_line2
|
||||
can_retrans_line3
|
||||
can_retrans_line4
|
||||
can_retrans_line5
|
||||
can_retrans_line6
|
||||
can_retrans_line7
|
||||
can_retrans_line8
|
||||
can_retrans_line10
|
||||
can_retrans_line11
|
||||
can_set_nmp_line1
|
||||
can_set_nmp_line2
|
||||
can_set_nmp_line3
|
||||
can_set_nmp_line4
|
||||
can_set_nmp_line5
|
||||
can_set_nmp_line6
|
||||
can_set_nmp_line7
|
||||
can_set_nmp_line8
|
||||
can_set_nmp_line10
|
||||
can_set_nmp_line11
|
||||
EOF
|
||||
|
||||
if [ -f $FAIL_MARKER ]; then
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
41
jdk/test/java/lang/instrument/ManifestTestAgent.java
Normal file
41
jdk/test/java/lang/instrument/ManifestTestAgent.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
|
||||
public class ManifestTestAgent {
|
||||
private static Instrumentation instrumentation;
|
||||
|
||||
private ManifestTestAgent() {
|
||||
}
|
||||
|
||||
public static void premain(String agentArgs, Instrumentation inst) {
|
||||
System.out.println("Hello from ManifestTestAgent!");
|
||||
System.out.println("isNativeMethodPrefixSupported()=" +
|
||||
inst.isNativeMethodPrefixSupported());
|
||||
System.out.println("isRedefineClassesSupported()=" +
|
||||
inst.isRedefineClassesSupported());
|
||||
System.out.println("isRetransformClassesSupported()=" +
|
||||
inst.isRetransformClassesSupported());
|
||||
}
|
||||
}
|
69
jdk/test/java/lang/instrument/ManifestTestApp.java
Normal file
69
jdk/test/java/lang/instrument/ManifestTestApp.java
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
public class ManifestTestApp {
|
||||
public static void main(String args[]) {
|
||||
System.out.println("Hello from ManifestTestApp!");
|
||||
|
||||
new ManifestTestApp().doTest();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
try {
|
||||
// load the class only found via the Boot-Class-Path attribute
|
||||
Object instance = loadExampleClass();
|
||||
if (instance.getClass().getClassLoader() == null) {
|
||||
System.out.println("PASS: ExampleForBootClassPath was loaded" +
|
||||
" by the boot class path loader.");
|
||||
} else {
|
||||
System.out.println("FAIL: ExampleForBootClassPath was loaded" +
|
||||
" by a non-boot class path loader.");
|
||||
System.exit(1);
|
||||
}
|
||||
} catch (NoClassDefFoundError ncdfe) {
|
||||
// This message just lets ManifestTest.sh know whether or
|
||||
// not ExampleForBootClassPath was loaded. Depending on
|
||||
// the current test case, that will be either a PASSing
|
||||
// condition or a FAILing condition as determined by
|
||||
// ManifestTest.sh.
|
||||
System.out.println("ExampleForBootClassPath was not loaded.");
|
||||
}
|
||||
}
|
||||
|
||||
Object loadExampleClass() {
|
||||
ExampleForBootClassPath instance = new ExampleForBootClassPath();
|
||||
System.out.println("ExampleForBootClassPath was loaded.");
|
||||
if (instance.fifteen() == 15) {
|
||||
System.out.println("PASS: the correct" +
|
||||
" ExampleForBootClassPath was loaded.");
|
||||
} else {
|
||||
System.out.println("FAIL: the wrong ExampleForBootClassPath" +
|
||||
" was loaded.");
|
||||
System.out.println("FAIL: instance.fifteen()=" +
|
||||
instance.fifteen());
|
||||
System.exit(1);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
* @summary test setNativeMethodPrefix
|
||||
* @author Robert Field, Sun Microsystems
|
||||
*
|
||||
* @run shell MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true'
|
||||
* @run shell/timeout=240 MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true'
|
||||
* @run main/othervm -javaagent:NativeMethodPrefixAgent.jar NativeMethodPrefixApp
|
||||
*/
|
||||
|
||||
|
72
jdk/test/java/lang/instrument/ParallelTransformerLoader.sh
Normal file
72
jdk/test/java/lang/instrument/ParallelTransformerLoader.sh
Normal file
@ -0,0 +1,72 @@
|
||||
#
|
||||
# Copyright 2008 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 5088398
|
||||
# @summary Test parallel class loading by parallel transformers.
|
||||
# @author Daniel D. Daugherty as modified from the code of Daryl Puryear @ Wily
|
||||
#
|
||||
# @run shell MakeJAR3.sh ParallelTransformerLoaderAgent
|
||||
# @run build ParallelTransformerLoaderApp
|
||||
# @run shell/timeout=240 ParallelTransformerLoader.sh
|
||||
#
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAR="${TESTJAVA}"/bin/jar
|
||||
JAVAC="${TESTJAVA}"/bin/javac
|
||||
JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
"${JAVAC}" -d . \
|
||||
"${TESTSRC}"/TestClass1.java \
|
||||
"${TESTSRC}"/TestClass2.java \
|
||||
"${TESTSRC}"/TestClass3.java
|
||||
|
||||
"${JAR}" cvf Test.jar Test*.class
|
||||
# Removing the test class files is important. If these
|
||||
# .class files are available on the classpath other
|
||||
# than via Test.jar, then the deadlock will not reproduce.
|
||||
rm -f Test*.class
|
||||
|
||||
"${JAVA}" ${TESTVMOPTS} -javaagent:ParallelTransformerLoaderAgent.jar=Test.jar \
|
||||
-classpath "${TESTCLASSES}" ParallelTransformerLoaderApp
|
||||
result=$?
|
||||
echo "result=$result"
|
||||
|
||||
exit $result
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
|
||||
/**
|
||||
* Test Java Agent
|
||||
*
|
||||
* @author Daryl Puryear
|
||||
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
|
||||
*/
|
||||
public class ParallelTransformerLoaderAgent
|
||||
{
|
||||
private static URL sURL;
|
||||
private static ClassLoader sClassLoader;
|
||||
|
||||
public static synchronized ClassLoader
|
||||
getClassLoader()
|
||||
{
|
||||
return sClassLoader;
|
||||
}
|
||||
|
||||
public static synchronized void
|
||||
generateNewClassLoader()
|
||||
{
|
||||
sClassLoader = new URLClassLoader(new URL[] {sURL});
|
||||
}
|
||||
|
||||
public static void
|
||||
premain( String agentArgs,
|
||||
Instrumentation instrumentation)
|
||||
throws Exception
|
||||
{
|
||||
if (agentArgs == null || agentArgs == "")
|
||||
{
|
||||
System.err.println("Error: No jar file name provided, test will not run.");
|
||||
return;
|
||||
}
|
||||
|
||||
sURL = (new File(agentArgs)).toURL();
|
||||
System.out.println("Using jar file: " + sURL);
|
||||
generateNewClassLoader();
|
||||
|
||||
instrumentation.addTransformer(new TestTransformer());
|
||||
}
|
||||
|
||||
private static class TestTransformer
|
||||
implements ClassFileTransformer
|
||||
{
|
||||
public byte[]
|
||||
transform( ClassLoader loader,
|
||||
String className,
|
||||
Class classBeingRedefined,
|
||||
ProtectionDomain protectionDomain,
|
||||
byte[] classfileBuffer)
|
||||
throws IllegalClassFormatException
|
||||
{
|
||||
String tName = Thread.currentThread().getName();
|
||||
// In 160_03 and older, transform() is called
|
||||
// with the "system_loader_lock" held and that
|
||||
// prevents the bootstrap class loaded from
|
||||
// running in parallel. If we add a slight sleep
|
||||
// delay here when the transform() call is not
|
||||
// main or TestThread, then the deadlock in
|
||||
// 160_03 and older is much more reproducible.
|
||||
if (!tName.equals("main") && !tName.equals("TestThread")) {
|
||||
System.out.println("Thread '" + tName +
|
||||
"' has called transform()");
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
|
||||
// load additional classes when called from other threads
|
||||
if (!tName.equals("main"))
|
||||
{
|
||||
loadClasses(3);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void
|
||||
loadClasses( int index)
|
||||
{
|
||||
ClassLoader loader = ParallelTransformerLoaderAgent.getClassLoader();
|
||||
try
|
||||
{
|
||||
Class.forName("TestClass" + index, true, loader);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2008 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 Java Program
|
||||
*
|
||||
* @author Daryl Puryear
|
||||
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
|
||||
*/
|
||||
public class ParallelTransformerLoaderApp
|
||||
{
|
||||
private static final int kNumIterations = 1000;
|
||||
|
||||
public static void
|
||||
main( String[] args)
|
||||
throws Exception
|
||||
{
|
||||
System.out.println();
|
||||
System.out.print("Starting test with " + kNumIterations + " iterations");
|
||||
for (int i = 0; i < kNumIterations; i++)
|
||||
{
|
||||
// load some classes from multiple threads (this thread and one other)
|
||||
Thread testThread = new TestThread(2);
|
||||
testThread.start();
|
||||
loadClasses(1);
|
||||
|
||||
// log that it completed and reset for the next iteration
|
||||
testThread.join();
|
||||
System.out.print(".");
|
||||
ParallelTransformerLoaderAgent.generateNewClassLoader();
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.println("Test completed successfully");
|
||||
}
|
||||
|
||||
private static class TestThread
|
||||
extends Thread
|
||||
{
|
||||
private final int fIndex;
|
||||
|
||||
public
|
||||
TestThread( int index)
|
||||
{
|
||||
super("TestThread");
|
||||
|
||||
fIndex = index;
|
||||
}
|
||||
|
||||
public void
|
||||
run()
|
||||
{
|
||||
loadClasses(fIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void
|
||||
loadClasses( int index)
|
||||
{
|
||||
ClassLoader loader = ParallelTransformerLoaderAgent.getClassLoader();
|
||||
try
|
||||
{
|
||||
Class.forName("TestClass" + index, true, loader);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -22,11 +22,10 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Used by PremainClassTest.sh - dummy "main application" which doesn't do anything
|
||||
* dummy "Hello World"ish application for "premain" tests
|
||||
*/
|
||||
public class DummyMain {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello from DummyMain!");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (0,0,0,1): declared 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent0001
|
||||
* @run main/othervm -javaagent:InheritAgent0001.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent0001 extends InheritAgent0001Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent0001!");
|
||||
}
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
||||
|
||||
class InheritAgent0001Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (0,0,1,0): declared 2-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent0010
|
||||
* @run main/othervm -javaagent:InheritAgent0010.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent0010 extends InheritAgent0010Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent0010!");
|
||||
}
|
||||
}
|
||||
|
||||
class InheritAgent0010Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (0,0,1,1): declared 2-arg and declared 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent0011
|
||||
* @run main/othervm -javaagent:InheritAgent0011.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent0011 extends InheritAgent0011Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent0011!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent0011!");
|
||||
}
|
||||
}
|
||||
|
||||
class InheritAgent0011Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (0,1,0,0): inherited 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent0100
|
||||
* @run main/othervm -javaagent:InheritAgent0100.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent0100 extends InheritAgent0100Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
||||
|
||||
class InheritAgent0100Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent0100Super!");
|
||||
}
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (0,1,0,1): inherited 1-arg and declared 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent0101
|
||||
* @run main/othervm -javaagent:InheritAgent0101.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent0101 extends InheritAgent0101Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent0101!");
|
||||
}
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
||||
|
||||
class InheritAgent0101Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent0101Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (0,1,1,0): inherited 1-arg and declared 2-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent0110
|
||||
* @run main/othervm -javaagent:InheritAgent0110.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent0110 extends InheritAgent0110Super {
|
||||
|
||||
// This agent does NOT have a one argument premain() method.
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent0110!");
|
||||
}
|
||||
}
|
||||
|
||||
class InheritAgent0110Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent0110Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (0,1,1,1): inherited 1-arg, declared 2-arg and declared 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent0111
|
||||
* @run main/othervm -javaagent:InheritAgent0111.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent0111 extends InheritAgent0111Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent0111!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent0111!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class InheritAgent0111Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent0111Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (1,0,0,0): inherited 2-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent1000
|
||||
* @run main/othervm -javaagent:InheritAgent1000.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent1000 extends InheritAgent1000Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
||||
|
||||
class InheritAgent1000Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1000Super!");
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (1,0,0,1): inherited 2-arg, and declared 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent1001
|
||||
* @run main/othervm -javaagent:InheritAgent1001.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent1001 extends InheritAgent1001Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent1001!");
|
||||
}
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
||||
|
||||
class InheritAgent1001Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1001Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (1,0,1,0): inherited 2-arg, and declared 2-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent1010
|
||||
* @run main/othervm -javaagent:InheritAgent1010.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent1010 extends InheritAgent1010Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1010!");
|
||||
}
|
||||
}
|
||||
|
||||
class InheritAgent1010Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1010Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (1,0,1,1): inherited 2-arg, declared 2-arg and declared 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent1011
|
||||
* @run main/othervm -javaagent:InheritAgent1011.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent1011 extends InheritAgent1011Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent1011!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1011!");
|
||||
}
|
||||
}
|
||||
|
||||
class InheritAgent1011Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1011Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (1,1,0,0): inherited 2-arg and inherited 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent1100
|
||||
* @run main/othervm -javaagent:InheritAgent1100.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent1100 extends InheritAgent1100Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
||||
|
||||
class InheritAgent1100Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent1100Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1100Super!");
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (1,1,0,1): inherited 2-arg, inherited 1-arg, and declared 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent1101
|
||||
* @run main/othervm -javaagent:InheritAgent1101.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent1101 extends InheritAgent1101Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent1101!");
|
||||
}
|
||||
|
||||
// This agent does NOT have a double argument premain() method.
|
||||
}
|
||||
|
||||
class InheritAgent1101Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent1101Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1101Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (1,1,1,0): inherited 2-arg, inherited 1-arg, and declared 2-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent1110
|
||||
* @run main/othervm -javaagent:InheritAgent1110.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent1110 extends InheritAgent1110Super {
|
||||
|
||||
// This agent does NOT have a single argument premain() method.
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1110!");
|
||||
}
|
||||
}
|
||||
|
||||
class InheritAgent1110Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent1110Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1110Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2008 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 6289149
|
||||
* @summary test config (1,1,1,1): inherited 2-arg, inherited 1-arg, declared 2-arg and declared 1-arg in agent class
|
||||
* @author Daniel D. Daugherty, Sun Microsystems
|
||||
*
|
||||
* @run shell ../MakeJAR3.sh InheritAgent1111
|
||||
* @run main/othervm -javaagent:InheritAgent1111.jar DummyMain
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class InheritAgent1111 extends InheritAgent1111Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent1111!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1111!");
|
||||
}
|
||||
}
|
||||
|
||||
class InheritAgent1111Super {
|
||||
|
||||
//
|
||||
// This agent has a single argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs) {
|
||||
System.out.println("Hello from Single-Arg InheritAgent1111Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
|
||||
//
|
||||
// This agent has a double argument premain() method which
|
||||
// is NOT the one that should be called.
|
||||
//
|
||||
public static void premain (String agentArgs, Instrumentation instArg) {
|
||||
System.out.println("Hello from Double-Arg InheritAgent1111Super!");
|
||||
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class NoPremainAgent {
|
||||
|
||||
// This agent is missing the premain() function.
|
||||
}
|
68
jdk/test/java/lang/instrument/PremainClass/NoPremainAgent.sh
Normal file
68
jdk/test/java/lang/instrument/PremainClass/NoPremainAgent.sh
Normal file
@ -0,0 +1,68 @@
|
||||
#
|
||||
# Copyright 2008 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 6289149
|
||||
# @summary test when the agent's class is missing the premain() function.
|
||||
# @author Daniel D. Daugherty, Sun Microsystems
|
||||
#
|
||||
# @run build DummyMain
|
||||
# @run shell ../MakeJAR3.sh NoPremainAgent
|
||||
# @run shell NoPremainAgent.sh
|
||||
#
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVAC="${TESTJAVA}"/bin/javac
|
||||
JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
"${JAVA}" ${TESTVMOPTS} -javaagent:NoPremainAgent.jar \
|
||||
-classpath "${TESTCLASSES}" DummyMain > output.log 2>&1
|
||||
cat output.log
|
||||
|
||||
MESG="java.lang.NoSuchMethodException"
|
||||
grep "$MESG" output.log
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: found '$MESG' in the test output"
|
||||
else
|
||||
echo "FAIL: did NOT find '$MESG' in the test output"
|
||||
fi
|
||||
|
||||
exit $result
|
@ -49,7 +49,7 @@ JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
"$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/DummyMain.java
|
||||
|
||||
"${JAVA}" -javaagent:"${TESTSRC}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
|
||||
"${JAVA}" ${TESTVMOPTS} -javaagent:"${TESTSRC}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
|
||||
result=$?
|
||||
|
||||
exit $result
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
|
||||
class ZeroArgPremainAgent {
|
||||
|
||||
// This agent has a zero arg premain() function.
|
||||
public static void premain () {
|
||||
System.out.println("Hello from ZeroArgInheritAgent!");
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
#
|
||||
# Copyright 2008 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 6289149
|
||||
# @summary test when the agent's class has a zero arg premain() function.
|
||||
# @author Daniel D. Daugherty, Sun Microsystems
|
||||
#
|
||||
# @run build DummyMain
|
||||
# @run shell ../MakeJAR3.sh ZeroArgPremainAgent
|
||||
# @run shell ZeroArgPremainAgent.sh
|
||||
#
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVAC="${TESTJAVA}"/bin/javac
|
||||
JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
"${JAVA}" ${TESTVMOPTS} -javaagent:ZeroArgPremainAgent.jar \
|
||||
-classpath "${TESTCLASSES}" DummyMain > output.log 2>&1
|
||||
cat output.log
|
||||
|
||||
MESG="java.lang.NoSuchMethodException"
|
||||
grep "$MESG" output.log
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: found '$MESG' in the test output"
|
||||
else
|
||||
echo "FAIL: did NOT find '$MESG' in the test output"
|
||||
fi
|
||||
|
||||
exit $result
|
@ -0,0 +1,81 @@
|
||||
#
|
||||
# Copyright 2008 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 5003341 4917140 6545149
|
||||
# @summary Redefine a class with a native method.
|
||||
# @author Daniel D. Daugherty as modified from the test submitted by clovis@par.univie.ac.at
|
||||
#
|
||||
# @run shell MakeJAR3.sh RedefineClassWithNativeMethodAgent 'Can-Redefine-Classes: true'
|
||||
# @run build RedefineClassWithNativeMethodApp
|
||||
# @run shell RedefineClassWithNativeMethod.sh
|
||||
#
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVAC="${TESTJAVA}"/bin/javac
|
||||
JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
"${JAVA}" ${TESTVMOPTS} \
|
||||
-javaagent:RedefineClassWithNativeMethodAgent.jar=java/lang/Thread.class \
|
||||
-classpath "${TESTCLASSES}" RedefineClassWithNativeMethodApp \
|
||||
> output.log 2>&1
|
||||
result=$?
|
||||
|
||||
cat output.log
|
||||
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "PASS: RedefineClassWithNativeMethodApp exited with status of 0."
|
||||
else
|
||||
echo "FAIL: RedefineClassWithNativeMethodApp exited with status of $result"
|
||||
exit "$result"
|
||||
fi
|
||||
|
||||
MESG="Exception"
|
||||
grep "$MESG" output.log
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "FAIL: found '$MESG' in the test output"
|
||||
result=1
|
||||
else
|
||||
echo "PASS: did NOT find '$MESG' in the test output"
|
||||
result=0
|
||||
fi
|
||||
|
||||
exit $result
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.instrument.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class RedefineClassWithNativeMethodAgent {
|
||||
static Class clz;
|
||||
|
||||
// just read the original class and redefine it via a Timer
|
||||
public static void premain(String agentArgs, final Instrumentation inst) throws Exception {
|
||||
String s = agentArgs.substring(0, agentArgs.indexOf(".class"));
|
||||
clz = Class.forName(s.replace('/', '.'));
|
||||
ClassLoader loader =
|
||||
RedefineClassWithNativeMethodAgent.class.getClassLoader();
|
||||
URL classURL = loader.getResource(agentArgs);
|
||||
if (classURL == null) {
|
||||
throw new Exception("Cannot find class: " + agentArgs);
|
||||
}
|
||||
|
||||
int redefineLength;
|
||||
InputStream redefineStream;
|
||||
|
||||
System.out.println("Reading test class from " + classURL);
|
||||
if (classURL.getProtocol().equals("file")) {
|
||||
File f = new File(classURL.getFile());
|
||||
redefineStream = new FileInputStream(f);
|
||||
redefineLength = (int) f.length();
|
||||
} else {
|
||||
URLConnection conn = classURL.openConnection();
|
||||
redefineStream = conn.getInputStream();
|
||||
redefineLength = conn.getContentLength();
|
||||
}
|
||||
|
||||
final byte[] buffer = new byte[redefineLength];
|
||||
new BufferedInputStream(redefineStream).read(buffer);
|
||||
new Timer(true).schedule(new TimerTask() {
|
||||
public void run() {
|
||||
try {
|
||||
System.out.println("Instrumenting");
|
||||
ClassDefinition cld = new ClassDefinition(clz, buffer);
|
||||
inst.redefineClasses(new ClassDefinition[] { cld });
|
||||
}
|
||||
catch (Exception e) { e.printStackTrace(); }
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
public class RedefineClassWithNativeMethodApp {
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
// give the agent a chance to redefine the target class
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
|
||||
System.out.println("Creating instance of " +
|
||||
RedefineClassWithNativeMethodAgent.clz);
|
||||
RedefineClassWithNativeMethodAgent.clz.newInstance();
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
82
jdk/test/java/lang/instrument/RedefineMethodAddInvoke.sh
Normal file
82
jdk/test/java/lang/instrument/RedefineMethodAddInvoke.sh
Normal file
@ -0,0 +1,82 @@
|
||||
#
|
||||
# Copyright 2008 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 6667089
|
||||
# @summary Reflexive invocation of newly added methods broken.
|
||||
# @author Daniel D. Daugherty
|
||||
#
|
||||
# @run shell MakeJAR3.sh RedefineMethodAddInvokeAgent 'Can-Redefine-Classes: true'
|
||||
# @run build RedefineMethodAddInvokeApp
|
||||
# @run shell RedefineMethodAddInvoke.sh
|
||||
#
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVAC="${TESTJAVA}"/bin/javac
|
||||
JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
cp "${TESTSRC}"/RedefineMethodAddInvokeTarget_1.java \
|
||||
RedefineMethodAddInvokeTarget.java
|
||||
"${JAVAC}" -d . RedefineMethodAddInvokeTarget.java
|
||||
mv RedefineMethodAddInvokeTarget.java RedefineMethodAddInvokeTarget_1.java
|
||||
mv RedefineMethodAddInvokeTarget.class RedefineMethodAddInvokeTarget_1.class
|
||||
|
||||
cp "${TESTSRC}"/RedefineMethodAddInvokeTarget_2.java \
|
||||
RedefineMethodAddInvokeTarget.java
|
||||
"${JAVAC}" -d . RedefineMethodAddInvokeTarget.java
|
||||
mv RedefineMethodAddInvokeTarget.java RedefineMethodAddInvokeTarget_2.java
|
||||
mv RedefineMethodAddInvokeTarget.class RedefineMethodAddInvokeTarget_2.class
|
||||
|
||||
"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodAddInvokeAgent.jar \
|
||||
-classpath "${TESTCLASSES}" RedefineMethodAddInvokeApp > output.log 2>&1
|
||||
cat output.log
|
||||
|
||||
MESG="Exception"
|
||||
grep "$MESG" output.log
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "FAIL: found '$MESG' in the test output"
|
||||
result=1
|
||||
else
|
||||
echo "PASS: did NOT find '$MESG' in the test output"
|
||||
result=0
|
||||
fi
|
||||
|
||||
exit $result
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
|
||||
public class RedefineMethodAddInvokeAgent {
|
||||
private static Instrumentation instrumentation;
|
||||
|
||||
private RedefineMethodAddInvokeAgent() {
|
||||
}
|
||||
|
||||
public static void premain(String agentArgs, Instrumentation inst) {
|
||||
System.out.println("Hello from RedefineMethodAddInvokeAgent!");
|
||||
System.out.println("isRedefineClassesSupported()=" +
|
||||
inst.isRedefineClassesSupported());
|
||||
|
||||
instrumentation = inst;
|
||||
}
|
||||
|
||||
public static Instrumentation getInstrumentation() {
|
||||
return instrumentation;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.instrument.*;
|
||||
|
||||
public class RedefineMethodAddInvokeApp {
|
||||
public static void main(String args[]) throws Exception {
|
||||
System.out.println("Hello from RedefineMethodAddInvokeApp!");
|
||||
|
||||
new RedefineMethodAddInvokeApp().doTest();
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
RedefineMethodAddInvokeTarget target =
|
||||
new RedefineMethodAddInvokeTarget();
|
||||
|
||||
System.out.println("RedefineMethodAddInvokeApp: invoking myMethod()");
|
||||
target.test(0); // invoke the original myMethod()
|
||||
|
||||
// add myMethod1()
|
||||
do_redefine(1);
|
||||
|
||||
System.out.println("RedefineMethodAddInvokeApp: invoking myMethod1()");
|
||||
target.test(1); // invoke myMethod1()
|
||||
|
||||
// add myMethod2()
|
||||
do_redefine(2);
|
||||
|
||||
System.out.println("RedefineMethodAddInvokeApp: invoking myMethod2()");
|
||||
target.test(2); // invoke myMethod2()
|
||||
}
|
||||
|
||||
private static void do_redefine(int counter) throws Exception {
|
||||
File f = new File("RedefineMethodAddInvokeTarget_" + counter +
|
||||
".class");
|
||||
System.out.println("Reading test class from " + f);
|
||||
InputStream redefineStream = new FileInputStream(f);
|
||||
|
||||
byte[] redefineBuffer = NamedBuffer.loadBufferFromStream(redefineStream);
|
||||
|
||||
ClassDefinition redefineParamBlock = new ClassDefinition(
|
||||
RedefineMethodAddInvokeTarget.class, redefineBuffer);
|
||||
|
||||
RedefineMethodAddInvokeAgent.getInstrumentation().redefineClasses(
|
||||
new ClassDefinition[] {redefineParamBlock});
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class RedefineMethodAddInvokeTarget {
|
||||
public void test(int counter) throws Exception {
|
||||
Method method = getClass().getDeclaredMethod("myMethod" +
|
||||
(counter == 0 ? "" : counter));
|
||||
method.setAccessible(true);
|
||||
method.invoke(this);
|
||||
}
|
||||
|
||||
public void myMethod() {
|
||||
System.out.println("Hello from the original myMethod()!");
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class RedefineMethodAddInvokeTarget {
|
||||
public void test(int counter) throws Exception {
|
||||
Method method = getClass().getDeclaredMethod("myMethod" +
|
||||
(counter == 0 ? "" : counter));
|
||||
method.setAccessible(true);
|
||||
method.invoke(this);
|
||||
}
|
||||
|
||||
public void myMethod() {
|
||||
System.out.println("Hello from the non-EMCP myMethod()!");
|
||||
}
|
||||
|
||||
private final void myMethod1() {
|
||||
System.out.println("Hello from myMethod1()!");
|
||||
System.out.println("Calling myMethod() from myMethod1():");
|
||||
myMethod();
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class RedefineMethodAddInvokeTarget {
|
||||
public void test(int counter) throws Exception {
|
||||
Method method = getClass().getDeclaredMethod("myMethod" +
|
||||
(counter == 0 ? "" : counter));
|
||||
method.setAccessible(true);
|
||||
method.invoke(this);
|
||||
}
|
||||
|
||||
public void myMethod() {
|
||||
System.out.println("Hello from the non-EMCP again myMethod()!");
|
||||
}
|
||||
|
||||
private final void myMethod1() {
|
||||
System.out.println("Hello from myMethod1()!");
|
||||
System.out.println("Calling myMethod() from myMethod1():");
|
||||
myMethod();
|
||||
}
|
||||
|
||||
private final void myMethod2() {
|
||||
System.out.println("Hello from myMethod2()!");
|
||||
System.out.println("Calling myMethod1() from myMethod2():");
|
||||
myMethod1();
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
* @summary test retransformClasses
|
||||
* @author Robert Field, Sun Microsystems
|
||||
*
|
||||
* @run shell MakeJAR2.sh RetransformAgent RetransformApp 'Can-Retransform-Classes: true'
|
||||
* @run shell/timeout=240 MakeJAR2.sh RetransformAgent RetransformApp 'Can-Retransform-Classes: true'
|
||||
* @run main/othervm -javaagent:RetransformAgent.jar RetransformApp
|
||||
*/
|
||||
|
||||
|
86
jdk/test/java/lang/instrument/StressGetObjectSizeApp.java
Normal file
86
jdk/test/java/lang/instrument/StressGetObjectSizeApp.java
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
|
||||
public class StressGetObjectSizeApp
|
||||
extends ASimpleInstrumentationTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor for StressGetObjectSizeApp.
|
||||
* @param name
|
||||
*/
|
||||
public StressGetObjectSizeApp(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
public static void
|
||||
main (String[] args)
|
||||
throws Throwable {
|
||||
ATestCaseScaffold test = new StressGetObjectSizeApp(args[0]);
|
||||
test.runTest();
|
||||
}
|
||||
|
||||
protected final void
|
||||
doRunTest()
|
||||
throws Throwable {
|
||||
stressGetObjectSize();
|
||||
}
|
||||
|
||||
public void stressGetObjectSize() {
|
||||
System.out.println("main: an object size=" +
|
||||
fInst.getObjectSize(new Object()));
|
||||
|
||||
RoundAndRound[] threads = new RoundAndRound[10];
|
||||
for (int i = 0; i < threads.length; ++i) {
|
||||
threads[i] = new RoundAndRound(fInst);
|
||||
threads[i].start();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(500); // let all threads get going in their loops
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
System.out.println("stressGetObjectSize: returning");
|
||||
return;
|
||||
}
|
||||
|
||||
private static class RoundAndRound extends Thread {
|
||||
private final Instrumentation inst;
|
||||
private final Object anObject;
|
||||
|
||||
public RoundAndRound(Instrumentation inst) {
|
||||
this.inst = inst;
|
||||
this.anObject = new Object();
|
||||
setDaemon(true);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
long sum = 0;
|
||||
while (true) {
|
||||
sum += inst.getObjectSize(anObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
70
jdk/test/java/lang/instrument/StressGetObjectSizeTest.sh
Normal file
70
jdk/test/java/lang/instrument/StressGetObjectSizeTest.sh
Normal file
@ -0,0 +1,70 @@
|
||||
#
|
||||
# Copyright 2008 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 6572160
|
||||
# @summary stress getObjectSize() API
|
||||
# @author Daniel D. Daugherty as modified from the code of fischman@google.com
|
||||
#
|
||||
# @run build StressGetObjectSizeApp
|
||||
# @run shell MakeJAR.sh basicAgent
|
||||
# @run shell StressGetObjectSizeTest.sh
|
||||
#
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
"${JAVA}" ${TESTVMOPTS} -javaagent:basicAgent.jar \
|
||||
-classpath "${TESTCLASSES}" StressGetObjectSizeApp StressGetObjectSizeApp \
|
||||
> output.log 2>&1
|
||||
cat output.log
|
||||
|
||||
MESG="ASSERTION FAILED"
|
||||
grep "$MESG" output.log
|
||||
result=$?
|
||||
if [ "$result" = 0 ]; then
|
||||
echo "FAIL: found '$MESG' in the test output"
|
||||
result=1
|
||||
else
|
||||
echo "PASS: did NOT find '$MESG' in the test output"
|
||||
result=0
|
||||
fi
|
||||
|
||||
exit $result
|
36
jdk/test/java/lang/instrument/TestClass1.java
Normal file
36
jdk/test/java/lang/instrument/TestClass1.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2008 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 Java Program
|
||||
*
|
||||
* @author Daryl Puryear
|
||||
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
|
||||
*/
|
||||
public class TestClass1
|
||||
{
|
||||
public
|
||||
TestClass1()
|
||||
{
|
||||
}
|
||||
}
|
36
jdk/test/java/lang/instrument/TestClass2.java
Normal file
36
jdk/test/java/lang/instrument/TestClass2.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2008 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 Java Program
|
||||
*
|
||||
* @author Daryl Puryear
|
||||
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
|
||||
*/
|
||||
public class TestClass2
|
||||
{
|
||||
public
|
||||
TestClass2()
|
||||
{
|
||||
}
|
||||
}
|
36
jdk/test/java/lang/instrument/TestClass3.java
Normal file
36
jdk/test/java/lang/instrument/TestClass3.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2008 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 Java Program
|
||||
*
|
||||
* @author Daryl Puryear
|
||||
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
|
||||
*/
|
||||
public class TestClass3
|
||||
{
|
||||
public
|
||||
TestClass3()
|
||||
{
|
||||
}
|
||||
}
|
@ -79,6 +79,12 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
|
||||
protected static final int TOTAL_THREADS = MAX_TRANS - MIN_TRANS + 1;
|
||||
|
||||
private byte[] fDummyClassBytes;
|
||||
// fCheckedTransformers is a Vector that is used to verify
|
||||
// that the transform() function is called in the same
|
||||
// order in which the transformers were added to the
|
||||
// TransformerManager. The test currently verifies that all
|
||||
// transformers for a specific worker thread are in
|
||||
// increasing order by index value.
|
||||
private Vector fCheckedTransformers;
|
||||
private Instrumentation fInstrumentation;
|
||||
private int fFinished;
|
||||
@ -131,9 +137,16 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
|
||||
threads[i].start();
|
||||
}
|
||||
|
||||
while (!exec.fDone)
|
||||
// Effective Java - Item 48: Synchronize access to shared mutable data
|
||||
// Don't use a direct field getter.
|
||||
while (!exec.isDone())
|
||||
{
|
||||
Thread.currentThread().yield();
|
||||
// Effective Java - Item 51: Don't depend on the thread scheduler
|
||||
// Use sleep() instead of yield().
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
assertTrue(finalCheck());
|
||||
|
||||
@ -169,13 +182,17 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
|
||||
this.fExec = exec;
|
||||
}
|
||||
|
||||
// Effective Java - Item 48: Synchronize access to shared mutable data
|
||||
// Document a synchronized setter.
|
||||
protected synchronized void
|
||||
threadFinished(Thread t)
|
||||
{
|
||||
fFinished++;
|
||||
}
|
||||
|
||||
protected boolean
|
||||
// Effective Java - Item 48: Synchronize access to shared mutable data
|
||||
// Provide synchronized getter.
|
||||
protected synchronized boolean
|
||||
threadsDone()
|
||||
{
|
||||
return fFinished == TOTAL_THREADS;
|
||||
@ -188,7 +205,9 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
|
||||
protected boolean
|
||||
testCompleted()
|
||||
{
|
||||
return getExecThread().fDone;
|
||||
// Effective Java - Item 48: Synchronize access to shared mutable data
|
||||
// Don't use direct field getter.
|
||||
return getExecThread().isDone();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,11 +283,19 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
|
||||
private void
|
||||
executeTransform()
|
||||
{
|
||||
fCheckedTransformers.clear();
|
||||
|
||||
try
|
||||
{
|
||||
ClassDefinition cd = new ClassDefinition(DummyClass.class, fDummyClassBytes);
|
||||
|
||||
// When the ClassDefinition above is created for the first
|
||||
// time and every time redefineClasses() below is called,
|
||||
// the transform() function is called for each registered
|
||||
// transformer. We only want one complete set of calls to
|
||||
// be logged in the fCheckedTransformers Vector so we clear
|
||||
// any calls logged for ClassDefinition above and just use
|
||||
// the ones logged for redefineClasses() below.
|
||||
fCheckedTransformers.clear();
|
||||
|
||||
getInstrumentation().redefineClasses(new ClassDefinition[]{ cd });
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
@ -325,6 +352,18 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
|
||||
{
|
||||
private boolean fDone = false;
|
||||
|
||||
// Effective Java - Item 48: Synchronize access to shared mutable data
|
||||
// Provide a synchronized getter.
|
||||
private synchronized boolean isDone() {
|
||||
return fDone;
|
||||
}
|
||||
|
||||
// Effective Java - Item 48: Synchronize access to shared mutable data
|
||||
// Provide a synchronized setter.
|
||||
private synchronized void setIsDone() {
|
||||
fDone = true;
|
||||
}
|
||||
|
||||
public void
|
||||
run()
|
||||
{
|
||||
@ -335,7 +374,9 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
|
||||
|
||||
// Do a final check for good measure
|
||||
executeTransform();
|
||||
fDone = true;
|
||||
// Effective Java - Item 48: Synchronize access to shared mutable data
|
||||
// Don't use direct field setter.
|
||||
setIsDone();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,10 +27,9 @@
|
||||
* @summary multi-thread test to exercise sync and contention for removes to transformer registry
|
||||
* @author Gabriel Adauto, Wily Technology
|
||||
*
|
||||
* @ignore Disabled until race condition which hangs test can be fixed.
|
||||
* @run build TransformerManagementThreadRemoveTests
|
||||
* @run shell MakeJAR.sh basicAgent
|
||||
* @run main/othervm -javaagent:basicAgent.jar TransformerManagementThreadRemoveTests TransformerManagementThreadRemoveTests
|
||||
* @run shell MakeJAR.sh redefineAgent
|
||||
* @run main/othervm -javaagent:redefineAgent.jar TransformerManagementThreadRemoveTests TransformerManagementThreadRemoveTests
|
||||
*/
|
||||
import java.util.*;
|
||||
|
||||
@ -87,7 +86,12 @@ public class TransformerManagementThreadRemoveTests
|
||||
|
||||
while (!testCompleted())
|
||||
{
|
||||
Thread.currentThread().yield();
|
||||
// Effective Java - Item 51: Don't depend on the thread scheduler
|
||||
// Use sleep() instead of yield().
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
assertTrue(finalCheck());
|
||||
|
||||
|
@ -26,14 +26,14 @@
|
||||
# @summary Unit tests for appendToBootstrapClassLoaderSearch and
|
||||
# appendToSystemClasLoaderSearch methods.
|
||||
#
|
||||
# @run shell CircularityErrorTest.sh
|
||||
# @run shell/timeout=240 CircularityErrorTest.sh
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
. ${TESTSRC}/CommonSetup.sh
|
||||
|
||||
# Setup to create circularity condition
|
||||
@ -71,5 +71,5 @@ $JAR -cfm "${TESTCLASSES}"/CircularityErrorTest.jar "${MANIFEST}" \
|
||||
-C "${TESTCLASSES}" CircularityErrorTest.class
|
||||
|
||||
# Finally we run the test
|
||||
(cd "${TESTCLASSES}";
|
||||
$JAVA -javaagent:CircularityErrorTest.jar CircularityErrorTest)
|
||||
(cd "${TESTCLASSES}";
|
||||
$JAVA ${TESTVMOPTS} -javaagent:CircularityErrorTest.jar CircularityErrorTest)
|
||||
|
@ -34,11 +34,11 @@ then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
. ${TESTSRC}/CommonSetup.sh
|
||||
|
||||
# Create Foo and Bar
|
||||
# Foo has a reference to Bar but we deleted Bar so that
|
||||
# Foo has a reference to Bar but we deleted Bar so that
|
||||
# a NoClassDefFoundError will be thrown when Foo tries to
|
||||
# resolve the reference to Bar
|
||||
|
||||
@ -53,11 +53,11 @@ cat << EOF > "${FOO}"
|
||||
public class Foo {
|
||||
public static boolean doSomething() {
|
||||
try {
|
||||
Bar b = new Bar();
|
||||
return true;
|
||||
} catch (NoClassDefFoundError x) {
|
||||
return false;
|
||||
}
|
||||
Bar b = new Bar();
|
||||
return true;
|
||||
} catch (NoClassDefFoundError x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
@ -79,5 +79,5 @@ $JAR -cfm "${TESTCLASSES}"/ClassUnloadTest.jar "${MANIFEST}" \
|
||||
|
||||
# Finally we run the test
|
||||
(cd "${TESTCLASSES}"; \
|
||||
$JAVA -Xverify:none -XX:+TraceClassUnloading -javaagent:ClassUnloadTest.jar \
|
||||
ClassUnloadTest "${OTHERDIR}" Bar.jar)
|
||||
$JAVA ${TESTVMOPTS} -Xverify:none -XX:+TraceClassUnloading \
|
||||
-javaagent:ClassUnloadTest.jar ClassUnloadTest "${OTHERDIR}" Bar.jar)
|
||||
|
@ -24,7 +24,6 @@
|
||||
#
|
||||
|
||||
|
||||
#%E
|
||||
#
|
||||
# Common setup for unit tests. Setups up the following variables:
|
||||
#
|
||||
@ -66,7 +65,7 @@ then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
|
@ -23,24 +23,24 @@
|
||||
# have any questions.
|
||||
#
|
||||
|
||||
|
||||
|
||||
# @test
|
||||
# @bug 6173575 6388987
|
||||
# @summary Unit tests for appendToBootstrapClassLoaderSearch and
|
||||
# @summary Unit tests for appendToBootstrapClassLoaderSearch and
|
||||
# appendToSystemClasLoaderSearch methods.
|
||||
#
|
||||
# @build Agent AgentSupport BootSupport BasicTest PrematureLoadTest DynamicTest
|
||||
# @run shell run_tests.sh
|
||||
# @run shell/timeout=240 run_tests.sh
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
. ${TESTSRC}/CommonSetup.sh
|
||||
|
||||
|
||||
|
||||
# Simple tests
|
||||
|
||||
echo "Creating jar files for simple tests..."
|
||||
@ -50,13 +50,13 @@ cd ${TESTCLASSES}
|
||||
"$JAR" -cfm Agent.jar "${TESTSRC}"/manifest.mf Agent.class
|
||||
"$JAR" -cf AgentSupport.jar AgentSupport.class
|
||||
"$JAR" -cf BootSupport.jar BootSupport.class
|
||||
"$JAR" -cf SimpleTests.jar BasicTest.class PrematureLoadTest.class
|
||||
"$JAR" -cf SimpleTests.jar BasicTest.class PrematureLoadTest.class
|
||||
|
||||
failures=0
|
||||
|
||||
go() {
|
||||
echo ''
|
||||
sh -xc "$JAVA -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1
|
||||
sh -xc "$JAVA ${TESTVMOPTS} -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1
|
||||
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ mkdir tmp
|
||||
"${JAVAC}" -d tmp "${TESTSRC}"/Tracer.java
|
||||
(cd tmp; "${JAR}" cf ../Tracer.jar org/tools/Tracer.class)
|
||||
|
||||
# InstrumentedApplication is Application+instrmentation - don't copy as
|
||||
# InstrumentedApplication is Application+instrmentation - don't copy as
|
||||
# we don't want the original file permission
|
||||
|
||||
cat "${TESTSRC}"/InstrumentedApplication.java > ./Application.java
|
||||
@ -85,11 +85,11 @@ mv Application.class InstrumentedApplication.bytes
|
||||
cp "${TESTSRC}"/Application.java .
|
||||
"${JAVAC}" -d . Application.java
|
||||
|
||||
sh -xc "$JAVA -classpath . -javaagent:Agent.jar DynamicTest" 2>&1
|
||||
sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar DynamicTest" 2>&1
|
||||
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
|
||||
|
||||
# Repeat test with security manager
|
||||
sh -xc "$JAVA -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1
|
||||
sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1
|
||||
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
|
||||
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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
|
||||
@ -46,9 +46,7 @@ public class TestGetInstance {
|
||||
|
||||
Cipher c;
|
||||
|
||||
c = Cipher.getInstance("des");
|
||||
same(p, c.getProvider());
|
||||
c = Cipher.getInstance("des/cbc/pkcs5padding");
|
||||
c = Cipher.getInstance("PBEWithMD5AndTripleDES");
|
||||
same(p, c.getProvider());
|
||||
|
||||
c = Cipher.getInstance("des", "SunJCE");
|
||||
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 6471865 6675768
|
||||
* @summary DescriptorSupport constructors throw IAE when traces are enabled;
|
||||
* RequiredModelMBean.addAttributeChangeNotificationListener throws exception
|
||||
* when traces enabled and no attributes.
|
||||
* @author Luis-Miguel Alventosa
|
||||
* @author Paul Cheeseman
|
||||
*/
|
||||
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.management.Notification;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.management.modelmbean.DescriptorSupport;
|
||||
import javax.management.modelmbean.RequiredModelMBean;
|
||||
|
||||
public class LoggingExceptionTest {
|
||||
private static final String tests[] = new String[] {
|
||||
"DescriptorSupport()",
|
||||
"DescriptorSupport(int)",
|
||||
"DescriptorSupport(String)",
|
||||
"DescriptorSupport(String...)",
|
||||
"DescriptorSupport(String[], Object[])",
|
||||
"DescriptorSupport(DescriptorSupport)",
|
||||
"RequiredModelMBean.addAttributeChangeNotificationListener",
|
||||
};
|
||||
public static void main(String[] args) {
|
||||
Handler handler = new ConsoleHandler();
|
||||
Logger logger = Logger.getLogger("javax.management.modelmbean");
|
||||
logger.addHandler(handler);
|
||||
logger.setLevel(Level.FINEST);
|
||||
try {
|
||||
for (int i = 0; i < tests.length; i++) {
|
||||
System.out.println(">>> DescriptorSupportLoggingTest: Test Case " + i);
|
||||
DescriptorSupport ds;
|
||||
String msg = "Instantiate " + tests[i];
|
||||
System.out.println(msg);
|
||||
switch (i) {
|
||||
case 0:
|
||||
ds = new DescriptorSupport();
|
||||
break;
|
||||
case 1:
|
||||
ds = new DescriptorSupport(10);
|
||||
break;
|
||||
case 2:
|
||||
ds = new DescriptorSupport(new DescriptorSupport().toXMLString());
|
||||
break;
|
||||
case 3:
|
||||
ds = new DescriptorSupport("name1=value1", "name2=value2");
|
||||
break;
|
||||
case 4:
|
||||
ds = new DescriptorSupport(new String[] {"name"}, new Object[] {"value"});
|
||||
break;
|
||||
case 5:
|
||||
ds = new DescriptorSupport(new DescriptorSupport());
|
||||
break;
|
||||
case 6:
|
||||
RequiredModelMBean mbean = new RequiredModelMBean();
|
||||
NotificationListener nl = new NotificationListener() {
|
||||
public void handleNotification(Notification notification,
|
||||
Object handback) {}
|
||||
};
|
||||
mbean.addAttributeChangeNotificationListener(nl, null, null);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
System.out.println(msg + " OK");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Got unexpected exception = " + e);
|
||||
String msg = "Test FAILED!";
|
||||
System.out.println(msg);
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
System.out.println("Test PASSED!");
|
||||
}
|
||||
}
|
347
jdk/test/javax/management/query/QueryNotifFilterTest.java
Normal file
347
jdk/test/javax/management/query/QueryNotifFilterTest.java
Normal file
@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Copyright 2007 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 QueryNotifFilterTest
|
||||
* @bug 6610917
|
||||
* @summary Test the QueryNotificationFilter class
|
||||
* @author Eamonn McManus
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.management.Attribute;
|
||||
import javax.management.AttributeChangeNotification;
|
||||
import javax.management.MBeanAttributeInfo;
|
||||
import javax.management.MBeanInfo;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.Notification;
|
||||
import javax.management.NotificationFilter;
|
||||
import javax.management.ObjectInstance;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.Query;
|
||||
import javax.management.QueryEval;
|
||||
import javax.management.QueryExp;
|
||||
import javax.management.QueryNotificationFilter;
|
||||
|
||||
public class QueryNotifFilterTest {
|
||||
private static class Case {
|
||||
final Notification notif;
|
||||
final QueryExp query;
|
||||
final boolean expect;
|
||||
final Class<? extends Notification> notifClass;
|
||||
Case(Notification notif, String query, boolean expect) {
|
||||
this(notif, query, notif.getClass(), expect);
|
||||
}
|
||||
Case(Notification notif, String query,
|
||||
Class<? extends Notification> notifClass, boolean expect) {
|
||||
this(notif, Query.fromString(query), notifClass, expect);
|
||||
}
|
||||
Case(Notification notif, QueryExp query, boolean expect) {
|
||||
this(notif, query, notif.getClass(), expect);
|
||||
}
|
||||
Case(Notification notif, QueryExp query,
|
||||
Class<? extends Notification> notifClass, boolean expect) {
|
||||
this.notif = notif;
|
||||
this.query = query;
|
||||
this.expect = expect;
|
||||
this.notifClass = notifClass;
|
||||
}
|
||||
}
|
||||
|
||||
/* In principle users can create their own implementations of QueryExp
|
||||
* and use them with QueryNotificationFilter. If they do so, then
|
||||
* they can call any MBeanServer method. Not all of those methods
|
||||
* will work with the special MBeanServer we concoct to analyze a
|
||||
* Notification, but some will, including some that are not called
|
||||
* by the standard queries. So we check each of those cases too.
|
||||
*/
|
||||
private static class ExoticCase {
|
||||
final Notification trueNotif;
|
||||
final Notification falseNotif;
|
||||
final QueryExp query;
|
||||
ExoticCase(Notification trueNotif, Notification falseNotif, QueryExp query) {
|
||||
this.trueNotif = trueNotif;
|
||||
this.falseNotif = falseNotif;
|
||||
this.query = query;
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class ExoticQuery
|
||||
extends QueryEval implements QueryExp {
|
||||
private final String queryString;
|
||||
ExoticQuery(String queryString) {
|
||||
this.queryString = queryString;
|
||||
}
|
||||
abstract boolean apply(MBeanServer mbs, ObjectName name) throws Exception;
|
||||
@Override
|
||||
public boolean apply(ObjectName name) {
|
||||
try {
|
||||
return apply(getMBeanServer(), name);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.out);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return queryString;
|
||||
}
|
||||
}
|
||||
|
||||
private static ObjectName makeObjectName(String s) {
|
||||
try {
|
||||
return new ObjectName(s);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CustomNotification extends Notification {
|
||||
public CustomNotification(String type, Object source, long seqNo) {
|
||||
super(type, source, seqNo);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "claude";
|
||||
}
|
||||
|
||||
public boolean isInteresting() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Notification simpleNotif =
|
||||
new Notification("mytype", "source", 0L);
|
||||
private static final Notification attrChangeNotif =
|
||||
new AttributeChangeNotification(
|
||||
"x", 0L, 0L, "msg", "AttrName", "int", 2, 3);
|
||||
private static final ObjectName testObjectName = makeObjectName("a:b=c");
|
||||
private static final Notification sourcedNotif =
|
||||
new Notification("mytype", testObjectName, 0L);
|
||||
private static final Notification customNotif =
|
||||
new CustomNotification("mytype", testObjectName, 0L);
|
||||
|
||||
private static final Case[] testCases = {
|
||||
new Case(simpleNotif, "Type = 'mytype'", true),
|
||||
new Case(simpleNotif, "Type = 'mytype'",
|
||||
Notification.class, true),
|
||||
new Case(simpleNotif, "Type = 'mytype'",
|
||||
AttributeChangeNotification.class, false),
|
||||
new Case(simpleNotif, "Type != 'mytype'", false),
|
||||
new Case(simpleNotif, "Type = 'somethingelse'", false),
|
||||
new Case(attrChangeNotif, "AttributeName = 'AttrName'", true),
|
||||
new Case(attrChangeNotif,
|
||||
"instanceof 'javax.management.AttributeChangeNotification'",
|
||||
true),
|
||||
new Case(attrChangeNotif,
|
||||
"instanceof 'javax.management.Notification'",
|
||||
true),
|
||||
new Case(attrChangeNotif,
|
||||
"instanceof 'javax.management.relation.MBeanServerNotification'",
|
||||
false),
|
||||
new Case(attrChangeNotif,
|
||||
"class = 'javax.management.AttributeChangeNotification'",
|
||||
true),
|
||||
new Case(attrChangeNotif,
|
||||
"javax.management.AttributeChangeNotification#AttributeName = 'AttrName'",
|
||||
true),
|
||||
new Case(sourcedNotif,
|
||||
testObjectName,
|
||||
true),
|
||||
new Case(sourcedNotif,
|
||||
makeObjectName("a*:b=*"),
|
||||
true),
|
||||
new Case(sourcedNotif,
|
||||
makeObjectName("a*:c=*"),
|
||||
false),
|
||||
new Case(customNotif, "Name = 'claude'", true),
|
||||
new Case(customNotif, "Name = 'tiddly'", false),
|
||||
new Case(customNotif, "Interesting = true", true),
|
||||
new Case(customNotif, "Interesting = false", false),
|
||||
};
|
||||
|
||||
private static final ExoticCase[] exoticTestCases = {
|
||||
new ExoticCase(
|
||||
simpleNotif, new Notification("notmytype", "source", 0L),
|
||||
new ExoticQuery("getAttributes") {
|
||||
boolean apply(MBeanServer mbs, ObjectName name)
|
||||
throws Exception {
|
||||
List<Attribute> attrs = mbs.getAttributes(
|
||||
name, new String[] {"Type", "Source"}).asList();
|
||||
return (attrs.get(0).equals(new Attribute("Type", "mytype")) &&
|
||||
attrs.get(1).equals(new Attribute("Source", "source")));
|
||||
}
|
||||
}),
|
||||
new ExoticCase(
|
||||
new Notification("mytype", "source", 0L) {},
|
||||
simpleNotif,
|
||||
new ExoticQuery("getClassLoaderFor") {
|
||||
boolean apply(MBeanServer mbs, ObjectName name)
|
||||
throws Exception {
|
||||
return (mbs.getClassLoaderFor(name) ==
|
||||
this.getClass().getClassLoader());
|
||||
}
|
||||
}),
|
||||
new ExoticCase(
|
||||
sourcedNotif, simpleNotif,
|
||||
new ExoticQuery("getDomains") {
|
||||
boolean apply(MBeanServer mbs, ObjectName name)
|
||||
throws Exception {
|
||||
return Arrays.equals(mbs.getDomains(),
|
||||
new String[] {testObjectName.getDomain()});
|
||||
}
|
||||
}),
|
||||
new ExoticCase(
|
||||
simpleNotif, attrChangeNotif,
|
||||
new ExoticQuery("getMBeanInfo") {
|
||||
boolean apply(MBeanServer mbs, ObjectName name)
|
||||
throws Exception {
|
||||
MBeanInfo mbi = mbs.getMBeanInfo(name);
|
||||
// If we ever add a constructor to Notification then
|
||||
// we will have to change the 4 below.
|
||||
if (mbi.getOperations().length > 0 ||
|
||||
mbi.getConstructors().length != 4 ||
|
||||
mbi.getNotifications().length > 0)
|
||||
return false;
|
||||
Set<String> expect = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"Class", "Message", "SequenceNumber", "Source",
|
||||
"TimeStamp", "Type", "UserData"));
|
||||
Set<String> actual = new HashSet<String>();
|
||||
for (MBeanAttributeInfo mbai : mbi.getAttributes())
|
||||
actual.add(mbai.getName());
|
||||
return actual.equals(expect);
|
||||
}
|
||||
}),
|
||||
new ExoticCase(
|
||||
simpleNotif, attrChangeNotif,
|
||||
new ExoticQuery("getObjectInstance") {
|
||||
boolean apply(MBeanServer mbs, ObjectName name)
|
||||
throws Exception {
|
||||
ObjectInstance oi = mbs.getObjectInstance(name);
|
||||
return oi.getClassName().equals(Notification.class.getName());
|
||||
}
|
||||
}),
|
||||
new ExoticCase(
|
||||
sourcedNotif, simpleNotif,
|
||||
new ExoticQuery("queryNames") {
|
||||
boolean apply(MBeanServer mbs, ObjectName name)
|
||||
throws Exception {
|
||||
Set<ObjectName> names = mbs.queryNames(null,
|
||||
Query.eq(Query.attr("Type"), Query.value("mytype")));
|
||||
return names.equals(Collections.singleton(testObjectName));
|
||||
}
|
||||
}),
|
||||
new ExoticCase(
|
||||
sourcedNotif, simpleNotif,
|
||||
new ExoticQuery("queryMBeans") {
|
||||
boolean apply(MBeanServer mbs, ObjectName name)
|
||||
throws Exception {
|
||||
Set<ObjectInstance> insts = mbs.queryMBeans(null,
|
||||
Query.eq(Query.attr("Type"), Query.value("mytype")));
|
||||
if (insts.size() != 1)
|
||||
return false;
|
||||
ObjectInstance inst = insts.iterator().next();
|
||||
return (inst.getObjectName().equals(testObjectName) &&
|
||||
inst.getClassName().equals(Notification.class.getName()));
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
private static enum Test {
|
||||
QUERY_EXP("query"), STRING("string"), STRING_PLUS_CLASS("string with class");
|
||||
private final String name;
|
||||
Test(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean allok = true;
|
||||
for (Case testCase : testCases) {
|
||||
for (Test test : Test.values()) {
|
||||
QueryNotificationFilter nf;
|
||||
String queryString;
|
||||
switch (test) {
|
||||
case QUERY_EXP: {
|
||||
QueryExp inst = Query.isInstanceOf(
|
||||
Query.value(testCase.notifClass.getName()));
|
||||
QueryExp and = Query.and(inst, testCase.query);
|
||||
queryString = Query.toString(and);
|
||||
nf = new QueryNotificationFilter(and);
|
||||
break;
|
||||
}
|
||||
case STRING: {
|
||||
String s = "instanceof '" + testCase.notifClass.getName() + "'";
|
||||
queryString = s + " and " + Query.toString(testCase.query);
|
||||
nf = new QueryNotificationFilter(queryString);
|
||||
break;
|
||||
}
|
||||
case STRING_PLUS_CLASS:
|
||||
queryString = null;
|
||||
nf = new QueryNotificationFilter(
|
||||
testCase.notifClass, Query.toString(testCase.query));
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
boolean accept = nf.isNotificationEnabled(testCase.notif);
|
||||
if (queryString != null) {
|
||||
queryString = Query.toString(Query.fromString(queryString));
|
||||
if (!queryString.equals(Query.toString(nf.getQuery()))) {
|
||||
System.out.println("FAIL: query string mismatch: expected " +
|
||||
"\"" + queryString + "\", got \"" +
|
||||
Query.toString(nf.getQuery()));
|
||||
allok = false;
|
||||
}
|
||||
}
|
||||
boolean ok = (accept == testCase.expect);
|
||||
System.out.println((ok ? "pass" : "FAIL") + ": " +
|
||||
testCase.query + " (" + test + ")");
|
||||
allok &= ok;
|
||||
}
|
||||
}
|
||||
for (ExoticCase testCase : exoticTestCases) {
|
||||
NotificationFilter nf = new QueryNotificationFilter(testCase.query);
|
||||
for (boolean expect : new boolean[] {true, false}) {
|
||||
Notification n = expect ? testCase.trueNotif : testCase.falseNotif;
|
||||
boolean accept = nf.isNotificationEnabled(n);
|
||||
boolean ok = (accept == expect);
|
||||
System.out.println((ok ? "pass" : "FAIL") + ": " +
|
||||
testCase.query + ": " + n);
|
||||
allok &= ok;
|
||||
}
|
||||
}
|
||||
if (!allok)
|
||||
throw new Exception("TEST FAILED");
|
||||
}
|
||||
}
|
109
jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java
Normal file
109
jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2008 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 6572331
|
||||
* @summary basic test for RSA cipher key wrapping functionality
|
||||
* @author Valerie Peng
|
||||
* @library ..
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import java.security.*;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class TestRSACipherWrap extends PKCS11Test {
|
||||
|
||||
private static final String RSA_ALGO = "RSA/ECB/PKCS1Padding";
|
||||
|
||||
public void main(Provider p) throws Exception {
|
||||
try {
|
||||
Cipher.getInstance(RSA_ALGO, p);
|
||||
} catch (GeneralSecurityException e) {
|
||||
System.out.println("Not supported by provider, skipping");
|
||||
return;
|
||||
}
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", p);
|
||||
kpg.initialize(1024);
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
PublicKey publicKey = kp.getPublic();
|
||||
PrivateKey privateKey = kp.getPrivate();
|
||||
|
||||
Cipher cipherPKCS11 = Cipher.getInstance(RSA_ALGO, p);
|
||||
Cipher cipherJce = Cipher.getInstance(RSA_ALGO, "SunJCE");
|
||||
|
||||
String algos[] = {"AES", "RC2", "Blowfish"};
|
||||
int keySizes[] = {128, 256};
|
||||
|
||||
for (int j = 0; j < algos.length; j++) {
|
||||
String algorithm = algos[j];
|
||||
KeyGenerator keygen =
|
||||
KeyGenerator.getInstance(algorithm);
|
||||
|
||||
for (int i = 0; i < keySizes.length; i++) {
|
||||
SecretKey secretKey = null;
|
||||
System.out.print("Generate " + keySizes[i] + "-bit " +
|
||||
algorithm + " key using ");
|
||||
try {
|
||||
keygen.init(keySizes[i]);
|
||||
secretKey = keygen.generateKey();
|
||||
System.out.println(keygen.getProvider().getName());
|
||||
} catch (InvalidParameterException ipe) {
|
||||
secretKey = new SecretKeySpec(new byte[32], algorithm);
|
||||
System.out.println("SecretKeySpec class");
|
||||
}
|
||||
test(kp, secretKey, cipherPKCS11, cipherJce);
|
||||
test(kp, secretKey, cipherPKCS11, cipherPKCS11);
|
||||
test(kp, secretKey, cipherJce, cipherPKCS11);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(KeyPair kp, SecretKey secretKey,
|
||||
Cipher wrapCipher, Cipher unwrapCipher)
|
||||
throws Exception {
|
||||
String algo = secretKey.getAlgorithm();
|
||||
wrapCipher.init(Cipher.WRAP_MODE, kp.getPublic());
|
||||
byte[] wrappedKey = wrapCipher.wrap(secretKey);
|
||||
unwrapCipher.init(Cipher.UNWRAP_MODE, kp.getPrivate());
|
||||
Key unwrappedKey =
|
||||
unwrapCipher.unwrap(wrappedKey, algo, Cipher.SECRET_KEY);
|
||||
|
||||
System.out.println("Test " + wrapCipher.getProvider().getName() +
|
||||
"/" + unwrapCipher.getProvider().getName() + ": ");
|
||||
if (!Arrays.equals(secretKey.getEncoded(),
|
||||
unwrappedKey.getEncoded())) {
|
||||
throw new Exception("Test Failed!");
|
||||
}
|
||||
System.out.println("Passed");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
main(new TestRSACipherWrap());
|
||||
}
|
||||
}
|
||||
|
282
jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java
Normal file
282
jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright 2008 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 modi
|
||||
fy it
|
||||
* under the terms of the GNU General Public License version 2 onl
|
||||
y, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, bu
|
||||
t WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABIL
|
||||
ITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public L
|
||||
icense
|
||||
* version 2 for more details (a copy is included in the LICENSE f
|
||||
ile that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public Licen
|
||||
se version
|
||||
* 2 along with this work; if not, write to the Free Software Foun
|
||||
dation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, San
|
||||
ta Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional inform
|
||||
ation or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test %I% %E%
|
||||
* @bug 4898461
|
||||
* @summary basic test for symmetric ciphers with padding
|
||||
* @author Valerie Peng
|
||||
* @library ..
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.util.*;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
public class TestSymmCiphers extends PKCS11Test {
|
||||
|
||||
private static class CI { // class for holding Cipher Information
|
||||
|
||||
String transformation;
|
||||
String keyAlgo;
|
||||
int dataSize;
|
||||
|
||||
CI(String transformation, String keyAlgo, int dataSize) {
|
||||
this.transformation = transformation;
|
||||
this.keyAlgo = keyAlgo;
|
||||
this.dataSize = dataSize;
|
||||
}
|
||||
}
|
||||
private static final CI[] TEST_LIST = {
|
||||
new CI("ARCFOUR", "ARCFOUR", 400),
|
||||
new CI("RC4", "RC4", 401),
|
||||
new CI("DES/CBC/NoPadding", "DES", 400),
|
||||
new CI("DESede/CBC/NoPadding", "DESede", 160),
|
||||
new CI("AES/CBC/NoPadding", "AES", 4800),
|
||||
new CI("Blowfish/CBC/NoPadding", "Blowfish", 24),
|
||||
new CI("DES/cbc/PKCS5Padding", "DES", 6401),
|
||||
new CI("DESede/CBC/PKCS5Padding", "DESede", 402),
|
||||
new CI("AES/CBC/PKCS5Padding", "AES", 30),
|
||||
new CI("Blowfish/CBC/PKCS5Padding", "Blowfish", 19),
|
||||
new CI("DES/ECB/NoPadding", "DES", 400),
|
||||
new CI("DESede/ECB/NoPadding", "DESede", 160),
|
||||
new CI("AES/ECB/NoPadding", "AES", 4800),
|
||||
new CI("DES/ECB/PKCS5Padding", "DES", 32),
|
||||
new CI("DES/ECB/PKCS5Padding", "DES", 6400),
|
||||
new CI("DESede/ECB/PKCS5Padding", "DESede", 400),
|
||||
new CI("AES/ECB/PKCS5Padding", "AES", 64),
|
||||
new CI("DES", "DES", 6400),
|
||||
new CI("DESede", "DESede", 408),
|
||||
new CI("AES", "AES", 128)
|
||||
};
|
||||
private static StringBuffer debugBuf = new StringBuffer();
|
||||
|
||||
public void main(Provider p) throws Exception {
|
||||
// NSS reports CKR_DEVICE_ERROR when the data passed to
|
||||
// its EncryptUpdate/DecryptUpdate is not multiple of blocks
|
||||
int firstBlkSize = 16;
|
||||
boolean status = true;
|
||||
Random random = new Random();
|
||||
try {
|
||||
for (int i = 0; i < TEST_LIST.length; i++) {
|
||||
CI currTest = TEST_LIST[i];
|
||||
System.out.println("===" + currTest.transformation + "===");
|
||||
try {
|
||||
KeyGenerator kg =
|
||||
KeyGenerator.getInstance(currTest.keyAlgo, p);
|
||||
SecretKey key = kg.generateKey();
|
||||
Cipher c1 = Cipher.getInstance(currTest.transformation, p);
|
||||
Cipher c2 = Cipher.getInstance(currTest.transformation,
|
||||
"SunJCE");
|
||||
|
||||
byte[] plainTxt = new byte[currTest.dataSize];
|
||||
random.nextBytes(plainTxt);
|
||||
System.out.println("Testing inLen = " + plainTxt.length);
|
||||
|
||||
c2.init(Cipher.ENCRYPT_MODE, key);
|
||||
AlgorithmParameters params = c2.getParameters();
|
||||
byte[] answer = c2.doFinal(plainTxt);
|
||||
System.out.println("Encryption tests: START");
|
||||
test(c1, Cipher.ENCRYPT_MODE, key, params, firstBlkSize,
|
||||
plainTxt, answer);
|
||||
System.out.println("Encryption tests: DONE");
|
||||
c2.init(Cipher.DECRYPT_MODE, key, params);
|
||||
byte[] answer2 = c2.doFinal(answer);
|
||||
System.out.println("Decryption tests: START");
|
||||
test(c1, Cipher.DECRYPT_MODE, key, params, firstBlkSize,
|
||||
answer, answer2);
|
||||
System.out.println("Decryption tests: DONE");
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
System.out.println("Skipping unsupported algorithm: " +
|
||||
nsae);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// print out debug info when exception is encountered
|
||||
if (debugBuf != null) {
|
||||
System.out.println(debugBuf.toString());
|
||||
debugBuf = new StringBuffer();
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(Cipher cipher, int mode, SecretKey key,
|
||||
AlgorithmParameters params, int firstBlkSize,
|
||||
byte[] in, byte[] answer) throws Exception {
|
||||
// test setup
|
||||
long startTime, endTime;
|
||||
cipher.init(mode, key, params);
|
||||
int outLen = cipher.getOutputSize(in.length);
|
||||
//debugOut("Estimated output size = " + outLen + "\n");
|
||||
|
||||
// test data preparation
|
||||
ByteBuffer inBuf = ByteBuffer.allocate(in.length);
|
||||
inBuf.put(in);
|
||||
inBuf.position(0);
|
||||
ByteBuffer inDirectBuf = ByteBuffer.allocateDirect(in.length);
|
||||
inDirectBuf.put(in);
|
||||
inDirectBuf.position(0);
|
||||
ByteBuffer outBuf = ByteBuffer.allocate(outLen);
|
||||
ByteBuffer outDirectBuf = ByteBuffer.allocateDirect(outLen);
|
||||
|
||||
// test#1: byte[] in + byte[] out
|
||||
//debugOut("Test#1:\n");
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
startTime = System.nanoTime();
|
||||
byte[] temp = cipher.update(in, 0, firstBlkSize);
|
||||
if (temp != null && temp.length > 0) {
|
||||
baos.write(temp, 0, temp.length);
|
||||
}
|
||||
temp = cipher.doFinal(in, firstBlkSize, in.length - firstBlkSize);
|
||||
if (temp != null && temp.length > 0) {
|
||||
baos.write(temp, 0, temp.length);
|
||||
}
|
||||
byte[] testOut1 = baos.toByteArray();
|
||||
endTime = System.nanoTime();
|
||||
perfOut("stream InBuf + stream OutBuf: " +
|
||||
(endTime - startTime));
|
||||
match(testOut1, answer);
|
||||
|
||||
// test#2: Non-direct Buffer in + non-direct Buffer out
|
||||
//debugOut("Test#2:\n");
|
||||
//debugOut("inputBuf: " + inBuf + "\n");
|
||||
//debugOut("outputBuf: " + outBuf + "\n");
|
||||
|
||||
startTime = System.nanoTime();
|
||||
cipher.update(inBuf, outBuf);
|
||||
cipher.doFinal(inBuf, outBuf);
|
||||
endTime = System.nanoTime();
|
||||
perfOut("non-direct InBuf + non-direct OutBuf: " +
|
||||
(endTime - startTime));
|
||||
match(outBuf, answer);
|
||||
|
||||
// test#3: Direct Buffer in + direc Buffer out
|
||||
//debugOut("Test#3:\n");
|
||||
//debugOut("(pre) inputBuf: " + inDirectBuf + "\n");
|
||||
//debugOut("(pre) outputBuf: " + outDirectBuf + "\n");
|
||||
|
||||
startTime = System.nanoTime();
|
||||
cipher.update(inDirectBuf, outDirectBuf);
|
||||
cipher.doFinal(inDirectBuf, outDirectBuf);
|
||||
endTime = System.nanoTime();
|
||||
perfOut("direct InBuf + direct OutBuf: " +
|
||||
(endTime - startTime));
|
||||
|
||||
//debugOut("(post) inputBuf: " + inDirectBuf + "\n");
|
||||
//debugOut("(post) outputBuf: " + outDirectBuf + "\n");
|
||||
match(outDirectBuf, answer);
|
||||
|
||||
// test#4: Direct Buffer in + non-direct Buffer out
|
||||
//debugOut("Test#4:\n");
|
||||
inDirectBuf.position(0);
|
||||
outBuf.position(0);
|
||||
//debugOut("inputBuf: " + inDirectBuf + "\n");
|
||||
//debugOut("outputBuf: " + outBuf + "\n");
|
||||
|
||||
startTime = System.nanoTime();
|
||||
cipher.update(inDirectBuf, outBuf);
|
||||
cipher.doFinal(inDirectBuf, outBuf);
|
||||
endTime = System.nanoTime();
|
||||
perfOut("direct InBuf + non-direct OutBuf: " +
|
||||
(endTime - startTime));
|
||||
match(outBuf, answer);
|
||||
|
||||
// test#5: Non-direct Buffer in + direct Buffer out
|
||||
//debugOut("Test#5:\n");
|
||||
inBuf.position(0);
|
||||
outDirectBuf.position(0);
|
||||
|
||||
//debugOut("(pre) inputBuf: " + inBuf + "\n");
|
||||
//debugOut("(pre) outputBuf: " + outDirectBuf + "\n");
|
||||
|
||||
startTime = System.nanoTime();
|
||||
cipher.update(inBuf, outDirectBuf);
|
||||
cipher.doFinal(inBuf, outDirectBuf);
|
||||
endTime = System.nanoTime();
|
||||
perfOut("non-direct InBuf + direct OutBuf: " +
|
||||
(endTime - startTime));
|
||||
|
||||
//debugOut("(post) inputBuf: " + inBuf + "\n");
|
||||
//debugOut("(post) outputBuf: " + outDirectBuf + "\n");
|
||||
match(outDirectBuf, answer);
|
||||
|
||||
debugBuf = null;
|
||||
}
|
||||
|
||||
private static void perfOut(String msg) {
|
||||
if (debugBuf != null) {
|
||||
debugBuf.append("PERF>" + msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static void debugOut(String msg) {
|
||||
if (debugBuf != null) {
|
||||
debugBuf.append(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static void match(byte[] b1, byte[] b2) throws Exception {
|
||||
if (b1.length != b2.length) {
|
||||
debugOut("got len : " + b1.length + "\n");
|
||||
debugOut("expect len: " + b2.length + "\n");
|
||||
throw new Exception("mismatch - different length! got: " + b1.length + ", expect: " + b2.length + "\n");
|
||||
} else {
|
||||
for (int i = 0; i < b1.length; i++) {
|
||||
if (b1[i] != b2[i]) {
|
||||
debugOut("got : " + toString(b1) + "\n");
|
||||
debugOut("expect: " + toString(b2) + "\n");
|
||||
throw new Exception("mismatch");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void match(ByteBuffer bb, byte[] answer) throws Exception {
|
||||
byte[] bbTemp = new byte[bb.position()];
|
||||
bb.position(0);
|
||||
bb.get(bbTemp, 0, bbTemp.length);
|
||||
match(bbTemp, answer);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
main(new TestSymmCiphers());
|
||||
}
|
||||
}
|
194
jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.java
Normal file
194
jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.java
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.cert.*;
|
||||
import java.security.spec.*;
|
||||
import java.security.interfaces.*;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
public class SecretKeysBasic extends PKCS11Test {
|
||||
|
||||
private static final char SEP = File.separatorChar;
|
||||
private static char[] tokenPwd;
|
||||
private static final char[] nssPwd =
|
||||
new char[]{'t', 'e', 's', 't', '1', '2'};
|
||||
private static final char[] solarisPwd =
|
||||
new char[]{'p', 'i', 'n'};
|
||||
private static SecretKey sk1;
|
||||
private static SecretKey sk2;
|
||||
private static SecretKey softkey;
|
||||
private static KeyStore ks;
|
||||
private static final String KS_TYPE = "PKCS11";
|
||||
private static Provider provider;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
main(new SecretKeysBasic());
|
||||
}
|
||||
|
||||
public void main(Provider p) throws Exception {
|
||||
this.provider = p;
|
||||
|
||||
// create secret key
|
||||
byte[] keyVal = new byte[16];
|
||||
(new SecureRandom()).nextBytes(keyVal);
|
||||
// NSS will throw CKR_HOST_MEMORY if calling C_DecryptInit w/
|
||||
// (keyVal[0] == 0)
|
||||
if (keyVal[0] == 0) {
|
||||
keyVal[0] = 1;
|
||||
}
|
||||
softkey = new SecretKeySpec(keyVal, "AES");
|
||||
dumpKey("softkey", softkey);
|
||||
|
||||
KeyGenerator kg = KeyGenerator.getInstance("DESede", provider);
|
||||
sk1 = kg.generateKey();
|
||||
dumpKey("skey1", sk1);
|
||||
sk2 = kg.generateKey();
|
||||
dumpKey("skey2", sk2);
|
||||
|
||||
String token = System.getProperty("TOKEN");
|
||||
|
||||
if (token == null || token.length() == 0) {
|
||||
System.out.println("Error: missing TOKEN system property");
|
||||
throw new Exception("token arg required");
|
||||
}
|
||||
|
||||
if ("nss".equals(token)) {
|
||||
tokenPwd = nssPwd;
|
||||
} else if ("solaris".equals(token)) {
|
||||
tokenPwd = solarisPwd;
|
||||
}
|
||||
|
||||
int testnum = 1;
|
||||
doTest();
|
||||
}
|
||||
|
||||
private static boolean checkSecretKeyEntry(String alias,
|
||||
SecretKey expected,
|
||||
boolean saveBeforeCheck)
|
||||
throws Exception {
|
||||
if (saveBeforeCheck) {
|
||||
ks.setKeyEntry(alias, expected, null, null);
|
||||
}
|
||||
SecretKey result = (SecretKey) (ks.getKey(alias, null));
|
||||
String keyEncFormat = result.getFormat();
|
||||
if (keyEncFormat == null) {
|
||||
// sensitive or un-extractable keys - verify by encrypt/decrypt
|
||||
byte[] data = new byte[64];
|
||||
Cipher c =
|
||||
Cipher.getInstance(result.getAlgorithm() + "/CBC/NoPadding",
|
||||
provider);
|
||||
c.init(Cipher.ENCRYPT_MODE, expected);
|
||||
byte[] encOut = c.doFinal(data);
|
||||
c.init(Cipher.DECRYPT_MODE, result, c.getParameters());
|
||||
byte[] decOut = c.doFinal(encOut);
|
||||
if (!Arrays.equals(data, decOut)) {
|
||||
return false;
|
||||
}
|
||||
} else if (keyEncFormat.toUpperCase().equals("RAW")) {
|
||||
if (!Arrays.equals(result.getEncoded(), expected.getEncoded())) {
|
||||
dumpKey("\texpected:", expected);
|
||||
dumpKey("\treturns:", result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void dumpKey(String info, SecretKey key) {
|
||||
System.out.println(info + "> " + key);
|
||||
System.out.println("\tALGO=" + key.getAlgorithm());
|
||||
if (key.getFormat() != null) {
|
||||
System.out.println("\t[" + key.getFormat() + "] VALUE=" +
|
||||
new BigInteger(key.getEncoded()));
|
||||
} else {
|
||||
System.out.println("\tVALUE=n/a");
|
||||
}
|
||||
}
|
||||
|
||||
private static void doTest() throws Exception {
|
||||
if (ks == null) {
|
||||
ks = KeyStore.getInstance(KS_TYPE, provider);
|
||||
ks.load(null, tokenPwd);
|
||||
}
|
||||
|
||||
System.out.println("Number of entries: " + ks.size());
|
||||
if (ks.size() != 0) {
|
||||
System.out.println("Deleting entries under aliases: ");
|
||||
for (Enumeration<String> aliases = ks.aliases();
|
||||
aliases.hasMoreElements();) {
|
||||
String alias = aliases.nextElement();
|
||||
System.out.println("\t" + alias);
|
||||
ks.deleteEntry(alias);
|
||||
}
|
||||
}
|
||||
|
||||
String alias = "testSKey";
|
||||
|
||||
boolean testResult = checkSecretKeyEntry(alias, softkey, true);
|
||||
if (!testResult) {
|
||||
System.out.println("FAILURE: setKey() w/ softSecretKey failed");
|
||||
}
|
||||
|
||||
if (!checkSecretKeyEntry(alias, sk1, true)) {
|
||||
testResult = false;
|
||||
System.out.println("FAILURE: setKey() w/ skey1 failed");
|
||||
}
|
||||
if (!checkSecretKeyEntry(alias, sk2, true)) {
|
||||
testResult = false;
|
||||
System.out.println("FAILURE: setKey() w/ skey2 failed");
|
||||
}
|
||||
|
||||
ks.store(null);
|
||||
System.out.println("Reloading keystore...");
|
||||
|
||||
ks.load(null, "whatever".toCharArray());
|
||||
if (ks.size() != 1) {
|
||||
System.out.println("FAILURE: reload#1 ks.size() != 1");
|
||||
}
|
||||
if (!checkSecretKeyEntry(alias, sk2, false)) {
|
||||
testResult = false;
|
||||
System.out.println("FAILURE: reload#1 ks entry check failed");
|
||||
}
|
||||
|
||||
ks.deleteEntry(alias);
|
||||
ks.store(null);
|
||||
|
||||
System.out.println("Reloading keystore...");
|
||||
ks.load(null, "whatever".toCharArray());
|
||||
if (ks.size() != 0) {
|
||||
testResult = false;
|
||||
System.out.println("FAILURE: reload#2 ks.size() != 0");
|
||||
}
|
||||
if (!testResult) {
|
||||
throw new Exception("One or more test failed!");
|
||||
}
|
||||
}
|
||||
}
|
164
jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh
Normal file
164
jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh
Normal file
@ -0,0 +1,164 @@
|
||||
#
|
||||
# Copyright 2008 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 6599979
|
||||
# @summary Ensure that re-assigning the alias works
|
||||
#
|
||||
# @run shell SecretKeysBasic.sh
|
||||
#
|
||||
# To run by hand:
|
||||
# %sh SecretKeysBasic.sh
|
||||
#
|
||||
# Note:
|
||||
# . test only runs on solaris at the moment
|
||||
|
||||
# set a few environment variables so that the shell-script can run stand-alone
|
||||
# in the source directory
|
||||
|
||||
# if running by hand on windows, change TESTSRC and TESTCLASSES to "."
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC=`pwd`
|
||||
fi
|
||||
if [ "${TESTCLASSES}" = "" ] ; then
|
||||
TESTCLASSES=`pwd`
|
||||
fi
|
||||
|
||||
# if running by hand on windows, change this to appropriate value
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
TESTJAVA="/net/shimmer/export/valeriep/jdk7/build/solaris-sparc"
|
||||
fi
|
||||
echo TESTSRC=${TESTSRC}
|
||||
echo TESTCLASSES=${TESTCLASSES}
|
||||
echo TESTJAVA=${TESTJAVA}
|
||||
echo ""
|
||||
|
||||
#DEBUG=sunpkcs11,pkcs11keystore
|
||||
|
||||
echo DEBUG=${DEBUG}
|
||||
echo ""
|
||||
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS )
|
||||
FS="/"
|
||||
PS=":"
|
||||
SCCS="${FS}usr${FS}ccs${FS}bin${FS}sccs"
|
||||
CP="${FS}bin${FS}cp -f"
|
||||
RM="${FS}bin${FS}rm -rf"
|
||||
MKDIR="${FS}bin${FS}mkdir -p"
|
||||
CHMOD="${FS}bin${FS}chmod"
|
||||
;;
|
||||
* )
|
||||
echo "Unsupported System ${OS} - Test only runs on Solaris"
|
||||
exit 0;
|
||||
;;
|
||||
esac
|
||||
|
||||
TOKENS="nss solaris"
|
||||
STATUS=0
|
||||
for token in ${TOKENS}
|
||||
do
|
||||
|
||||
if [ ${token} = "nss" ]
|
||||
then
|
||||
# make cert/key DBs writable if token is NSS
|
||||
${CP} ${TESTSRC}${FS}..${FS}nss${FS}db${FS}cert8.db ${TESTCLASSES}
|
||||
${CHMOD} +w ${TESTCLASSES}${FS}cert8.db
|
||||
|
||||
${CP} ${TESTSRC}${FS}..${FS}nss${FS}db${FS}key3.db ${TESTCLASSES}
|
||||
${CHMOD} +w ${TESTCLASSES}${FS}key3.db
|
||||
USED_FILE_LIST="${TESTCLASSES}${FS}cert8.db ${TESTCLASSES}${FS}key3.db"
|
||||
elif [ ${token} = "solaris" ]
|
||||
then
|
||||
OS_VERSION=`uname -r`
|
||||
case "${OS_VERSION}" in
|
||||
5.1* )
|
||||
SOFTTOKEN_DIR=${TESTCLASSES}
|
||||
export SOFTTOKEN_DIR
|
||||
;;
|
||||
* )
|
||||
echo "Unsupported Version ${OS_VERSION} - Test only runs on Solaris"
|
||||
exit 0;
|
||||
;;
|
||||
esac
|
||||
|
||||
# copy keystore into write-able location
|
||||
if [ -d ${TESTCLASSES}${FS}pkcs11_softtoken ]
|
||||
then
|
||||
echo "Removing old pkcs11_keystore, creating new pkcs11_keystore"
|
||||
|
||||
echo ${RM} ${TESTCLASSES}${FS}pkcs11_softtoken
|
||||
${RM} ${TESTCLASSES}${FS}pkcs11_softtoken
|
||||
fi
|
||||
echo ${MKDIR} ${TESTCLASSES}${FS}pkcs11_softtoken${FS}private
|
||||
${MKDIR} ${TESTCLASSES}${FS}pkcs11_softtoken${FS}private
|
||||
|
||||
echo ${MKDIR} ${TESTCLASSES}${FS}pkcs11_softtoken${FS}public
|
||||
${MKDIR} ${TESTCLASSES}${FS}pkcs11_softtoken${FS}public
|
||||
|
||||
echo ${CP} ${TESTSRC}${FS}BasicData${FS}pkcs11_softtoken${FS}objstore_info \
|
||||
${TESTCLASSES}${FS}pkcs11_softtoken
|
||||
${CP} ${TESTSRC}${FS}BasicData${FS}pkcs11_softtoken${FS}objstore_info \
|
||||
${TESTCLASSES}${FS}pkcs11_softtoken
|
||||
|
||||
echo ${CHMOD} +w ${TESTCLASSES}${FS}pkcs11_softtoken${FS}objstore_info
|
||||
${CHMOD} 600 ${TESTCLASSES}${FS}pkcs11_softtoken${FS}objstore_info
|
||||
USED_FILE_LIST="${TESTCLASSES}${FS}pkcs11_softtoken"
|
||||
fi
|
||||
|
||||
cd ${TESTCLASSES}
|
||||
${TESTJAVA}${FS}bin${FS}javac \
|
||||
-classpath ${TESTCLASSES} \
|
||||
-d ${TESTCLASSES} \
|
||||
${TESTSRC}${FS}SecretKeysBasic.java
|
||||
|
||||
# run test
|
||||
cd ${TESTSRC}
|
||||
${TESTJAVA}${FS}bin${FS}java \
|
||||
-DDIR=${TESTSRC}${FS}BasicData${FS} \
|
||||
-classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \
|
||||
-DCUSTOM_DB_DIR=${TESTCLASSES} \
|
||||
-DCUSTOM_P11_CONFIG=${TESTSRC}${FS}BasicData${FS}p11-${token}.txt \
|
||||
-DNO_DEFAULT=true \
|
||||
-DNO_DEIMOS=true \
|
||||
-DTOKEN=${token} \
|
||||
-Djava.security.debug=${DEBUG} \
|
||||
SecretKeysBasic
|
||||
|
||||
# -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}BasicData${FS}p11-${token}.txt \
|
||||
|
||||
# save error status
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "Test against " ${token} " Failed!"
|
||||
STATUS=1
|
||||
fi
|
||||
|
||||
# clean up
|
||||
${RM} ${USED_FILE_LIST}
|
||||
|
||||
done
|
||||
|
||||
# return
|
||||
exit ${STATUS}
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright 2001-2008 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 6668231
|
||||
* @summary Presence of a critical subjectAltName causes JSSE's SunX509 to
|
||||
* fail trusted checks
|
||||
* @author Xuelei Fan
|
||||
*
|
||||
* This test depends on binary keystore, crisubn.jks and trusted.jks. Because
|
||||
* JAVA keytool cannot generate X509 certificate with SubjectAltName extension,
|
||||
* the certificates are generated with openssl toolkits and then imported into
|
||||
* JAVA keystore.
|
||||
*
|
||||
* The crisubn.jks holds a private key entry and the corresponding X509
|
||||
* certificate issued with an empty Subject field, and a critical
|
||||
* SubjectAltName extension.
|
||||
*
|
||||
* The trusted.jks holds the trusted certificate.
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import javax.net.ssl.*;
|
||||
import java.security.cert.Certificate;
|
||||
|
||||
public class CriticalSubjectAltName implements HostnameVerifier {
|
||||
/*
|
||||
* =============================================================
|
||||
* Set the various variables needed for the tests, then
|
||||
* specify what tests to run on each side.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Should we run the client or server in a separate thread?
|
||||
* Both sides can throw exceptions, but do you have a preference
|
||||
* as to which side should be the main thread.
|
||||
*/
|
||||
static boolean separateServerThread = true;
|
||||
|
||||
/*
|
||||
* Where do we find the keystores?
|
||||
*/
|
||||
static String pathToStores = "./";
|
||||
static String keyStoreFile = "crisubn.jks";
|
||||
static String trustStoreFile = "trusted.jks";
|
||||
static String passwd = "passphrase";
|
||||
|
||||
/*
|
||||
* Is the server ready to serve?
|
||||
*/
|
||||
volatile static boolean serverReady = false;
|
||||
|
||||
/*
|
||||
* Turn on SSL debugging?
|
||||
*/
|
||||
static boolean debug = false;
|
||||
|
||||
/*
|
||||
* If the client or server is doing some kind of object creation
|
||||
* that the other side depends on, and that thread prematurely
|
||||
* exits, you may experience a hang. The test harness will
|
||||
* terminate all hung threads after its timeout has expired,
|
||||
* currently 3 minutes by default, but you might try to be
|
||||
* smart about it....
|
||||
*/
|
||||
|
||||
/*
|
||||
* Define the server side of the test.
|
||||
*
|
||||
* If the server prematurely exits, serverReady will be set to true
|
||||
* to avoid infinite hangs.
|
||||
*/
|
||||
void doServerSide() throws Exception {
|
||||
SSLServerSocketFactory sslssf =
|
||||
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
|
||||
SSLServerSocket sslServerSocket =
|
||||
(SSLServerSocket) sslssf.createServerSocket(serverPort);
|
||||
serverPort = sslServerSocket.getLocalPort();
|
||||
|
||||
/*
|
||||
* Signal Client, we're ready for his connect.
|
||||
*/
|
||||
serverReady = true;
|
||||
|
||||
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
|
||||
OutputStream sslOS = sslSocket.getOutputStream();
|
||||
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sslOS));
|
||||
bw.write("HTTP/1.1 200 OK\r\n\r\n\r\n");
|
||||
bw.flush();
|
||||
Thread.sleep(5000);
|
||||
sslSocket.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the client side of the test.
|
||||
*
|
||||
* If the server prematurely exits, serverReady will be set to true
|
||||
* to avoid infinite hangs.
|
||||
*/
|
||||
void doClientSide() throws Exception {
|
||||
|
||||
/*
|
||||
* Wait for server to get started.
|
||||
*/
|
||||
while (!serverReady) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
URL url = new URL("https://localhost:"+serverPort+"/index.html");
|
||||
HttpsURLConnection urlc = (HttpsURLConnection)url.openConnection();
|
||||
urlc.setHostnameVerifier(this);
|
||||
urlc.getInputStream();
|
||||
|
||||
if (urlc.getResponseCode() == -1) {
|
||||
throw new RuntimeException("getResponseCode() returns -1");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* =============================================================
|
||||
* The remainder is just support stuff
|
||||
*/
|
||||
|
||||
// use any free port by default
|
||||
volatile int serverPort = 0;
|
||||
|
||||
volatile Exception serverException = null;
|
||||
volatile Exception clientException = null;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String keyFilename =
|
||||
System.getProperty("test.src", "./") + "/" + pathToStores +
|
||||
"/" + keyStoreFile;
|
||||
String trustFilename =
|
||||
System.getProperty("test.src", "./") + "/" + pathToStores +
|
||||
"/" + trustStoreFile;
|
||||
|
||||
System.setProperty("javax.net.ssl.keyStore", keyFilename);
|
||||
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
|
||||
System.setProperty("javax.net.ssl.trustStore", trustFilename);
|
||||
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
|
||||
|
||||
if (debug)
|
||||
System.setProperty("javax.net.debug", "all");
|
||||
|
||||
/*
|
||||
* Start the tests.
|
||||
*/
|
||||
new CriticalSubjectAltName();
|
||||
}
|
||||
|
||||
Thread clientThread = null;
|
||||
Thread serverThread = null;
|
||||
|
||||
/*
|
||||
* Primary constructor, used to drive remainder of the test.
|
||||
*
|
||||
* Fork off the other side, then do your work.
|
||||
*/
|
||||
CriticalSubjectAltName() throws Exception {
|
||||
if (separateServerThread) {
|
||||
startServer(true);
|
||||
startClient(false);
|
||||
} else {
|
||||
startClient(true);
|
||||
startServer(false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for other side to close down.
|
||||
*/
|
||||
if (separateServerThread) {
|
||||
serverThread.join();
|
||||
} else {
|
||||
clientThread.join();
|
||||
}
|
||||
|
||||
/*
|
||||
* When we get here, the test is pretty much over.
|
||||
*
|
||||
* If the main thread excepted, that propagates back
|
||||
* immediately. If the other thread threw an exception, we
|
||||
* should report back.
|
||||
*/
|
||||
if (serverException != null)
|
||||
throw serverException;
|
||||
if (clientException != null)
|
||||
throw clientException;
|
||||
}
|
||||
|
||||
void startServer(boolean newThread) throws Exception {
|
||||
if (newThread) {
|
||||
serverThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
doServerSide();
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* Our server thread just died.
|
||||
*
|
||||
* Release the client, if not active already...
|
||||
*/
|
||||
System.err.println("Server died...");
|
||||
serverReady = true;
|
||||
serverException = e;
|
||||
}
|
||||
}
|
||||
};
|
||||
serverThread.start();
|
||||
} else {
|
||||
doServerSide();
|
||||
}
|
||||
}
|
||||
|
||||
void startClient(boolean newThread) throws Exception {
|
||||
if (newThread) {
|
||||
clientThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
doClientSide();
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* Our client thread just died.
|
||||
*/
|
||||
System.err.println("Client died...");
|
||||
clientException = e;
|
||||
}
|
||||
}
|
||||
};
|
||||
clientThread.start();
|
||||
} else {
|
||||
doClientSide();
|
||||
}
|
||||
}
|
||||
|
||||
// Simple test method to blindly agree that hostname and certname match
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user