提交 05fd4e51 编写于 作者: T tbell

Merge

#
# 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
......
#
# 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
......@@ -449,11 +449,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))
......
#
# 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
#
......
#
# 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
......
#
# 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
......
#
# 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 {
......
/*
* 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
......
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 <===================================
......
/*
* 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,
......
/*
* 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
......
/*
* 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_PRIVATE_TRUE,
new CK_ATTRIBUTE(CKA_LABEL, alias),
};
try {
P11SecretKeyFactory.convertKey(token, skey, null, attrs);
} catch (InvalidKeyException ike) {
// re-throw KeyStoreException to match javadoc
throw new KeyStoreException("Cannot convert to PKCS11 keys", ike);
}
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);
// update global alias map
aliasMap.put(alias, new AliasInfo(alias));
// create the new entry
Session session = null;
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);
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() {
......
/*
* 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);
}
......
/*
* 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");
}
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");
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);
}
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");
}
......
/*
* 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;
}
......
/*
* 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
......
#
# 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
/*
* 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());
}
}
/*
* 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
*/
......
#
# 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
/*
* 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();
}
}
}
}
/*
* 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!");
}
}
/*
* 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.
}
/*
* 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.
}
/*
* 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.
}
/*
* 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.
}
/*
* 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.
}
......@@ -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
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册