mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-02 04:00:16 +00:00
Merge
This commit is contained in:
commit
fa77b083c4
@ -367,8 +367,24 @@ COPY_FILES += $(PROPS_DST)
|
||||
POLICY_SRC := $(JDK_TOPDIR)/src/share/lib/security/java.policy
|
||||
POLICY_DST := $(JDK_OUTPUTDIR)/lib/security/java.policy
|
||||
|
||||
$(POLICY_DST): $(POLICY_SRC)
|
||||
$(call install-file)
|
||||
POLICY_SRC_LIST :=
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
POLICY_SRC_LIST += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS)/lib/security/java.policy
|
||||
endif
|
||||
ifndef OPENJDK
|
||||
ifneq (, $(filter $(OPENJDK_TARGET_OS), windows solaris))
|
||||
POLICY_SRC_LIST += $(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS)/lib/security/java.policy
|
||||
endif
|
||||
endif
|
||||
|
||||
POLICY_SRC_LIST += $(POLICY_SRC)
|
||||
|
||||
$(POLICY_DST): $(POLICY_SRC_LIST)
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@ $@.tmp
|
||||
$(foreach f,$(POLICY_SRC_LIST),$(CAT) $(f) >> $@.tmp;)
|
||||
$(MV) $@.tmp $@
|
||||
|
||||
COPY_FILES += $(POLICY_DST)
|
||||
|
||||
|
||||
@ -21,4 +21,4 @@
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
tzdata2014b
|
||||
tzdata2014c
|
||||
|
||||
@ -358,11 +358,54 @@ Rule Egypt 2007 only - Sep Thu>=1 23:00s 0 -
|
||||
# http://www.worldtimezone.com/dst_news/dst_news_egypt02.html
|
||||
# </a>
|
||||
|
||||
# From Ahmad El-Dardiry (2014-05-07):
|
||||
# Egypt is to change back to Daylight system on May 15
|
||||
# http://english.ahram.org.eg/NewsContent/1/64/100735/Egypt/Politics-/Egypts-government-to-reapply-daylight-saving-time-.aspx
|
||||
|
||||
# From Gunther Vermier (2015-05-13):
|
||||
# our Egypt office confirms that the change will be at 15 May "midnight" (24:00)
|
||||
|
||||
# From Paul Eggert (2014-05-13):
|
||||
# Sarah El Deeb and Lee Keath of AP report that the Egyptian government says
|
||||
# the change is because of blackouts in Cairo, even though Ahram Online (cited
|
||||
# above) says DST had no affect on electricity consumption. The AP story says
|
||||
# DST will not be observed during Ramadan. There is no information about when
|
||||
# DST will end. See:
|
||||
# http://abcnews.go.com/International/wireStory/el-sissi-pushes-egyptians-line-23614833
|
||||
#
|
||||
# For now, guess that later transitions will use 2010's rules, and that
|
||||
# Egypt will agree with Morocco (see below) about the date Ramadan starts and
|
||||
# ends, though (unlike Morocco) it will switch at 00:00 standard time. In
|
||||
# Egypt the spring-forward transitions are removed for 2020-2022, when the
|
||||
# guessed spring-forward date falls during the estimated Ramadan, and all
|
||||
# transitions removed for 2023-2038, where the estimated Ramadan falls entirely
|
||||
# outside the guessed daylight-saving time. Ramadan intrudes on the guessed
|
||||
# DST starting in 2039, but that's beyond our somewhat-arbitrary cutoff.
|
||||
|
||||
Rule Egypt 2008 only - Aug lastThu 23:00s 0 -
|
||||
Rule Egypt 2009 only - Aug 20 23:00s 0 -
|
||||
Rule Egypt 2010 only - Aug 11 0:00 0 -
|
||||
Rule Egypt 2010 only - Sep 10 0:00 1:00 S
|
||||
Rule Egypt 2010 only - Sep lastThu 23:00s 0 -
|
||||
Rule Egypt 2014 only - May 15 24:00 1:00 S
|
||||
Rule Egypt 2014 only - Jun 29 0:00s 0 -
|
||||
Rule Egypt 2014 only - Jul 29 0:00s 1:00 S
|
||||
Rule Egypt 2014 max - Sep lastThu 23:00s 0 -
|
||||
Rule Egypt 2015 2019 - Apr lastFri 0:00s 1:00 S
|
||||
Rule Egypt 2015 only - Jun 18 0:00s 0 -
|
||||
Rule Egypt 2015 only - Jul 18 0:00s 1:00 S
|
||||
Rule Egypt 2016 only - Jun 7 0:00s 0 -
|
||||
Rule Egypt 2016 only - Jul 7 0:00s 1:00 S
|
||||
Rule Egypt 2017 only - May 27 0:00s 0 -
|
||||
Rule Egypt 2017 only - Jun 26 0:00s 1:00 S
|
||||
Rule Egypt 2018 only - May 16 0:00s 0 -
|
||||
Rule Egypt 2018 only - Jun 15 0:00s 1:00 S
|
||||
Rule Egypt 2019 only - May 6 0:00s 0 -
|
||||
Rule Egypt 2019 only - Jun 5 0:00s 1:00 S
|
||||
Rule Egypt 2020 only - May 24 0:00s 1:00 S
|
||||
Rule Egypt 2021 only - May 13 0:00s 1:00 S
|
||||
Rule Egypt 2022 only - May 3 0:00s 1:00 S
|
||||
Rule Egypt 2023 max - Apr lastFri 0:00s 1:00 S
|
||||
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Africa/Cairo 2:05:09 - LMT 1900 Oct
|
||||
|
||||
@ -1370,22 +1370,6 @@ Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u
|
||||
# "Jordan will switch to winter time on Friday, October 27".
|
||||
#
|
||||
|
||||
# From Phil Pizzey (2009-04-02):
|
||||
# ...I think I may have spotted an error in the timezone data for
|
||||
# Jordan.
|
||||
# The current (2009d) asia file shows Jordan going to daylight
|
||||
# saving
|
||||
# time on the last Thursday in March.
|
||||
#
|
||||
# Rule Jordan 2000 max - Mar lastThu 0:00s 1:00 S
|
||||
#
|
||||
# However timeanddate.com, which I usually find reliable, shows Jordan
|
||||
# going to daylight saving time on the last Friday in March since 2002.
|
||||
# Please see
|
||||
# <a href="http://www.timeanddate.com/worldclock/timezone.html?n=11">
|
||||
# http://www.timeanddate.com/worldclock/timezone.html?n=11
|
||||
# </a>
|
||||
|
||||
# From Steffen Thorsen (2009-04-02):
|
||||
# This single one might be good enough, (2009-03-24, Arabic):
|
||||
# <a href="http://petra.gov.jo/Artical.aspx?Lng=2&Section=8&Artical=95279">
|
||||
|
||||
@ -2989,6 +2989,10 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880
|
||||
# From Alexander Krivenyshev (2014-03-17):
|
||||
# time change at 2:00 (2am) on March 30, 2014
|
||||
# http://vz.ru/news/2014/3/17/677464.html
|
||||
# From Paul Eggert (2014-03-30):
|
||||
# Simferopol and Sevastopol reportedly changed their central town clocks
|
||||
# late the previous day, but this appears to have been ceremonial
|
||||
# and the discrepancies are small enough to not worry about.
|
||||
2:00 EU EE%sT 2014 Mar 30 2:00
|
||||
4:00 - MSK
|
||||
|
||||
|
||||
@ -62,25 +62,6 @@ GENSRC_MISC += $(JDK_OUTPUTDIR)/gensrc/sun/tools/jconsole/Version.java
|
||||
|
||||
##########################################################################################
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS_API), posix)
|
||||
UPSUFFIX := $(OPENJDK_TARGET_OS)
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
UPSUFFIX := bsd
|
||||
endif
|
||||
# UNIXProcess.java is different for solaris and linux. We need to copy
|
||||
# the correct UNIXProcess.java over to $(JDK_OUTPUTDIR)/gensrc/java/lang/.
|
||||
|
||||
$(JDK_OUTPUTDIR)/gensrc/java/lang/UNIXProcess.java: \
|
||||
$(JDK_TOPDIR)/src/solaris/classes/java/lang/UNIXProcess.java.$(UPSUFFIX)
|
||||
$(ECHO) $(LOG_INFO) Copying UNIXProcess.java.$(OPENJDK_TARGET_OS) to java/lang/UNIXProcess.java
|
||||
$(call install-file)
|
||||
$(CHMOD) u+rw $@
|
||||
|
||||
GENSRC_MISC += $(JDK_OUTPUTDIR)/gensrc/java/lang/UNIXProcess.java
|
||||
endif
|
||||
|
||||
##########################################################################################
|
||||
|
||||
GENSRC_MISC += $(JDK_OUTPUTDIR)/gensrc/sun/nio/ch/SocketOptionRegistry.java
|
||||
|
||||
GENSRC_SOR_SRC := $(JDK_TOPDIR)/make/src/native/genconstants/ch
|
||||
|
||||
@ -100,9 +100,7 @@ PROFILE_2_RTJAR_INCLUDE_TYPES :=
|
||||
|
||||
PROFILE_2_RTJAR_EXCLUDE_TYPES :=
|
||||
|
||||
PROFILE_2_INCLUDE_METAINF_SERVICES := \
|
||||
META-INF/services/sun.util.spi.XmlPropertiesProvider
|
||||
|
||||
PROFILE_2_INCLUDE_METAINF_SERVICES :=
|
||||
|
||||
PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
|
||||
com/sun/jmx \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,38 +22,33 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.internal.util.xml;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.InvalidPropertiesFormatException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
package com.sun.tools.attach;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.util.spi.XmlPropertiesProvider;
|
||||
|
||||
/**
|
||||
* A {@code XmlPropertiesProvider} implementation that uses the UKit XML parser.
|
||||
* Exception type to signal that an attach operation failed in the target VM.
|
||||
*
|
||||
* <p> This exception can be thrown by the various operations of
|
||||
* {@link com.sun.tools.attach.VirtualMachine} when the operation
|
||||
* fails in the target VM. If there is a communication error,
|
||||
* a regular IOException will be thrown.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
@jdk.Exported
|
||||
public class AttachOperationFailedException extends IOException {
|
||||
|
||||
public class BasicXmlPropertiesProvider extends XmlPropertiesProvider {
|
||||
private static final long serialVersionUID = 2140308168167478043L;
|
||||
|
||||
public BasicXmlPropertiesProvider() { }
|
||||
|
||||
@Override
|
||||
public void load(Properties props, InputStream in)
|
||||
throws IOException, InvalidPropertiesFormatException
|
||||
{
|
||||
PropertiesDefaultHandler handler = new PropertiesDefaultHandler();
|
||||
handler.load(props, in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(Properties props, OutputStream os, String comment,
|
||||
String encoding)
|
||||
throws IOException
|
||||
{
|
||||
PropertiesDefaultHandler handler = new PropertiesDefaultHandler();
|
||||
handler.store(props, os, comment, encoding);
|
||||
/**
|
||||
* Constructs an <code>AttachOperationFailedException</code> with
|
||||
* the specified detail message.
|
||||
*
|
||||
* @param s the detail message.
|
||||
*/
|
||||
public AttachOperationFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -564,8 +564,15 @@ public abstract class VirtualMachine {
|
||||
*
|
||||
* @return The system properties
|
||||
*
|
||||
* @throws AttachOperationFailedException
|
||||
* If the target virtual machine is unable to complete the
|
||||
* attach operation. A more specific error message will be
|
||||
* given by {@link AttachOperationFailedException#getMessage()}.
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
* If an I/O error occurs, a communication error for example,
|
||||
* that cannot be identified as an error to indicate that the
|
||||
* operation failed in the target VM.
|
||||
*
|
||||
* @see java.lang.System#getProperties
|
||||
* @see #loadAgentLibrary
|
||||
@ -591,8 +598,15 @@ public abstract class VirtualMachine {
|
||||
*
|
||||
* @return The agent properties
|
||||
*
|
||||
* @throws AttachOperationFailedException
|
||||
* If the target virtual machine is unable to complete the
|
||||
* attach operation. A more specific error message will be
|
||||
* given by {@link AttachOperationFailedException#getMessage()}.
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
* If an I/O error occurs, a communication error for example,
|
||||
* that cannot be identified as an error to indicate that the
|
||||
* operation failed in the target VM.
|
||||
*/
|
||||
public abstract Properties getAgentProperties() throws IOException;
|
||||
|
||||
|
||||
@ -4498,7 +4498,6 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
||||
* Character case is ignored for all of the valid script names.
|
||||
* The en_US locale's case mapping rules are used to provide
|
||||
* case-insensitive string comparisons for script name validation.
|
||||
* <p>
|
||||
*
|
||||
* @param scriptName A {@code UnicodeScript} name.
|
||||
* @return The {@code UnicodeScript} constant identified
|
||||
@ -5503,7 +5502,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
||||
* '\u00D0' '\u00D1' '\u00D2' '\u00D3' '\u00D4' '\u00D5' '\u00D6' '\u00D8'
|
||||
* '\u00D9' '\u00DA' '\u00DB' '\u00DC' '\u00DD' '\u00DE'
|
||||
* </pre></blockquote>
|
||||
* <p> Many other Unicode characters are uppercase too.<p>
|
||||
* <p> Many other Unicode characters are uppercase too.
|
||||
*
|
||||
* @param codePoint the character (Unicode code point) to be tested.
|
||||
* @return {@code true} if the character is uppercase;
|
||||
@ -5581,7 +5580,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
||||
* <li>{@code LATIN CAPITAL LETTER N WITH SMALL LETTER J}
|
||||
* <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z}
|
||||
* </ul>
|
||||
* <p> Many other Unicode characters are titlecase too.<p>
|
||||
* <p> Many other Unicode characters are titlecase too.
|
||||
*
|
||||
* @param codePoint the character (Unicode code point) to be tested.
|
||||
* @return {@code true} if the character is titlecase;
|
||||
@ -6777,7 +6776,6 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
||||
* <li> It is {@code '\u005Cu001E'}, U+001E RECORD SEPARATOR.
|
||||
* <li> It is {@code '\u005Cu001F'}, U+001F UNIT SEPARATOR.
|
||||
* </ul>
|
||||
* <p>
|
||||
*
|
||||
* @param codePoint the character (Unicode code point) to be tested.
|
||||
* @return {@code true} if the character is a Java whitespace
|
||||
@ -7121,7 +7119,6 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
||||
/**
|
||||
* Converts the character (Unicode code point) argument to uppercase using
|
||||
* information from the UnicodeData file.
|
||||
* <p>
|
||||
*
|
||||
* @param codePoint the character (Unicode code point) to be converted.
|
||||
* @return either the uppercase equivalent of the character, if
|
||||
|
||||
@ -62,6 +62,7 @@ final class ConditionalSpecialCasing {
|
||||
//# Conditional mappings
|
||||
//# ================================================================================
|
||||
new Entry(0x03A3, new char[]{0x03C2}, new char[]{0x03A3}, null, FINAL_CASED), // # GREEK CAPITAL LETTER SIGMA
|
||||
new Entry(0x0130, new char[]{0x0069, 0x0307}, new char[]{0x0130}, null, 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
|
||||
//# ================================================================================
|
||||
//# Locale-sensitive mappings
|
||||
@ -77,8 +78,8 @@ final class ConditionalSpecialCasing {
|
||||
|
||||
//# ================================================================================
|
||||
//# Turkish and Azeri
|
||||
// new Entry(0x0130, new char[]{0x0069}, new char[]{0x0130}, "tr", 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
// new Entry(0x0130, new char[]{0x0069}, new char[]{0x0130}, "az", 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
new Entry(0x0130, new char[]{0x0069}, new char[]{0x0130}, "tr", 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
new Entry(0x0130, new char[]{0x0069}, new char[]{0x0130}, "az", 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
new Entry(0x0307, new char[]{}, new char[]{0x0307}, "tr", AFTER_I), // # COMBINING DOT ABOVE
|
||||
new Entry(0x0307, new char[]{}, new char[]{0x0307}, "az", AFTER_I), // # COMBINING DOT ABOVE
|
||||
new Entry(0x0049, new char[]{0x0131}, new char[]{0x0049}, "tr", NOT_BEFORE_DOT), // # LATIN CAPITAL LETTER I
|
||||
@ -147,21 +148,25 @@ final class ConditionalSpecialCasing {
|
||||
|
||||
private static char[] lookUpTable(String src, int index, Locale locale, boolean bLowerCasing) {
|
||||
HashSet<Entry> set = entryTable.get(new Integer(src.codePointAt(index)));
|
||||
char[] ret = null;
|
||||
|
||||
if (set != null) {
|
||||
Iterator<Entry> iter = set.iterator();
|
||||
String currentLang = locale.getLanguage();
|
||||
while (iter.hasNext()) {
|
||||
Entry entry = iter.next();
|
||||
String conditionLang= entry.getLanguage();
|
||||
String conditionLang = entry.getLanguage();
|
||||
if (((conditionLang == null) || (conditionLang.equals(currentLang))) &&
|
||||
isConditionMet(src, index, locale, entry.getCondition())) {
|
||||
return (bLowerCasing ? entry.getLowerCase() : entry.getUpperCase());
|
||||
ret = bLowerCasing ? entry.getLowerCase() : entry.getUpperCase();
|
||||
if (conditionLang != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static boolean isConditionMet(String src, int index, Locale locale, int condition) {
|
||||
|
||||
@ -1048,7 +1048,6 @@ public final class Math {
|
||||
* whereas {@code (-4 / 3) == -1}.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
*
|
||||
* @param x the dividend
|
||||
* @param y the divisor
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -83,7 +83,7 @@ public class Runtime {
|
||||
* blocks indefinitely.
|
||||
*
|
||||
* <p> The <tt>{@link System#exit(int) System.exit}</tt> method is the
|
||||
* conventional and convenient means of invoking this method. <p>
|
||||
* conventional and convenient means of invoking this method.
|
||||
*
|
||||
* @param status
|
||||
* Termination status. By convention, a nonzero status code
|
||||
@ -180,7 +180,7 @@ public class Runtime {
|
||||
* method goes awry by, for example, corrupting internal data structures or
|
||||
* attempting to access nonexistent memory. If the virtual machine aborts
|
||||
* then no guarantee can be made about whether or not any shutdown hooks
|
||||
* will be run. <p>
|
||||
* will be run.
|
||||
*
|
||||
* @param hook
|
||||
* An initialized but unstarted <tt>{@link Thread}</tt> object
|
||||
@ -248,7 +248,7 @@ public class Runtime {
|
||||
* hooks to be started and does not run uninvoked finalizers if
|
||||
* finalization-on-exit has been enabled. If the shutdown sequence has
|
||||
* already been initiated then this method does not wait for any running
|
||||
* shutdown hooks or finalizers to finish their work. <p>
|
||||
* shutdown hooks or finalizers to finish their work.
|
||||
*
|
||||
* @param status
|
||||
* Termination status. By convention, a nonzero status code
|
||||
|
||||
@ -1242,7 +1242,6 @@ class SecurityManager {
|
||||
* <code>super.checkPropertiesAccess</code>
|
||||
* at the point the overridden method would normally throw an
|
||||
* exception.
|
||||
* <p>
|
||||
*
|
||||
* @exception SecurityException if the calling thread does not have
|
||||
* permission to access or modify the system properties.
|
||||
@ -1320,7 +1319,6 @@ class SecurityManager {
|
||||
* <code>super.checkPrintJobAccess</code>
|
||||
* at the point the overridden method would normally throw an
|
||||
* exception.
|
||||
* <p>
|
||||
*
|
||||
* @exception SecurityException if the calling thread does not have
|
||||
* permission to initiate a print job request.
|
||||
@ -1566,7 +1564,6 @@ class SecurityManager {
|
||||
* <code>super.checkSetFactory</code>
|
||||
* at the point the overridden method would normally throw an
|
||||
* exception.
|
||||
* <p>
|
||||
*
|
||||
* @exception SecurityException if the calling thread does not have
|
||||
* permission to specify a socket factory or a stream
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2583,6 +2583,9 @@ public final class String
|
||||
if (cp == '\u03A3') { // GREEK CAPITAL LETTER SIGMA
|
||||
return toLowerCaseEx(result, i, locale, false);
|
||||
}
|
||||
if (cp == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
return toLowerCaseEx(result, i, locale, true);
|
||||
}
|
||||
cp = Character.toLowerCase(cp);
|
||||
if (!Character.isBmpCodePoint(cp)) {
|
||||
return toLowerCaseEx(result, i, locale, false);
|
||||
@ -2650,7 +2653,7 @@ public final class String
|
||||
* LATIN SMALL LETTER DOTLESS I character.
|
||||
* To obtain correct results for locale insensitive strings, use
|
||||
* {@code toLowerCase(Locale.ROOT)}.
|
||||
* <p>
|
||||
*
|
||||
* @return the {@code String}, converted to lowercase.
|
||||
* @see java.lang.String#toLowerCase(Locale)
|
||||
*/
|
||||
@ -2812,7 +2815,7 @@ public final class String
|
||||
* LATIN CAPITAL LETTER I WITH DOT ABOVE character.
|
||||
* To obtain correct results for locale insensitive strings, use
|
||||
* {@code toUpperCase(Locale.ROOT)}.
|
||||
* <p>
|
||||
*
|
||||
* @return the {@code String}, converted to uppercase.
|
||||
* @see java.lang.String#toUpperCase(Locale)
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -133,7 +133,6 @@ public final class System {
|
||||
* <p>First, if there is a security manager, its <code>checkPermission</code>
|
||||
* method is called with a <code>RuntimePermission("setIO")</code> permission
|
||||
* to see if it's ok to reassign the "standard" input stream.
|
||||
* <p>
|
||||
*
|
||||
* @param in the new standard input stream.
|
||||
*
|
||||
@ -762,7 +761,6 @@ public final class System {
|
||||
* permission. This may result in a SecurityException being thrown.
|
||||
* If no exception is thrown, the specified property is set to the given
|
||||
* value.
|
||||
* <p>
|
||||
*
|
||||
* @param key the name of the system property.
|
||||
* @param value the value of the system property.
|
||||
@ -801,7 +799,6 @@ public final class System {
|
||||
* is called with a <code>PropertyPermission(key, "write")</code>
|
||||
* permission. This may result in a SecurityException being thrown.
|
||||
* If no exception is thrown, the specified property is removed.
|
||||
* <p>
|
||||
*
|
||||
* @param key the name of the system property to be removed.
|
||||
* @return the previous string value of the system property,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
This code is free software; you can redistribute it and/or modify it
|
||||
@ -140,7 +140,7 @@ supports the starting of agents after the VM has started the following applies:
|
||||
|
||||
<li><p>The system class loader (
|
||||
{@link java.lang.ClassLoader#getSystemClassLoader ClassLoader.getSystemClassLoader}) must
|
||||
support a mechanism to add an agent JAR file to the system class path. <p></li>
|
||||
support a mechanism to add an agent JAR file to the system class path.</li>
|
||||
</ol>
|
||||
|
||||
<P>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -50,7 +50,7 @@ import sun.security.util.SecurityConstants;
|
||||
* <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
|
||||
* <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
|
||||
* </ul>
|
||||
* <p>
|
||||
*
|
||||
* @author John Rose, JSR 292 EG
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -89,7 +89,7 @@ import sun.management.MemoryNotifInfoCompositeData;
|
||||
* Subsequent crossing of the usage threshold value does not cause
|
||||
* further notification until the memory usage has returned
|
||||
* to become less than the usage threshold value.
|
||||
* <p></li>
|
||||
* </li>
|
||||
* <li>A {@link #MEMORY_COLLECTION_THRESHOLD_EXCEEDED
|
||||
* collection usage threshold exceeded notification}.
|
||||
* <br>This notification will be emitted when
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -429,12 +429,12 @@ public class ThreadInfo {
|
||||
* <br>The thread is in the {@link java.lang.Thread.State#BLOCKED BLOCKED}
|
||||
* state waiting to enter the <tt>synchronized</tt> statement
|
||||
* or method.
|
||||
* <p></li>
|
||||
* </li>
|
||||
* <li>an object monitor to be notified by another thread.
|
||||
* <br>The thread is in the {@link java.lang.Thread.State#WAITING WAITING}
|
||||
* or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
|
||||
* due to a call to the {@link Object#wait Object.wait} method.
|
||||
* <p></li>
|
||||
* </li>
|
||||
* <li>a synchronization object responsible for the thread parking.
|
||||
* <br>The thread is in the {@link java.lang.Thread.State#WAITING WAITING}
|
||||
* or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,7 +31,6 @@ Provides the management interfaces for monitoring and management of the
|
||||
Java virtual machine and other components in the Java runtime.
|
||||
It allows both local and remote
|
||||
monitoring and management of the running Java virtual machine.
|
||||
<p>
|
||||
|
||||
<h4><a name="MXBean">Platform MXBean</a></h4>
|
||||
<p>
|
||||
@ -41,7 +40,6 @@ Instrumentation Specification and only uses a set of basic data types.
|
||||
Each platform MXBean is a {@link java.lang.management.PlatformManagedObject}
|
||||
with a unique
|
||||
{@linkplain java.lang.management.PlatformManagedObject#getObjectName name}.
|
||||
<p>
|
||||
<h4>ManagementFactory</h4>
|
||||
|
||||
<p>The {@link java.lang.management.ManagementFactory} class is the management
|
||||
@ -80,7 +78,6 @@ MXBean</a> specification for details.
|
||||
Java virtual machine and the runtime in the following ways:
|
||||
<p>
|
||||
<b>1. Direct access to an MXBean interface</b>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Get an MXBean instance locally in the running Java virtual machine:
|
||||
<pre>
|
||||
@ -100,7 +97,6 @@ Java virtual machine and the runtime in the following ways:
|
||||
// Get the standard attribute "VmVendor"
|
||||
String vendor = mxbean.getVmVendor();
|
||||
</pre>
|
||||
<p>
|
||||
</li>
|
||||
<li>Construct an MXBean proxy instance that forwards the
|
||||
method calls to a given MBeanServer:
|
||||
@ -132,7 +128,7 @@ Java virtual machine and the runtime in the following ways:
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>2. Indirect access to an MXBean interface via MBeanServer</b><p>
|
||||
<b>2. Indirect access to an MXBean interface via MBeanServer</b>
|
||||
<ul>
|
||||
<li>Go through the
|
||||
{@link java.lang.management.ManagementFactory#getPlatformMBeanServer
|
||||
@ -143,7 +139,7 @@ Java virtual machine and the runtime in the following ways:
|
||||
<em>JMX open types</em> which include basic data types,
|
||||
{@link javax.management.openmbean.CompositeData CompositeData},
|
||||
and {@link javax.management.openmbean.TabularData TabularData}
|
||||
defined in {@link javax.management.openmbean.OpenType OpenType}.<p>
|
||||
defined in {@link javax.management.openmbean.OpenType OpenType}.
|
||||
<pre>
|
||||
MBeanServerConnection mbs;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -3597,7 +3597,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
* Converts the specified BigInteger to a string and appends to
|
||||
* {@code sb}. This implements the recursive Schoenhage algorithm
|
||||
* for base conversions.
|
||||
* <p/>
|
||||
* <p>
|
||||
* See Knuth, Donald, _The Art of Computer Programming_, Vol. 2,
|
||||
* Answers to Exercises (4.4) Question 14.
|
||||
*
|
||||
@ -3646,7 +3646,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
/**
|
||||
* Returns the value radix^(2^exponent) from the cache.
|
||||
* If this value doesn't already exist in the cache, it is added.
|
||||
* <p/>
|
||||
* <p>
|
||||
* This could be changed to a more complicated caching method using
|
||||
* {@code Future}.
|
||||
*/
|
||||
|
||||
@ -37,7 +37,7 @@ import java.io.BufferedWriter;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import sun.util.spi.XmlPropertiesProvider;
|
||||
import jdk.internal.util.xml.PropertiesDefaultHandler;
|
||||
|
||||
/**
|
||||
* The {@code Properties} class represents a persistent set of
|
||||
@ -877,7 +877,9 @@ class Properties extends Hashtable<Object,Object> {
|
||||
public synchronized void loadFromXML(InputStream in)
|
||||
throws IOException, InvalidPropertiesFormatException
|
||||
{
|
||||
XmlSupport.load(this, Objects.requireNonNull(in));
|
||||
Objects.requireNonNull(in);
|
||||
PropertiesDefaultHandler handler = new PropertiesDefaultHandler();
|
||||
handler.load(this, in);
|
||||
in.close();
|
||||
}
|
||||
|
||||
@ -949,8 +951,10 @@ class Properties extends Hashtable<Object,Object> {
|
||||
public void storeToXML(OutputStream os, String comment, String encoding)
|
||||
throws IOException
|
||||
{
|
||||
XmlSupport.save(this, Objects.requireNonNull(os), comment,
|
||||
Objects.requireNonNull(encoding));
|
||||
Objects.requireNonNull(os);
|
||||
Objects.requireNonNull(encoding);
|
||||
PropertiesDefaultHandler handler = new PropertiesDefaultHandler();
|
||||
handler.store(this, os, comment, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1128,83 +1132,4 @@ class Properties extends Hashtable<Object,Object> {
|
||||
private static final char[] hexDigit = {
|
||||
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
||||
};
|
||||
|
||||
/**
|
||||
* Supporting class for loading/storing properties in XML format.
|
||||
*
|
||||
* <p> The {@code load} and {@code store} methods defined here delegate to a
|
||||
* system-wide {@code XmlPropertiesProvider}. On first invocation of either
|
||||
* method then the system-wide provider is located as follows: </p>
|
||||
*
|
||||
* <ol>
|
||||
* <li> If the system property {@code sun.util.spi.XmlPropertiesProvider}
|
||||
* is defined then it is taken to be the full-qualified name of a concrete
|
||||
* provider class. The class is loaded with the system class loader as the
|
||||
* initiating loader. If it cannot be loaded or instantiated using a zero
|
||||
* argument constructor then an unspecified error is thrown. </li>
|
||||
*
|
||||
* <li> If the system property is not defined then the service-provider
|
||||
* loading facility defined by the {@link ServiceLoader} class is used to
|
||||
* locate a provider with the system class loader as the initiating
|
||||
* loader and {@code sun.util.spi.XmlPropertiesProvider} as the service
|
||||
* type. If this process fails then an unspecified error is thrown. If
|
||||
* there is more than one service provider installed then it is
|
||||
* not specified as to which provider will be used. </li>
|
||||
*
|
||||
* <li> If the provider is not found by the above means then a system
|
||||
* default provider will be instantiated and used. </li>
|
||||
* </ol>
|
||||
*/
|
||||
private static class XmlSupport {
|
||||
|
||||
private static XmlPropertiesProvider loadProviderFromProperty(ClassLoader cl) {
|
||||
String cn = System.getProperty("sun.util.spi.XmlPropertiesProvider");
|
||||
if (cn == null)
|
||||
return null;
|
||||
try {
|
||||
Class<?> c = Class.forName(cn, true, cl);
|
||||
return (XmlPropertiesProvider)c.newInstance();
|
||||
} catch (ClassNotFoundException |
|
||||
IllegalAccessException |
|
||||
InstantiationException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
}
|
||||
}
|
||||
|
||||
private static XmlPropertiesProvider loadProviderAsService(ClassLoader cl) {
|
||||
Iterator<XmlPropertiesProvider> iterator =
|
||||
ServiceLoader.load(XmlPropertiesProvider.class, cl).iterator();
|
||||
return iterator.hasNext() ? iterator.next() : null;
|
||||
}
|
||||
|
||||
private static XmlPropertiesProvider loadProvider() {
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<XmlPropertiesProvider>() {
|
||||
public XmlPropertiesProvider run() {
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
XmlPropertiesProvider provider = loadProviderFromProperty(cl);
|
||||
if (provider != null)
|
||||
return provider;
|
||||
provider = loadProviderAsService(cl);
|
||||
if (provider != null)
|
||||
return provider;
|
||||
return new jdk.internal.util.xml.BasicXmlPropertiesProvider();
|
||||
}});
|
||||
}
|
||||
|
||||
private static final XmlPropertiesProvider PROVIDER = loadProvider();
|
||||
|
||||
static void load(Properties props, InputStream in)
|
||||
throws IOException, InvalidPropertiesFormatException
|
||||
{
|
||||
PROVIDER.load(props, in);
|
||||
}
|
||||
|
||||
static void save(Properties props, OutputStream os, String comment,
|
||||
String encoding)
|
||||
throws IOException
|
||||
{
|
||||
PROVIDER.store(props, os, comment, encoding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1532,10 +1532,12 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||
*
|
||||
* @param corePoolSize the new core size
|
||||
* @throws IllegalArgumentException if {@code corePoolSize < 0}
|
||||
* or {@code corePoolSize} is greater than the {@linkplain
|
||||
* #getMaximumPoolSize() maximum pool size}
|
||||
* @see #getCorePoolSize
|
||||
*/
|
||||
public void setCorePoolSize(int corePoolSize) {
|
||||
if (corePoolSize < 0)
|
||||
if (corePoolSize < 0 || maximumPoolSize < corePoolSize)
|
||||
throw new IllegalArgumentException();
|
||||
int delta = corePoolSize - this.corePoolSize;
|
||||
this.corePoolSize = corePoolSize;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -156,7 +156,7 @@ import java.security.Permission;
|
||||
* </ul>
|
||||
*
|
||||
* <p>In a comma-separated list of actions, spaces are allowed before
|
||||
* and after each action.</p>
|
||||
* and after each action.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@ -1129,7 +1129,7 @@ public class MBeanPermission extends Permission {
|
||||
* Checks two MBeanPermission objects for equality. Checks
|
||||
* that <i>obj</i> is an MBeanPermission, and has the same
|
||||
* name and actions as this object.
|
||||
* <P>
|
||||
*
|
||||
* @param obj the object we are testing for equality with this object.
|
||||
* @return true if obj is an MBeanPermission, and has the
|
||||
* same name and actions as this MBeanPermission object.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -285,7 +285,7 @@ public class MBeanServerPermission extends BasicPermission {
|
||||
* Checks two MBeanServerPermission objects for equality. Checks that
|
||||
* <i>obj</i> is an MBeanServerPermission, and represents the same
|
||||
* list of allowable actions as this object.
|
||||
* <P>
|
||||
*
|
||||
* @param obj the object we are testing for equality with this object.
|
||||
* @return true if the objects are equal.
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -124,7 +124,7 @@ public interface ModelMBeanNotificationBroadcaster extends NotificationBroadcast
|
||||
/**
|
||||
* Sends an attributeChangeNotification which contains the old value and new value for the
|
||||
* attribute to the registered AttributeChangeNotification listeners on the ModelMBean.
|
||||
* <P>
|
||||
*
|
||||
* @param oldValue The original value for the Attribute
|
||||
* @param newValue The current value for the Attribute
|
||||
* <PRE>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -81,29 +81,29 @@ public class CompositeType extends OpenType<CompositeData> {
|
||||
* The Java class name of composite data values this composite type represents
|
||||
* (ie the class name returned by the {@link OpenType#getClassName() getClassName} method)
|
||||
* is set to the string value returned by <code>CompositeData.class.getName()</code>.
|
||||
* <p>
|
||||
*
|
||||
* @param typeName The name given to the composite type this instance represents; cannot be a null or empty string.
|
||||
* <br>
|
||||
*
|
||||
* @param description The human readable description of the composite type this instance represents;
|
||||
* cannot be a null or empty string.
|
||||
* <br>
|
||||
*
|
||||
* @param itemNames The names of the items contained in the
|
||||
* composite data values described by this <code>CompositeType</code> instance;
|
||||
* cannot be null and should contain at least one element; no element can be a null or empty string.
|
||||
* Note that the order in which the item names are given is not important to differentiate a
|
||||
* <code>CompositeType</code> instance from another;
|
||||
* the item names are internally stored sorted in ascending alphanumeric order.
|
||||
* <br>
|
||||
*
|
||||
* @param itemDescriptions The descriptions, in the same order as <var>itemNames</var>, of the items contained in the
|
||||
* composite data values described by this <code>CompositeType</code> instance;
|
||||
* should be of the same size as <var>itemNames</var>;
|
||||
* no element can be null or an empty string.
|
||||
* <br>
|
||||
*
|
||||
* @param itemTypes The open type instances, in the same order as <var>itemNames</var>, describing the items contained
|
||||
* in the composite data values described by this <code>CompositeType</code> instance;
|
||||
* should be of the same size as <var>itemNames</var>;
|
||||
* no element can be null.
|
||||
* <br>
|
||||
*
|
||||
* @throws IllegalArgumentException If <var>typeName</var> or <var>description</var> is a null or empty string,
|
||||
* or <var>itemNames</var> or <var>itemDescriptions</var> or <var>itemTypes</var> is null,
|
||||
* or any element of <var>itemNames</var> or <var>itemDescriptions</var>
|
||||
@ -111,7 +111,7 @@ public class CompositeType extends OpenType<CompositeData> {
|
||||
* or any element of <var>itemTypes</var> is null,
|
||||
* or <var>itemNames</var> or <var>itemDescriptions</var> or <var>itemTypes</var>
|
||||
* are not of the same size.
|
||||
* <br>
|
||||
*
|
||||
* @throws OpenDataException If <var>itemNames</var> contains duplicate item names
|
||||
* (case sensitive, but leading and trailing whitespaces removed).
|
||||
*/
|
||||
@ -356,7 +356,7 @@ public class CompositeType extends OpenType<CompositeData> {
|
||||
* <li>their type names are equal</li>
|
||||
* <li>their items' names and types are equal</li>
|
||||
* </ul>
|
||||
* <br>
|
||||
*
|
||||
* @param obj the object to be compared for equality with this <code>CompositeType</code> instance;
|
||||
* if <var>obj</var> is <code>null</code>, <code>equals</code> returns <code>false</code>.
|
||||
*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -113,7 +113,6 @@ public interface OpenMBeanAttributeInfo extends OpenMBeanParameterInfo {
|
||||
* for any two <code>OpenMBeanAttributeInfo</code> instances <code>t1</code> and <code>t2</code>,
|
||||
* as required by the general contract of the method
|
||||
* {@link Object#hashCode() Object.hashCode()}.
|
||||
* <p>
|
||||
*
|
||||
* @return the hash code value for this <code>OpenMBeanAttributeInfo</code> instance
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -118,7 +118,6 @@ public interface OpenMBeanConstructorInfo {
|
||||
* for any two <code>OpenMBeanConstructorInfo</code> instances <code>t1</code> and <code>t2</code>,
|
||||
* as required by the general contract of the method
|
||||
* {@link Object#hashCode() Object.hashCode()}.
|
||||
* <p>
|
||||
*
|
||||
* @return the hash code value for this <code>OpenMBeanConstructorInfo</code> instance
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -168,7 +168,6 @@ public interface OpenMBeanInfo {
|
||||
* for any two <code>OpenMBeanInfo</code> instances <code>t1</code> and <code>t2</code>,
|
||||
* as required by the general contract of the method
|
||||
* {@link Object#hashCode() Object.hashCode()}.
|
||||
* <p>
|
||||
*
|
||||
* @return the hash code value for this <code>OpenMBeanInfo</code> instance
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -161,7 +161,7 @@ public interface OpenMBeanOperationInfo {
|
||||
* for any two <code>OpenMBeanOperationInfo</code> instances <code>t1</code> and <code>t2</code>,
|
||||
* as required by the general contract of the method
|
||||
* {@link Object#hashCode() Object.hashCode()}.
|
||||
* <p>
|
||||
*
|
||||
*
|
||||
* @return the hash code value for this <code>OpenMBeanOperationInfo</code> instance
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -192,7 +192,6 @@ public interface OpenMBeanParameterInfo {
|
||||
* for any two <code>OpenMBeanParameterInfo</code> instances <code>t1</code> and <code>t2</code>,
|
||||
* as required by the general contract of the method
|
||||
* {@link Object#hashCode() Object.hashCode()}.
|
||||
* <p>
|
||||
*
|
||||
* @return the hash code value for this <code>OpenMBeanParameterInfo</code> instance
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -75,7 +75,7 @@ public class TabularType extends OpenType<TabularData> {
|
||||
* The Java class name of tabular data values this tabular type represents
|
||||
* (ie the class name returned by the {@link OpenType#getClassName() getClassName} method)
|
||||
* is set to the string value returned by <code>TabularData.class.getName()</code>.
|
||||
* <p>
|
||||
*
|
||||
* @param typeName The name given to the tabular type this instance represents; cannot be a null or empty string.
|
||||
* <br>
|
||||
* @param description The human readable description of the tabular type this instance represents;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -134,7 +134,7 @@ import sun.reflect.misc.ReflectUtil;
|
||||
* <code>MalformedURLException</code> if there is none. An
|
||||
* implementation may choose to find providers by other means. For
|
||||
* example, it may support the <a
|
||||
* href="{@docRoot}/../technotes/guides/jar/jar.html#Service Provider">
|
||||
* href="{@docRoot}/../technotes/guides/jar/jar.html#Service%20Provider">
|
||||
* JAR conventions for service providers</a>, where the service
|
||||
* interface is <code>JMXConnectorProvider</code>.</p>
|
||||
*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -125,7 +125,7 @@ import javax.management.MBeanServer;
|
||||
* <code>MalformedURLException</code> if there is none. An
|
||||
* implementation may choose to find providers by other means. For
|
||||
* example, it may support the <a
|
||||
* href="{@docRoot}/../technotes/guides/jar/jar.html#Service Provider">
|
||||
* href="{@docRoot}/../technotes/guides/jar/jar.html#Service%20Provider">
|
||||
* JAR conventions for service providers</a>, where the service
|
||||
* interface is <code>JMXConnectorServerProvider</code>.</p>
|
||||
*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -59,7 +59,7 @@ public class JMXPrincipal implements Principal, Serializable {
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* <p>Creates a JMXPrincipal for a given identity.</p>
|
||||
* Creates a JMXPrincipal for a given identity.
|
||||
*
|
||||
* @param name the JMX Remote API name for this identity.
|
||||
*
|
||||
@ -74,8 +74,6 @@ public class JMXPrincipal implements Principal, Serializable {
|
||||
/**
|
||||
* Returns the name of this principal.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the name of this <code>JMXPrincipal</code>.
|
||||
*/
|
||||
public String getName() {
|
||||
@ -85,8 +83,6 @@ public class JMXPrincipal implements Principal, Serializable {
|
||||
/**
|
||||
* Returns a string representation of this <code>JMXPrincipal</code>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return a string representation of this <code>JMXPrincipal</code>.
|
||||
*/
|
||||
public String toString() {
|
||||
@ -99,8 +95,6 @@ public class JMXPrincipal implements Principal, Serializable {
|
||||
* <code>JMXPrincipal</code> and the two JMXPrincipals
|
||||
* have the same name.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param o Object to be compared for equality with this
|
||||
* <code>JMXPrincipal</code>.
|
||||
*
|
||||
@ -124,8 +118,6 @@ public class JMXPrincipal implements Principal, Serializable {
|
||||
/**
|
||||
* Returns a hash code for this <code>JMXPrincipal</code>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return a hash code for this <code>JMXPrincipal</code>.
|
||||
*/
|
||||
public int hashCode() {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<head>
|
||||
<title>JMX<sup><font size="-2">TM</font></sup> Remote API.</title>
|
||||
<!--
|
||||
Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
This code is free software; you can redistribute it and/or modify it
|
||||
@ -60,7 +60,7 @@ questions.
|
||||
<li>User-defined connector protocols are also possible using the
|
||||
{@link javax.management.remote.JMXConnectorFactory
|
||||
JMXConnectorFactory} and, optionally, the Generic Connector
|
||||
(not part of this bundle, see note below).</p>
|
||||
(not part of this bundle, see note below).
|
||||
</ul>
|
||||
|
||||
<p><u>Note</u>: the optional packages implementing
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<head>
|
||||
<title>RMI connector</title>
|
||||
<!--
|
||||
Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
This code is free software; you can redistribute it and/or modify it
|
||||
@ -240,12 +240,12 @@ questions.
|
||||
that the RMI registry only allows registration from the local
|
||||
host. So, in this case, <code>myhost</code> must be the name
|
||||
(or a name) of the host that the connector server is running
|
||||
on.</p>
|
||||
on.
|
||||
|
||||
<p>In this <code>JMXServiceURL</code>, the first <code>rmi:</code>
|
||||
specifies the RMI
|
||||
connector, while the second <code>rmi:</code> specifies the RMI
|
||||
registry.</p>
|
||||
registry.
|
||||
|
||||
<p>As another example, if the <code>JMXServiceURL</code> is:
|
||||
|
||||
@ -262,7 +262,7 @@ questions.
|
||||
</pre>
|
||||
|
||||
which means entry <code>cn=this,ou=that</code> in the LDAP
|
||||
directory running on port 9999 of host <code>dirhost</code>.</p>
|
||||
directory running on port 9999 of host <code>dirhost</code>.
|
||||
|
||||
<p>If the <code>JMXServiceURL</code> is:
|
||||
|
||||
@ -280,7 +280,7 @@ questions.
|
||||
|
||||
For this case to work, the JNDI API must have been configured
|
||||
appropriately to supply the information about what directory to
|
||||
use.</p>
|
||||
use.
|
||||
|
||||
<p>In these examples, the host name <code>ignoredhost</code> is
|
||||
not used by the connector server or its clients. It can be
|
||||
|
||||
@ -160,7 +160,6 @@ public interface ScriptEngineFactory {
|
||||
* return ret;
|
||||
* }
|
||||
* } </pre>
|
||||
* <p>
|
||||
*
|
||||
* @param obj The name representing the object whose method is to be invoked. The
|
||||
* name is the one used to create bindings using the <code>put</code> method of
|
||||
|
||||
@ -123,7 +123,7 @@ public class PropertiesDefaultHandler extends DefaultHandler {
|
||||
|
||||
writer.writeEndElement();
|
||||
writer.writeEndDocument();
|
||||
writer.close();
|
||||
writer.flush();
|
||||
} catch (XMLStreamException e) {
|
||||
if (e.getCause() instanceof UnsupportedEncodingException) {
|
||||
throw (UnsupportedEncodingException) e.getCause();
|
||||
|
||||
@ -41,6 +41,8 @@ import java.nio.file.attribute.*;
|
||||
import java.nio.file.spi.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
@ -110,7 +112,9 @@ class ZipFileSystem extends FileSystem {
|
||||
}
|
||||
// sm and existence check
|
||||
zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ);
|
||||
if (!Files.isWritable(zfpath))
|
||||
boolean writeable = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Boolean>) () -> Files.isWritable(zfpath));
|
||||
if (!writeable)
|
||||
this.readOnly = true;
|
||||
this.zc = ZipCoder.get(nameEncoding);
|
||||
this.defaultdir = new ZipPath(this, getBytes(defaultDir));
|
||||
@ -262,9 +266,13 @@ class ZipFileSystem extends FileSystem {
|
||||
}
|
||||
beginWrite(); // lock and sync
|
||||
try {
|
||||
sync();
|
||||
ch.close(); // close the ch just in case no update
|
||||
} finally { // and sync dose not close the ch
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
||||
sync(); return null;
|
||||
});
|
||||
ch.close(); // close the ch just in case no update
|
||||
} catch (PrivilegedActionException e) { // and sync dose not close the ch
|
||||
throw (IOException)e.getException();
|
||||
} finally {
|
||||
endWrite();
|
||||
}
|
||||
|
||||
@ -281,8 +289,10 @@ class ZipFileSystem extends FileSystem {
|
||||
synchronized (tmppaths) {
|
||||
for (Path p: tmppaths) {
|
||||
try {
|
||||
Files.deleteIfExists(p);
|
||||
} catch (IOException x) {
|
||||
AccessController.doPrivileged(
|
||||
(PrivilegedExceptionAction<Boolean>)() -> Files.deleteIfExists(p));
|
||||
} catch (PrivilegedActionException e) {
|
||||
IOException x = (IOException)e.getException();
|
||||
if (ioe == null)
|
||||
ioe = x;
|
||||
else
|
||||
|
||||
@ -34,8 +34,11 @@ import java.util.StringTokenizer;
|
||||
import java.util.Random;
|
||||
|
||||
import sun.net.www.HeaderParser;
|
||||
import sun.net.NetProperties;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.AccessController;
|
||||
import static sun.net.www.protocol.http.HttpURLConnection.HTTP_CONNECT;
|
||||
|
||||
/**
|
||||
@ -51,6 +54,23 @@ class DigestAuthentication extends AuthenticationInfo {
|
||||
|
||||
private String authMethod;
|
||||
|
||||
private final static String compatPropName = "http.auth.digest." +
|
||||
"quoteParameters";
|
||||
|
||||
// true if http.auth.digest.quoteParameters Net property is true
|
||||
private static final boolean delimCompatFlag;
|
||||
|
||||
static {
|
||||
Boolean b = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Boolean>() {
|
||||
public Boolean run() {
|
||||
return NetProperties.getBoolean(compatPropName);
|
||||
}
|
||||
}
|
||||
);
|
||||
delimCompatFlag = (b == null) ? false : b.booleanValue();
|
||||
}
|
||||
|
||||
// Authentication parameters defined in RFC2617.
|
||||
// One instance of these may be shared among several DigestAuthentication
|
||||
// instances as a result of a single authorization (for multiple domains)
|
||||
@ -206,7 +226,7 @@ class DigestAuthentication extends AuthenticationInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaculates the request-digest and returns it.
|
||||
* Recalculates the request-digest and returns it.
|
||||
*
|
||||
* <P> Used in the common case where the requestURI is simply the
|
||||
* abs_path.
|
||||
@ -225,7 +245,7 @@ class DigestAuthentication extends AuthenticationInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaculates the request-digest and returns it.
|
||||
* Recalculates the request-digest and returns it.
|
||||
*
|
||||
* <P> Used when the requestURI is not the abs_path. The exact
|
||||
* requestURI can be passed as a String.
|
||||
@ -357,24 +377,34 @@ class DigestAuthentication extends AuthenticationInfo {
|
||||
ncfield = "\", nc=" + ncstring;
|
||||
}
|
||||
|
||||
String algoS, qopS;
|
||||
|
||||
if (delimCompatFlag) {
|
||||
// Put quotes around these String value parameters
|
||||
algoS = ", algorithm=\"" + algorithm + "\"";
|
||||
qopS = ", qop=\"auth\"";
|
||||
} else {
|
||||
// Don't put quotes around them, per the RFC
|
||||
algoS = ", algorithm=" + algorithm;
|
||||
qopS = ", qop=auth";
|
||||
}
|
||||
|
||||
String value = authMethod
|
||||
+ " username=\"" + pw.getUserName()
|
||||
+ "\", realm=\"" + realm
|
||||
+ "\", nonce=\"" + nonce
|
||||
+ ncfield
|
||||
+ ", uri=\"" + uri
|
||||
+ "\", response=\"" + response
|
||||
+ "\", algorithm=" + algorithm;
|
||||
+ "\", response=\"" + response + "\""
|
||||
+ algoS;
|
||||
if (opaque != null) {
|
||||
value = value + ", opaque=\"" + opaque;
|
||||
value = value + "\"";
|
||||
value += ", opaque=\"" + opaque + "\"";
|
||||
}
|
||||
if (cnonce != null) {
|
||||
value = value + ", cnonce=\"" + cnonce;
|
||||
value = value + "\"";
|
||||
value += ", cnonce=\"" + cnonce + "\"";
|
||||
}
|
||||
if (qop) {
|
||||
value = value + ", qop=auth";
|
||||
value += qopS;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -74,8 +74,6 @@ class PollingWatchService
|
||||
throws IOException
|
||||
{
|
||||
// check events - CCE will be thrown if there are invalid elements
|
||||
if (events.length == 0)
|
||||
throw new IllegalArgumentException("No events to register");
|
||||
final Set<WatchEvent.Kind<?>> eventSet =
|
||||
new HashSet<WatchEvent.Kind<?>>(events.length);
|
||||
for (WatchEvent.Kind<?> event: events) {
|
||||
@ -90,8 +88,6 @@ class PollingWatchService
|
||||
|
||||
// OVERFLOW is ignored
|
||||
if (event == StandardWatchEventKinds.OVERFLOW) {
|
||||
if (events.length == 1)
|
||||
throw new IllegalArgumentException("No events to register");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -100,6 +96,8 @@ class PollingWatchService
|
||||
throw new NullPointerException("An element in event set is 'null'");
|
||||
throw new UnsupportedOperationException(event.name());
|
||||
}
|
||||
if (eventSet.isEmpty())
|
||||
throw new IllegalArgumentException("No events to register");
|
||||
|
||||
// A modifier may be used to specify the sensitivity level
|
||||
SensitivityWatchEventModifier sensivity = SensitivityWatchEventModifier.MEDIUM;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -60,9 +60,6 @@ public final class PKIXValidator extends Validator {
|
||||
AccessController.doPrivileged
|
||||
(new GetBooleanAction("com.sun.net.ssl.checkRevocation"));
|
||||
|
||||
// enable use of the validator if possible
|
||||
private final static boolean TRY_VALIDATOR = true;
|
||||
|
||||
private final Set<X509Certificate> trustedCerts;
|
||||
private final PKIXBuilderParameters parameterTemplate;
|
||||
private int certPathLength = -1;
|
||||
@ -75,48 +72,28 @@ public final class PKIXValidator extends Validator {
|
||||
|
||||
PKIXValidator(String variant, Collection<X509Certificate> trustedCerts) {
|
||||
super(TYPE_PKIX, variant);
|
||||
if (trustedCerts instanceof Set) {
|
||||
this.trustedCerts = (Set<X509Certificate>)trustedCerts;
|
||||
} else {
|
||||
this.trustedCerts = new HashSet<X509Certificate>(trustedCerts);
|
||||
}
|
||||
Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>();
|
||||
this.trustedCerts = (trustedCerts instanceof Set) ?
|
||||
(Set<X509Certificate>)trustedCerts :
|
||||
new HashSet<X509Certificate>(trustedCerts);
|
||||
|
||||
Set<TrustAnchor> trustAnchors = new HashSet<>();
|
||||
for (X509Certificate cert : trustedCerts) {
|
||||
trustAnchors.add(new TrustAnchor(cert, null));
|
||||
}
|
||||
|
||||
try {
|
||||
parameterTemplate = new PKIXBuilderParameters(trustAnchors, null);
|
||||
factory = CertificateFactory.getInstance("X.509");
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
throw new RuntimeException("Unexpected error: " + e.toString(), e);
|
||||
}
|
||||
setDefaultParameters(variant);
|
||||
|
||||
// initCommon();
|
||||
if (TRY_VALIDATOR) {
|
||||
if (TRY_VALIDATOR == false) {
|
||||
return;
|
||||
}
|
||||
trustedSubjects = new HashMap<X500Principal, List<PublicKey>>();
|
||||
for (X509Certificate cert : trustedCerts) {
|
||||
X500Principal dn = cert.getSubjectX500Principal();
|
||||
List<PublicKey> keys;
|
||||
if (trustedSubjects.containsKey(dn)) {
|
||||
keys = trustedSubjects.get(dn);
|
||||
} else {
|
||||
keys = new ArrayList<PublicKey>();
|
||||
trustedSubjects.put(dn, keys);
|
||||
}
|
||||
keys.add(cert.getPublicKey());
|
||||
}
|
||||
try {
|
||||
factory = CertificateFactory.getInstance("X.509");
|
||||
} catch (CertificateException e) {
|
||||
throw new RuntimeException("Internal error", e);
|
||||
}
|
||||
|
||||
setDefaultParameters(variant);
|
||||
plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
|
||||
} else {
|
||||
plugin = false;
|
||||
}
|
||||
|
||||
trustedSubjects = setTrustedSubjects();
|
||||
}
|
||||
|
||||
PKIXValidator(String variant, PKIXBuilderParameters params) {
|
||||
@ -130,32 +107,40 @@ public final class PKIXValidator extends Validator {
|
||||
}
|
||||
parameterTemplate = params;
|
||||
|
||||
// initCommon();
|
||||
if (TRY_VALIDATOR) {
|
||||
if (TRY_VALIDATOR == false) {
|
||||
return;
|
||||
}
|
||||
trustedSubjects = new HashMap<X500Principal, List<PublicKey>>();
|
||||
for (X509Certificate cert : trustedCerts) {
|
||||
X500Principal dn = cert.getSubjectX500Principal();
|
||||
List<PublicKey> keys;
|
||||
if (trustedSubjects.containsKey(dn)) {
|
||||
keys = trustedSubjects.get(dn);
|
||||
} else {
|
||||
keys = new ArrayList<PublicKey>();
|
||||
trustedSubjects.put(dn, keys);
|
||||
}
|
||||
keys.add(cert.getPublicKey());
|
||||
}
|
||||
try {
|
||||
factory = CertificateFactory.getInstance("X.509");
|
||||
} catch (CertificateException e) {
|
||||
throw new RuntimeException("Internal error", e);
|
||||
}
|
||||
|
||||
plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
|
||||
|
||||
trustedSubjects = setTrustedSubjects();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the trustedSubjects Map using the DN and public keys from
|
||||
* the list of trusted certificates
|
||||
*
|
||||
* @return Map containing each subject DN and one or more public keys
|
||||
* tied to those DNs.
|
||||
*/
|
||||
private Map<X500Principal, List<PublicKey>> setTrustedSubjects() {
|
||||
Map<X500Principal, List<PublicKey>> subjectMap = new HashMap<>();
|
||||
|
||||
for (X509Certificate cert : trustedCerts) {
|
||||
X500Principal dn = cert.getSubjectX500Principal();
|
||||
List<PublicKey> keys;
|
||||
if (subjectMap.containsKey(dn)) {
|
||||
keys = subjectMap.get(dn);
|
||||
} else {
|
||||
plugin = false;
|
||||
keys = new ArrayList<PublicKey>();
|
||||
subjectMap.put(dn, keys);
|
||||
}
|
||||
keys.add(cert.getPublicKey());
|
||||
}
|
||||
|
||||
return subjectMap;
|
||||
}
|
||||
|
||||
public Collection<X509Certificate> getTrustedCertificates() {
|
||||
@ -217,7 +202,6 @@ public final class PKIXValidator extends Validator {
|
||||
pkixParameters.addCertPathChecker(algorithmChecker);
|
||||
}
|
||||
|
||||
if (TRY_VALIDATOR) {
|
||||
// check that chain is in correct order and check if chain contains
|
||||
// trust anchor
|
||||
X500Principal prevIssuer = null;
|
||||
@ -287,7 +271,6 @@ public final class PKIXValidator extends Validator {
|
||||
(ValidatorException.T_NO_TRUST_ANCHOR);
|
||||
}
|
||||
// otherwise, fall back to builder
|
||||
}
|
||||
|
||||
return doBuild(chain, otherCerts, pkixParameters);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -257,6 +257,20 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine {
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility method to read data into a String.
|
||||
*/
|
||||
String readErrorMessage(InputStream sis) throws IOException {
|
||||
byte b[] = new byte[1024];
|
||||
int n;
|
||||
StringBuffer message = new StringBuffer();
|
||||
while ((n = sis.read(b)) != -1) {
|
||||
message.append(new String(b, 0, n, "UTF-8"));
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
|
||||
// -- attach timeout support
|
||||
|
||||
private static long defaultAttachTimeout = 5000;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -33,10 +33,12 @@ import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import com.sun.tools.attach.AttachOperationFailedException;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.VirtualMachineDescriptor;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
|
||||
import sun.tools.attach.HotSpotVirtualMachine;
|
||||
import sun.tools.jstat.JStatLogger;
|
||||
import sun.jvmstat.monitor.Monitor;
|
||||
@ -119,6 +121,7 @@ public class JCmd {
|
||||
pids.add(arg.getPid() + "");
|
||||
}
|
||||
|
||||
boolean success = true;
|
||||
for (String pid : pids) {
|
||||
System.out.println(pid + ":");
|
||||
if (arg.isListCounters()) {
|
||||
@ -126,11 +129,16 @@ public class JCmd {
|
||||
} else {
|
||||
try {
|
||||
executeCommandForPid(pid, arg.getCommand());
|
||||
} catch(AttachOperationFailedException ex) {
|
||||
System.err.println(ex.getMessage());
|
||||
success = false;
|
||||
} catch(Exception ex) {
|
||||
ex.printStackTrace();
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.exit(success ? 0 : 1);
|
||||
}
|
||||
|
||||
private static void executeCommandForPid(String pid, String command)
|
||||
@ -150,13 +158,18 @@ public class JCmd {
|
||||
// read to EOF and just print output
|
||||
byte b[] = new byte[256];
|
||||
int n;
|
||||
boolean messagePrinted = false;
|
||||
do {
|
||||
n = in.read(b);
|
||||
if (n > 0) {
|
||||
String s = new String(b, 0, n, "UTF-8");
|
||||
System.out.print(s);
|
||||
messagePrinted = true;
|
||||
}
|
||||
} while (n > 0);
|
||||
if (!messagePrinted) {
|
||||
System.out.println("Command executed successfully");
|
||||
}
|
||||
}
|
||||
}
|
||||
vm.detach();
|
||||
|
||||
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.util.spi;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.InvalidPropertiesFormatException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Service-provider class for loading and storing {@link Properites} in XML
|
||||
* format.
|
||||
*
|
||||
* @see Properties#loadFromXML
|
||||
* @see Properties#storeToXML
|
||||
*/
|
||||
|
||||
public abstract class XmlPropertiesProvider {
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*/
|
||||
protected XmlPropertiesProvider() {
|
||||
// do nothing for now
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all of the properties represented by the XML document on the
|
||||
* specified input stream into a properties table.
|
||||
*
|
||||
* @param props the properties table to populate
|
||||
* @param in the input stream from which to read the XML document
|
||||
* @throws IOException if reading from the specified input stream fails
|
||||
* @throws java.io.UnsupportedEncodingException if the document's encoding
|
||||
* declaration can be read and it specifies an encoding that is not
|
||||
* supported
|
||||
* @throws InvalidPropertiesFormatException Data on input stream does not
|
||||
* constitute a valid XML document with the mandated document type.
|
||||
*
|
||||
* @see Properties#loadFromXML
|
||||
*/
|
||||
public abstract void load(Properties props, InputStream in)
|
||||
throws IOException, InvalidPropertiesFormatException;
|
||||
|
||||
/**
|
||||
* Emits an XML document representing all of the properties in a given
|
||||
* table.
|
||||
*
|
||||
* @param props the properies to store
|
||||
* @param out the output stream on which to emit the XML document.
|
||||
* @param comment a description of the property list, can be @{code null}
|
||||
* @param encoding the name of a supported character encoding
|
||||
*
|
||||
* @throws IOException if writing to the specified output stream fails
|
||||
* @throws java.io.UnsupportedEncodingException if the encoding is not
|
||||
* supported by the implementation
|
||||
* @throws NullPointerException if {@code out} is null.
|
||||
* @throws ClassCastException if this {@code Properties} object
|
||||
* contains any keys or values that are not
|
||||
* {@code Strings}.
|
||||
*
|
||||
* @see Properties#storeToXML
|
||||
*/
|
||||
public abstract void store(Properties props, OutputStream out,
|
||||
String comment, String encoding)
|
||||
throws IOException;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
sun.util.xml.PlatformXmlPropertiesProvider
|
||||
@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.util.xml;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.Map.Entry;
|
||||
import org.xml.sax.*;
|
||||
import org.w3c.dom.*;
|
||||
import javax.xml.parsers.*;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.dom.*;
|
||||
import javax.xml.transform.stream.*;
|
||||
|
||||
import sun.util.spi.XmlPropertiesProvider;
|
||||
|
||||
/**
|
||||
* A {@code XmlPropertiesProvider} implementation that uses the JAXP API
|
||||
* for parsing.
|
||||
*
|
||||
* @author Michael McCloskey
|
||||
* @since 1.3
|
||||
*/
|
||||
public class PlatformXmlPropertiesProvider extends XmlPropertiesProvider {
|
||||
|
||||
// XML loading and saving methods for Properties
|
||||
|
||||
// The required DTD URI for exported properties
|
||||
private static final String PROPS_DTD_URI =
|
||||
"http://java.sun.com/dtd/properties.dtd";
|
||||
|
||||
private static final String PROPS_DTD =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<!-- DTD for properties -->" +
|
||||
"<!ELEMENT properties ( comment?, entry* ) >"+
|
||||
"<!ATTLIST properties" +
|
||||
" version CDATA #FIXED \"1.0\">" +
|
||||
"<!ELEMENT comment (#PCDATA) >" +
|
||||
"<!ELEMENT entry (#PCDATA) >" +
|
||||
"<!ATTLIST entry " +
|
||||
" key CDATA #REQUIRED>";
|
||||
|
||||
/**
|
||||
* Version number for the format of exported properties files.
|
||||
*/
|
||||
private static final String EXTERNAL_XML_VERSION = "1.0";
|
||||
|
||||
@Override
|
||||
public void load(Properties props, InputStream in)
|
||||
throws IOException, InvalidPropertiesFormatException
|
||||
{
|
||||
Document doc = null;
|
||||
try {
|
||||
doc = getLoadingDoc(in);
|
||||
} catch (SAXException saxe) {
|
||||
throw new InvalidPropertiesFormatException(saxe);
|
||||
}
|
||||
Element propertiesElement = doc.getDocumentElement();
|
||||
String xmlVersion = propertiesElement.getAttribute("version");
|
||||
if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
|
||||
throw new InvalidPropertiesFormatException(
|
||||
"Exported Properties file format version " + xmlVersion +
|
||||
" is not supported. This java installation can read" +
|
||||
" versions " + EXTERNAL_XML_VERSION + " or older. You" +
|
||||
" may need to install a newer version of JDK.");
|
||||
importProperties(props, propertiesElement);
|
||||
}
|
||||
|
||||
static Document getLoadingDoc(InputStream in)
|
||||
throws SAXException, IOException
|
||||
{
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setIgnoringElementContentWhitespace(true);
|
||||
dbf.setValidating(true);
|
||||
dbf.setCoalescing(true);
|
||||
dbf.setIgnoringComments(true);
|
||||
try {
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
db.setEntityResolver(new Resolver());
|
||||
db.setErrorHandler(new EH());
|
||||
InputSource is = new InputSource(in);
|
||||
return db.parse(is);
|
||||
} catch (ParserConfigurationException x) {
|
||||
throw new Error(x);
|
||||
}
|
||||
}
|
||||
|
||||
static void importProperties(Properties props, Element propertiesElement) {
|
||||
NodeList entries = propertiesElement.getChildNodes();
|
||||
int numEntries = entries.getLength();
|
||||
int start = numEntries > 0 &&
|
||||
entries.item(0).getNodeName().equals("comment") ? 1 : 0;
|
||||
for (int i=start; i<numEntries; i++) {
|
||||
Element entry = (Element)entries.item(i);
|
||||
if (entry.hasAttribute("key")) {
|
||||
Node n = entry.getFirstChild();
|
||||
String val = (n == null) ? "" : n.getNodeValue();
|
||||
props.setProperty(entry.getAttribute("key"), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(Properties props, OutputStream os, String comment,
|
||||
String encoding)
|
||||
throws IOException
|
||||
{
|
||||
// fast-fail for unsupported charsets as UnsupportedEncodingException may
|
||||
// not be thrown later (see JDK-8000621)
|
||||
try {
|
||||
Charset.forName(encoding);
|
||||
} catch (IllegalCharsetNameException | UnsupportedCharsetException x) {
|
||||
throw new UnsupportedEncodingException(encoding);
|
||||
}
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = null;
|
||||
try {
|
||||
db = dbf.newDocumentBuilder();
|
||||
} catch (ParserConfigurationException pce) {
|
||||
assert(false);
|
||||
}
|
||||
Document doc = db.newDocument();
|
||||
Element properties = (Element)
|
||||
doc.appendChild(doc.createElement("properties"));
|
||||
|
||||
if (comment != null) {
|
||||
Element comments = (Element)properties.appendChild(
|
||||
doc.createElement("comment"));
|
||||
comments.appendChild(doc.createTextNode(comment));
|
||||
}
|
||||
|
||||
synchronized (props) {
|
||||
for (Entry<Object, Object> e : props.entrySet()) {
|
||||
final Object k = e.getKey();
|
||||
final Object v = e.getValue();
|
||||
if (k instanceof String && v instanceof String) {
|
||||
Element entry = (Element)properties.appendChild(
|
||||
doc.createElement("entry"));
|
||||
entry.setAttribute("key", (String)k);
|
||||
entry.appendChild(doc.createTextNode((String)v));
|
||||
}
|
||||
}
|
||||
}
|
||||
emitDocument(doc, os, encoding);
|
||||
}
|
||||
|
||||
static void emitDocument(Document doc, OutputStream os, String encoding)
|
||||
throws IOException
|
||||
{
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Transformer t = null;
|
||||
try {
|
||||
t = tf.newTransformer();
|
||||
t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI);
|
||||
t.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
t.setOutputProperty(OutputKeys.METHOD, "xml");
|
||||
t.setOutputProperty(OutputKeys.ENCODING, encoding);
|
||||
} catch (TransformerConfigurationException tce) {
|
||||
assert(false);
|
||||
}
|
||||
DOMSource doms = new DOMSource(doc);
|
||||
StreamResult sr = new StreamResult(os);
|
||||
try {
|
||||
t.transform(doms, sr);
|
||||
} catch (TransformerException te) {
|
||||
throw new IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Resolver implements EntityResolver {
|
||||
public InputSource resolveEntity(String pid, String sid)
|
||||
throws SAXException
|
||||
{
|
||||
if (sid.equals(PROPS_DTD_URI)) {
|
||||
InputSource is;
|
||||
is = new InputSource(new StringReader(PROPS_DTD));
|
||||
is.setSystemId(PROPS_DTD_URI);
|
||||
return is;
|
||||
}
|
||||
throw new SAXException("Invalid system identifier: " + sid);
|
||||
}
|
||||
}
|
||||
|
||||
private static class EH implements ErrorHandler {
|
||||
public void error(SAXParseException x) throws SAXException {
|
||||
throw x;
|
||||
}
|
||||
public void fatalError(SAXParseException x) throws SAXException {
|
||||
throw x;
|
||||
}
|
||||
public void warning(SAXParseException x) throws SAXException {
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,39 @@
|
||||
// permissions required by each component
|
||||
grant codeBase "file:${java.home}/lib/ext/zipfs.jar" {
|
||||
permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
|
||||
permission java.lang.RuntimePermission "fileSystemProvider";
|
||||
permission java.util.PropertyPermission "*", "read";
|
||||
};
|
||||
|
||||
// Standard extensions get all permissions by default
|
||||
grant codeBase "file:${java.home}/lib/ext/cldrdata.jar" {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.text.*";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.util.*";
|
||||
permission java.util.PropertyPermission "*", "read";
|
||||
};
|
||||
|
||||
grant codeBase "file:${{java.ext.dirs}}/*" {
|
||||
grant codeBase "file:${java.home}/lib/ext/localedata.jar" {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.text.*";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.util.*";
|
||||
permission java.util.PropertyPermission "*", "read";
|
||||
};
|
||||
|
||||
grant codeBase "file:${java.home}/lib/ext/dnsns.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "file:${java.home}/lib/ext/nashorn.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "file:${java.home}/lib/ext/sunec.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "file:${java.home}/lib/ext/sunjce_provider.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "file:${java.home}/lib/ext/sunpkcs11.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
|
||||
827
jdk/src/solaris/classes/java/lang/UNIXProcess.java
Normal file
827
jdk/src/solaris/classes/java/lang/UNIXProcess.java
Normal file
@ -0,0 +1,827 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.security.AccessController;
|
||||
import static java.security.AccessController.doPrivileged;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
/**
|
||||
* java.lang.Process subclass in the UNIX environment.
|
||||
*
|
||||
* @author Mario Wolczko and Ross Knippel.
|
||||
* @author Konstantin Kladko (ported to Linux and Bsd)
|
||||
* @author Martin Buchholz
|
||||
* @author Volker Simonis (ported to AIX)
|
||||
*/
|
||||
final class UNIXProcess extends Process {
|
||||
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
|
||||
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
private final int pid;
|
||||
private int exitcode;
|
||||
private boolean hasExited;
|
||||
|
||||
private /* final */ OutputStream stdin;
|
||||
private /* final */ InputStream stdout;
|
||||
private /* final */ InputStream stderr;
|
||||
|
||||
// only used on Solaris
|
||||
private /* final */ DeferredCloseInputStream stdout_inner_stream;
|
||||
|
||||
private static enum LaunchMechanism {
|
||||
// order IS important!
|
||||
FORK,
|
||||
POSIX_SPAWN,
|
||||
VFORK
|
||||
}
|
||||
|
||||
private static enum Platform {
|
||||
|
||||
LINUX(LaunchMechanism.VFORK, LaunchMechanism.FORK),
|
||||
|
||||
BSD(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
|
||||
|
||||
SOLARIS(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
|
||||
|
||||
AIX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK);
|
||||
|
||||
final LaunchMechanism defaultLaunchMechanism;
|
||||
final Set<LaunchMechanism> validLaunchMechanisms;
|
||||
|
||||
Platform(LaunchMechanism ... launchMechanisms) {
|
||||
this.defaultLaunchMechanism = launchMechanisms[0];
|
||||
this.validLaunchMechanisms =
|
||||
EnumSet.copyOf(Arrays.asList(launchMechanisms));
|
||||
}
|
||||
|
||||
private String helperPath(String javahome, String osArch) {
|
||||
switch (this) {
|
||||
case SOLARIS:
|
||||
if (osArch.equals("x86")) { osArch = "i386"; }
|
||||
else if (osArch.equals("x86_64")) { osArch = "amd64"; }
|
||||
// fall through...
|
||||
case LINUX:
|
||||
case AIX:
|
||||
return javahome + "/lib/" + osArch + "/jspawnhelper";
|
||||
|
||||
case BSD:
|
||||
return javahome + "/lib/jspawnhelper";
|
||||
|
||||
default:
|
||||
throw new AssertionError("Unsupported platform: " + this);
|
||||
}
|
||||
}
|
||||
|
||||
String helperPath() {
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<String>) () ->
|
||||
helperPath(System.getProperty("java.home"),
|
||||
System.getProperty("os.arch"))
|
||||
);
|
||||
}
|
||||
|
||||
LaunchMechanism launchMechanism() {
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<LaunchMechanism>) () -> {
|
||||
String s = System.getProperty(
|
||||
"jdk.lang.Process.launchMechanism");
|
||||
LaunchMechanism lm;
|
||||
if (s == null) {
|
||||
lm = defaultLaunchMechanism;
|
||||
s = lm.name().toLowerCase(Locale.ENGLISH);
|
||||
} else {
|
||||
try {
|
||||
lm = LaunchMechanism.valueOf(
|
||||
s.toUpperCase(Locale.ENGLISH));
|
||||
} catch (IllegalArgumentException e) {
|
||||
lm = null;
|
||||
}
|
||||
}
|
||||
if (lm == null || !validLaunchMechanisms.contains(lm)) {
|
||||
throw new Error(
|
||||
s + " is not a supported " +
|
||||
"process launch mechanism on this platform."
|
||||
);
|
||||
}
|
||||
return lm;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
static Platform get() {
|
||||
String osName = AccessController.doPrivileged(
|
||||
(PrivilegedAction<String>) () -> System.getProperty("os.name")
|
||||
);
|
||||
|
||||
if (osName.equals("Linux")) { return LINUX; }
|
||||
if (osName.contains("OS X")) { return BSD; }
|
||||
if (osName.equals("SunOS")) { return SOLARIS; }
|
||||
if (osName.equals("AIX")) { return AIX; }
|
||||
|
||||
throw new Error(osName + " is not a supported OS platform.");
|
||||
}
|
||||
}
|
||||
|
||||
private static final Platform platform = Platform.get();
|
||||
private static final LaunchMechanism launchMechanism = platform.launchMechanism();
|
||||
private static final byte[] helperpath = toCString(platform.helperPath());
|
||||
|
||||
private static byte[] toCString(String s) {
|
||||
if (s == null)
|
||||
return null;
|
||||
byte[] bytes = s.getBytes();
|
||||
byte[] result = new byte[bytes.length + 1];
|
||||
System.arraycopy(bytes, 0,
|
||||
result, 0,
|
||||
bytes.length);
|
||||
result[result.length-1] = (byte)0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* this is for the reaping thread */
|
||||
private native int waitForProcessExit(int pid);
|
||||
|
||||
/**
|
||||
* Creates a process. Depending on the {@code mode} flag, this is done by
|
||||
* one of the following mechanisms:
|
||||
* <pre>
|
||||
* 1 - fork(2) and exec(2)
|
||||
* 2 - posix_spawn(3P)
|
||||
* 3 - vfork(2) and exec(2)
|
||||
*
|
||||
* (4 - clone(2) and exec(2) - obsolete and currently disabled in native code)
|
||||
* </pre>
|
||||
* @param fds an array of three file descriptors.
|
||||
* Indexes 0, 1, and 2 correspond to standard input,
|
||||
* standard output and standard error, respectively. On
|
||||
* input, a value of -1 means to create a pipe to connect
|
||||
* child and parent processes. On output, a value which
|
||||
* is not -1 is the parent pipe fd corresponding to the
|
||||
* pipe which has been created. An element of this array
|
||||
* is -1 on input if and only if it is <em>not</em> -1 on
|
||||
* output.
|
||||
* @return the pid of the subprocess
|
||||
*/
|
||||
private native int forkAndExec(int mode, byte[] helperpath,
|
||||
byte[] prog,
|
||||
byte[] argBlock, int argc,
|
||||
byte[] envBlock, int envc,
|
||||
byte[] dir,
|
||||
int[] fds,
|
||||
boolean redirectErrorStream)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* The thread pool of "process reaper" daemon threads.
|
||||
*/
|
||||
private static final Executor processReaperExecutor =
|
||||
doPrivileged((PrivilegedAction<Executor>) () -> {
|
||||
|
||||
ThreadGroup tg = Thread.currentThread().getThreadGroup();
|
||||
while (tg.getParent() != null) tg = tg.getParent();
|
||||
ThreadGroup systemThreadGroup = tg;
|
||||
|
||||
ThreadFactory threadFactory = grimReaper -> {
|
||||
// Our thread stack requirement is quite modest.
|
||||
Thread t = new Thread(systemThreadGroup, grimReaper,
|
||||
"process reaper", 32768);
|
||||
t.setDaemon(true);
|
||||
// A small attempt (probably futile) to avoid priority inversion
|
||||
t.setPriority(Thread.MAX_PRIORITY);
|
||||
return t;
|
||||
};
|
||||
|
||||
return Executors.newCachedThreadPool(threadFactory);
|
||||
});
|
||||
|
||||
UNIXProcess(final byte[] prog,
|
||||
final byte[] argBlock, final int argc,
|
||||
final byte[] envBlock, final int envc,
|
||||
final byte[] dir,
|
||||
final int[] fds,
|
||||
final boolean redirectErrorStream)
|
||||
throws IOException {
|
||||
|
||||
pid = forkAndExec(launchMechanism.ordinal() + 1,
|
||||
helperpath,
|
||||
prog,
|
||||
argBlock, argc,
|
||||
envBlock, envc,
|
||||
dir,
|
||||
fds,
|
||||
redirectErrorStream);
|
||||
|
||||
try {
|
||||
doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
||||
initStreams(fds);
|
||||
return null;
|
||||
});
|
||||
} catch (PrivilegedActionException ex) {
|
||||
throw (IOException) ex.getException();
|
||||
}
|
||||
}
|
||||
|
||||
static FileDescriptor newFileDescriptor(int fd) {
|
||||
FileDescriptor fileDescriptor = new FileDescriptor();
|
||||
fdAccess.set(fileDescriptor, fd);
|
||||
return fileDescriptor;
|
||||
}
|
||||
|
||||
void initStreams(int[] fds) throws IOException {
|
||||
switch (platform) {
|
||||
case LINUX:
|
||||
case BSD:
|
||||
stdin = (fds[0] == -1) ?
|
||||
ProcessBuilder.NullOutputStream.INSTANCE :
|
||||
new ProcessPipeOutputStream(fds[0]);
|
||||
|
||||
stdout = (fds[1] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[1]);
|
||||
|
||||
stderr = (fds[2] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[2]);
|
||||
|
||||
processReaperExecutor.execute(() -> {
|
||||
int exitcode = waitForProcessExit(pid);
|
||||
|
||||
synchronized (this) {
|
||||
this.exitcode = exitcode;
|
||||
this.hasExited = true;
|
||||
this.notifyAll();
|
||||
}
|
||||
|
||||
if (stdout instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stdout).processExited();
|
||||
|
||||
if (stderr instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stderr).processExited();
|
||||
|
||||
if (stdin instanceof ProcessPipeOutputStream)
|
||||
((ProcessPipeOutputStream) stdin).processExited();
|
||||
});
|
||||
break;
|
||||
|
||||
case SOLARIS:
|
||||
stdin = (fds[0] == -1) ?
|
||||
ProcessBuilder.NullOutputStream.INSTANCE :
|
||||
new BufferedOutputStream(
|
||||
new FileOutputStream(newFileDescriptor(fds[0])));
|
||||
|
||||
stdout = (fds[1] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new BufferedInputStream(
|
||||
stdout_inner_stream =
|
||||
new DeferredCloseInputStream(
|
||||
newFileDescriptor(fds[1])));
|
||||
|
||||
stderr = (fds[2] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new DeferredCloseInputStream(newFileDescriptor(fds[2]));
|
||||
|
||||
/*
|
||||
* For each subprocess forked a corresponding reaper task
|
||||
* is submitted. That task is the only thread which waits
|
||||
* for the subprocess to terminate and it doesn't hold any
|
||||
* locks while doing so. This design allows waitFor() and
|
||||
* exitStatus() to be safely executed in parallel (and they
|
||||
* need no native code).
|
||||
*/
|
||||
processReaperExecutor.execute(() -> {
|
||||
int exitcode = waitForProcessExit(pid);
|
||||
|
||||
synchronized (this) {
|
||||
this.exitcode = exitcode;
|
||||
this.hasExited = true;
|
||||
this.notifyAll();
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case AIX:
|
||||
stdin = (fds[0] == -1) ?
|
||||
ProcessBuilder.NullOutputStream.INSTANCE :
|
||||
new ProcessPipeOutputStream(fds[0]);
|
||||
|
||||
stdout = (fds[1] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new DeferredCloseProcessPipeInputStream(fds[1]);
|
||||
|
||||
stderr = (fds[2] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new DeferredCloseProcessPipeInputStream(fds[2]);
|
||||
|
||||
processReaperExecutor.execute(() -> {
|
||||
int exitcode = waitForProcessExit(pid);
|
||||
|
||||
synchronized (this) {
|
||||
this.exitcode = exitcode;
|
||||
this.hasExited = true;
|
||||
this.notifyAll();
|
||||
}
|
||||
|
||||
if (stdout instanceof DeferredCloseProcessPipeInputStream)
|
||||
((DeferredCloseProcessPipeInputStream) stdout).processExited();
|
||||
|
||||
if (stderr instanceof DeferredCloseProcessPipeInputStream)
|
||||
((DeferredCloseProcessPipeInputStream) stderr).processExited();
|
||||
|
||||
if (stdin instanceof ProcessPipeOutputStream)
|
||||
((ProcessPipeOutputStream) stdin).processExited();
|
||||
});
|
||||
break;
|
||||
|
||||
default: throw new AssertionError("Unsupported platform: " + platform);
|
||||
}
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return stdin;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return stderr;
|
||||
}
|
||||
|
||||
public synchronized int waitFor() throws InterruptedException {
|
||||
while (!hasExited) {
|
||||
wait();
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean waitFor(long timeout, TimeUnit unit)
|
||||
throws InterruptedException
|
||||
{
|
||||
if (hasExited) return true;
|
||||
if (timeout <= 0) return false;
|
||||
|
||||
long timeoutAsNanos = unit.toNanos(timeout);
|
||||
long startTime = System.nanoTime();
|
||||
long rem = timeoutAsNanos;
|
||||
|
||||
while (!hasExited && (rem > 0)) {
|
||||
wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
|
||||
rem = timeoutAsNanos - (System.nanoTime() - startTime);
|
||||
}
|
||||
return hasExited;
|
||||
}
|
||||
|
||||
public synchronized int exitValue() {
|
||||
if (!hasExited) {
|
||||
throw new IllegalThreadStateException("process hasn't exited");
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
private static native void destroyProcess(int pid, boolean force);
|
||||
|
||||
private void destroy(boolean force) {
|
||||
switch (platform) {
|
||||
case LINUX:
|
||||
case BSD:
|
||||
case AIX:
|
||||
// There is a risk that pid will be recycled, causing us to
|
||||
// kill the wrong process! So we only terminate processes
|
||||
// that appear to still be running. Even with this check,
|
||||
// there is an unavoidable race condition here, but the window
|
||||
// is very small, and OSes try hard to not recycle pids too
|
||||
// soon, so this is quite safe.
|
||||
synchronized (this) {
|
||||
if (!hasExited)
|
||||
destroyProcess(pid, force);
|
||||
}
|
||||
try { stdin.close(); } catch (IOException ignored) {}
|
||||
try { stdout.close(); } catch (IOException ignored) {}
|
||||
try { stderr.close(); } catch (IOException ignored) {}
|
||||
break;
|
||||
|
||||
case SOLARIS:
|
||||
// There is a risk that pid will be recycled, causing us to
|
||||
// kill the wrong process! So we only terminate processes
|
||||
// that appear to still be running. Even with this check,
|
||||
// there is an unavoidable race condition here, but the window
|
||||
// is very small, and OSes try hard to not recycle pids too
|
||||
// soon, so this is quite safe.
|
||||
synchronized (this) {
|
||||
if (!hasExited)
|
||||
destroyProcess(pid, force);
|
||||
try {
|
||||
stdin.close();
|
||||
if (stdout_inner_stream != null)
|
||||
stdout_inner_stream.closeDeferred(stdout);
|
||||
if (stderr instanceof DeferredCloseInputStream)
|
||||
((DeferredCloseInputStream) stderr)
|
||||
.closeDeferred(stderr);
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: throw new AssertionError("Unsupported platform: " + platform);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
destroy(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process destroyForcibly() {
|
||||
destroy(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAlive() {
|
||||
return !hasExited;
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered input stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*
|
||||
* This is tricky because we do not want the user-level InputStream to be
|
||||
* closed until the user invokes close(), and we need to continue to be
|
||||
* able to read any buffered data lingering in the OS pipe buffer.
|
||||
*/
|
||||
private static class ProcessPipeInputStream extends BufferedInputStream {
|
||||
private final Object closeLock = new Object();
|
||||
|
||||
ProcessPipeInputStream(int fd) {
|
||||
super(new FileInputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
private static byte[] drainInputStream(InputStream in)
|
||||
throws IOException {
|
||||
int n = 0;
|
||||
int j;
|
||||
byte[] a = null;
|
||||
while ((j = in.available()) > 0) {
|
||||
a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
|
||||
n += in.read(a, n, j);
|
||||
}
|
||||
return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
synchronized (closeLock) {
|
||||
try {
|
||||
InputStream in = this.in;
|
||||
// this stream is closed if and only if: in == null
|
||||
if (in != null) {
|
||||
byte[] stragglers = drainInputStream(in);
|
||||
in.close();
|
||||
this.in = (stragglers == null) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ByteArrayInputStream(stragglers);
|
||||
}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// BufferedInputStream#close() is not synchronized unlike most other
|
||||
// methods. Synchronizing helps avoid race with processExited().
|
||||
synchronized (closeLock) {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered output stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*/
|
||||
private static class ProcessPipeOutputStream extends BufferedOutputStream {
|
||||
ProcessPipeOutputStream(int fd) {
|
||||
super(new FileOutputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
OutputStream out = this.out;
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {
|
||||
// We know of no reason to get an IOException, but if
|
||||
// we do, there's nothing else to do but carry on.
|
||||
}
|
||||
this.out = ProcessBuilder.NullOutputStream.INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A FileInputStream that supports the deferment of the actual close
|
||||
// operation until the last pending I/O operation on the stream has
|
||||
// finished. This is required on Solaris because we must close the stdin
|
||||
// and stdout streams in the destroy method in order to reclaim the
|
||||
// underlying file descriptors. Doing so, however, causes any thread
|
||||
// currently blocked in a read on one of those streams to receive an
|
||||
// IOException("Bad file number"), which is incompatible with historical
|
||||
// behavior. By deferring the close we allow any pending reads to see -1
|
||||
// (EOF) as they did before.
|
||||
//
|
||||
private static class DeferredCloseInputStream extends FileInputStream
|
||||
{
|
||||
DeferredCloseInputStream(FileDescriptor fd) {
|
||||
super(fd);
|
||||
}
|
||||
|
||||
private Object lock = new Object(); // For the following fields
|
||||
private boolean closePending = false;
|
||||
private int useCount = 0;
|
||||
private InputStream streamToClose;
|
||||
|
||||
private void raise() {
|
||||
synchronized (lock) {
|
||||
useCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void lower() throws IOException {
|
||||
synchronized (lock) {
|
||||
useCount--;
|
||||
if (useCount == 0 && closePending) {
|
||||
streamToClose.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stc is the actual stream to be closed; it might be this object, or
|
||||
// it might be an upstream object for which this object is downstream.
|
||||
//
|
||||
private void closeDeferred(InputStream stc) throws IOException {
|
||||
synchronized (lock) {
|
||||
if (useCount == 0) {
|
||||
stc.close();
|
||||
} else {
|
||||
closePending = true;
|
||||
streamToClose = stc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
synchronized (lock) {
|
||||
useCount = 0;
|
||||
closePending = false;
|
||||
}
|
||||
super.close();
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read();
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read(b);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read(b, off, len);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
public long skip(long n) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.skip(n);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.available();
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered input stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*
|
||||
* This is tricky because we do not want the user-level InputStream to be
|
||||
* closed until the user invokes close(), and we need to continue to be
|
||||
* able to read any buffered data lingering in the OS pipe buffer.
|
||||
*
|
||||
* On AIX this is especially tricky, because the 'close()' system call
|
||||
* will block if another thread is at the same time blocked in a file
|
||||
* operation (e.g. 'read()') on the same file descriptor. We therefore
|
||||
* combine 'ProcessPipeInputStream' approach used on Linux and Bsd
|
||||
* with the DeferredCloseInputStream approach used on Solaris. This means
|
||||
* that every potentially blocking operation on the file descriptor
|
||||
* increments a counter before it is executed and decrements it once it
|
||||
* finishes. The 'close()' operation will only be executed if there are
|
||||
* no pending operations. Otherwise it is deferred after the last pending
|
||||
* operation has finished.
|
||||
*
|
||||
*/
|
||||
private static class DeferredCloseProcessPipeInputStream
|
||||
extends BufferedInputStream {
|
||||
|
||||
private final Object closeLock = new Object();
|
||||
private int useCount = 0;
|
||||
private boolean closePending = false;
|
||||
|
||||
DeferredCloseProcessPipeInputStream(int fd) {
|
||||
super(new FileInputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
|
||||
private InputStream drainInputStream(InputStream in)
|
||||
throws IOException {
|
||||
int n = 0;
|
||||
int j;
|
||||
byte[] a = null;
|
||||
synchronized (closeLock) {
|
||||
if (buf == null) // asynchronous close()?
|
||||
return null; // discard
|
||||
j = in.available();
|
||||
}
|
||||
while (j > 0) {
|
||||
a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
|
||||
synchronized (closeLock) {
|
||||
if (buf == null) // asynchronous close()?
|
||||
return null; // discard
|
||||
n += in.read(a, n, j);
|
||||
j = in.available();
|
||||
}
|
||||
}
|
||||
return (a == null) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ByteArrayInputStream(n == a.length ? a : Arrays.copyOf(a, n));
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
try {
|
||||
InputStream in = this.in;
|
||||
if (in != null) {
|
||||
InputStream stragglers = drainInputStream(in);
|
||||
in.close();
|
||||
this.in = stragglers;
|
||||
}
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
private void raise() {
|
||||
synchronized (closeLock) {
|
||||
useCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void lower() throws IOException {
|
||||
synchronized (closeLock) {
|
||||
useCount--;
|
||||
if (useCount == 0 && closePending) {
|
||||
closePending = false;
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read();
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read(b);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read(b, off, len);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.skip(n);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.available();
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// BufferedInputStream#close() is not synchronized unlike most other
|
||||
// methods. Synchronizing helps avoid racing with drainInputStream().
|
||||
synchronized (closeLock) {
|
||||
if (useCount == 0) {
|
||||
super.close();
|
||||
}
|
||||
else {
|
||||
closePending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,504 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.security.AccessController;
|
||||
import static java.security.AccessController.doPrivileged;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
/**
|
||||
* java.lang.Process subclass in the UNIX environment.
|
||||
*
|
||||
* @author Mario Wolczko and Ross Knippel.
|
||||
* @author Konstantin Kladko (ported to Linux)
|
||||
* @author Martin Buchholz
|
||||
* @author Volker Simonis (ported to AIX)
|
||||
*/
|
||||
final class UNIXProcess extends Process {
|
||||
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
|
||||
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
private final int pid;
|
||||
private int exitcode;
|
||||
private boolean hasExited;
|
||||
|
||||
private /* final */ OutputStream stdin;
|
||||
private /* final */ InputStream stdout;
|
||||
private /* final */ InputStream stderr;
|
||||
|
||||
private static enum LaunchMechanism {
|
||||
FORK(1),
|
||||
POSIX_SPAWN(2);
|
||||
|
||||
private int value;
|
||||
LaunchMechanism(int x) {value = x;}
|
||||
};
|
||||
|
||||
/* On AIX, the default is to spawn */
|
||||
private static final LaunchMechanism launchMechanism;
|
||||
private static byte[] helperpath;
|
||||
|
||||
private static byte[] toCString(String s) {
|
||||
if (s == null)
|
||||
return null;
|
||||
byte[] bytes = s.getBytes();
|
||||
byte[] result = new byte[bytes.length + 1];
|
||||
System.arraycopy(bytes, 0,
|
||||
result, 0,
|
||||
bytes.length);
|
||||
result[result.length-1] = (byte)0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static {
|
||||
launchMechanism = AccessController.doPrivileged(
|
||||
new PrivilegedAction<LaunchMechanism>()
|
||||
{
|
||||
public LaunchMechanism run() {
|
||||
String javahome = System.getProperty("java.home");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
|
||||
helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
|
||||
String s = System.getProperty(
|
||||
"jdk.lang.Process.launchMechanism", "posix_spawn");
|
||||
|
||||
try {
|
||||
return LaunchMechanism.valueOf(s.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new Error(s + " is not a supported " +
|
||||
"process launch mechanism on this platform.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* this is for the reaping thread */
|
||||
private native int waitForProcessExit(int pid);
|
||||
|
||||
/**
|
||||
* Create a process. Depending on the mode flag, this is done by
|
||||
* one of the following mechanisms.
|
||||
* - fork(2) and exec(2)
|
||||
* - clone(2) and exec(2)
|
||||
* - vfork(2) and exec(2)
|
||||
*
|
||||
* @param fds an array of three file descriptors.
|
||||
* Indexes 0, 1, and 2 correspond to standard input,
|
||||
* standard output and standard error, respectively. On
|
||||
* input, a value of -1 means to create a pipe to connect
|
||||
* child and parent processes. On output, a value which
|
||||
* is not -1 is the parent pipe fd corresponding to the
|
||||
* pipe which has been created. An element of this array
|
||||
* is -1 on input if and only if it is <em>not</em> -1 on
|
||||
* output.
|
||||
* @return the pid of the subprocess
|
||||
*/
|
||||
private native int forkAndExec(int mode, byte[] helperpath,
|
||||
byte[] prog,
|
||||
byte[] argBlock, int argc,
|
||||
byte[] envBlock, int envc,
|
||||
byte[] dir,
|
||||
int[] fds,
|
||||
boolean redirectErrorStream)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* The thread factory used to create "process reaper" daemon threads.
|
||||
*/
|
||||
private static class ProcessReaperThreadFactory implements ThreadFactory {
|
||||
private final static ThreadGroup group = getRootThreadGroup();
|
||||
|
||||
private static ThreadGroup getRootThreadGroup() {
|
||||
return doPrivileged(new PrivilegedAction<ThreadGroup> () {
|
||||
public ThreadGroup run() {
|
||||
ThreadGroup root = Thread.currentThread().getThreadGroup();
|
||||
while (root.getParent() != null)
|
||||
root = root.getParent();
|
||||
return root;
|
||||
}});
|
||||
}
|
||||
|
||||
public Thread newThread(Runnable grimReaper) {
|
||||
// Our thread stack requirement is quite modest.
|
||||
Thread t = new Thread(group, grimReaper, "process reaper", 32768);
|
||||
t.setDaemon(true);
|
||||
// A small attempt (probably futile) to avoid priority inversion
|
||||
t.setPriority(Thread.MAX_PRIORITY);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The thread pool of "process reaper" daemon threads.
|
||||
*/
|
||||
private static final Executor processReaperExecutor =
|
||||
doPrivileged(new PrivilegedAction<Executor>() {
|
||||
public Executor run() {
|
||||
return Executors.newCachedThreadPool
|
||||
(new ProcessReaperThreadFactory());
|
||||
}});
|
||||
|
||||
UNIXProcess(final byte[] prog,
|
||||
final byte[] argBlock, final int argc,
|
||||
final byte[] envBlock, final int envc,
|
||||
final byte[] dir,
|
||||
final int[] fds,
|
||||
final boolean redirectErrorStream)
|
||||
throws IOException {
|
||||
|
||||
pid = forkAndExec(launchMechanism.value,
|
||||
helperpath,
|
||||
prog,
|
||||
argBlock, argc,
|
||||
envBlock, envc,
|
||||
dir,
|
||||
fds,
|
||||
redirectErrorStream);
|
||||
|
||||
try {
|
||||
doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws IOException {
|
||||
initStreams(fds);
|
||||
return null;
|
||||
}});
|
||||
} catch (PrivilegedActionException ex) {
|
||||
throw (IOException) ex.getException();
|
||||
}
|
||||
}
|
||||
|
||||
static FileDescriptor newFileDescriptor(int fd) {
|
||||
FileDescriptor fileDescriptor = new FileDescriptor();
|
||||
fdAccess.set(fileDescriptor, fd);
|
||||
return fileDescriptor;
|
||||
}
|
||||
|
||||
void initStreams(int[] fds) throws IOException {
|
||||
stdin = (fds[0] == -1) ?
|
||||
ProcessBuilder.NullOutputStream.INSTANCE :
|
||||
new ProcessPipeOutputStream(fds[0]);
|
||||
|
||||
stdout = (fds[1] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[1]);
|
||||
|
||||
stderr = (fds[2] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[2]);
|
||||
|
||||
processReaperExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
int exitcode = waitForProcessExit(pid);
|
||||
UNIXProcess.this.processExited(exitcode);
|
||||
}});
|
||||
}
|
||||
|
||||
void processExited(int exitcode) {
|
||||
synchronized (this) {
|
||||
this.exitcode = exitcode;
|
||||
hasExited = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
if (stdout instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stdout).processExited();
|
||||
|
||||
if (stderr instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stderr).processExited();
|
||||
|
||||
if (stdin instanceof ProcessPipeOutputStream)
|
||||
((ProcessPipeOutputStream) stdin).processExited();
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return stdin;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return stderr;
|
||||
}
|
||||
|
||||
public synchronized int waitFor() throws InterruptedException {
|
||||
while (!hasExited) {
|
||||
wait();
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean waitFor(long timeout, TimeUnit unit)
|
||||
throws InterruptedException
|
||||
{
|
||||
if (hasExited) return true;
|
||||
if (timeout <= 0) return false;
|
||||
|
||||
long timeoutAsNanos = unit.toNanos(timeout);
|
||||
long startTime = System.nanoTime();
|
||||
long rem = timeoutAsNanos;
|
||||
|
||||
while (!hasExited && (rem > 0)) {
|
||||
wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
|
||||
rem = timeoutAsNanos - (System.nanoTime() - startTime);
|
||||
}
|
||||
return hasExited;
|
||||
}
|
||||
|
||||
public synchronized int exitValue() {
|
||||
if (!hasExited) {
|
||||
throw new IllegalThreadStateException("process hasn't exited");
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
private static native void destroyProcess(int pid, boolean force);
|
||||
private void destroy(boolean force) {
|
||||
// There is a risk that pid will be recycled, causing us to
|
||||
// kill the wrong process! So we only terminate processes
|
||||
// that appear to still be running. Even with this check,
|
||||
// there is an unavoidable race condition here, but the window
|
||||
// is very small, and OSes try hard to not recycle pids too
|
||||
// soon, so this is quite safe.
|
||||
synchronized (this) {
|
||||
if (!hasExited)
|
||||
destroyProcess(pid, force);
|
||||
}
|
||||
try { stdin.close(); } catch (IOException ignored) {}
|
||||
try { stdout.close(); } catch (IOException ignored) {}
|
||||
try { stderr.close(); } catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
destroy(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process destroyForcibly() {
|
||||
destroy(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAlive() {
|
||||
return !hasExited;
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered input stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*
|
||||
* This is tricky because we do not want the user-level InputStream to be
|
||||
* closed until the user invokes close(), and we need to continue to be
|
||||
* able to read any buffered data lingering in the OS pipe buffer.
|
||||
*
|
||||
* On AIX this is especially tricky, because the 'close()' system call
|
||||
* will block if another thread is at the same time blocked in a file
|
||||
* operation (e.g. 'read()') on the same file descriptor. We therefore
|
||||
* combine this 'ProcessPipeInputStream' with the DeferredCloseInputStream
|
||||
* approach used on Solaris (see "UNIXProcess.java.solaris"). This means
|
||||
* that every potentially blocking operation on the file descriptor
|
||||
* increments a counter before it is executed and decrements it once it
|
||||
* finishes. The 'close()' operation will only be executed if there are
|
||||
* no pending operations. Otherwise it is deferred after the last pending
|
||||
* operation has finished.
|
||||
*
|
||||
*/
|
||||
static class ProcessPipeInputStream extends BufferedInputStream {
|
||||
private final Object closeLock = new Object();
|
||||
private int useCount = 0;
|
||||
private boolean closePending = false;
|
||||
|
||||
ProcessPipeInputStream(int fd) {
|
||||
super(new FileInputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
|
||||
private InputStream drainInputStream(InputStream in)
|
||||
throws IOException {
|
||||
int n = 0;
|
||||
int j;
|
||||
byte[] a = null;
|
||||
synchronized (closeLock) {
|
||||
if (buf == null) // asynchronous close()?
|
||||
return null; // discard
|
||||
j = in.available();
|
||||
}
|
||||
while (j > 0) {
|
||||
a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
|
||||
synchronized (closeLock) {
|
||||
if (buf == null) // asynchronous close()?
|
||||
return null; // discard
|
||||
n += in.read(a, n, j);
|
||||
j = in.available();
|
||||
}
|
||||
}
|
||||
return (a == null) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ByteArrayInputStream(n == a.length ? a : Arrays.copyOf(a, n));
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
try {
|
||||
InputStream in = this.in;
|
||||
if (in != null) {
|
||||
InputStream stragglers = drainInputStream(in);
|
||||
in.close();
|
||||
this.in = stragglers;
|
||||
}
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
private void raise() {
|
||||
synchronized (closeLock) {
|
||||
useCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void lower() throws IOException {
|
||||
synchronized (closeLock) {
|
||||
useCount--;
|
||||
if (useCount == 0 && closePending) {
|
||||
closePending = false;
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read();
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read(b);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read(b, off, len);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.skip(n);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.available();
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// BufferedInputStream#close() is not synchronized unlike most other methods.
|
||||
// Synchronizing helps avoid racing with drainInputStream().
|
||||
synchronized (closeLock) {
|
||||
if (useCount == 0) {
|
||||
super.close();
|
||||
}
|
||||
else {
|
||||
closePending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered output stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*/
|
||||
static class ProcessPipeOutputStream extends BufferedOutputStream {
|
||||
ProcessPipeOutputStream(int fd) {
|
||||
super(new FileOutputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
OutputStream out = this.out;
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {
|
||||
// We know of no reason to get an IOException, but if
|
||||
// we do, there's nothing else to do but carry on.
|
||||
}
|
||||
this.out = ProcessBuilder.NullOutputStream.INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,408 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.security.AccessController;
|
||||
import static java.security.AccessController.doPrivileged;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
/**
|
||||
* java.lang.Process subclass in the UNIX environment.
|
||||
*
|
||||
* @author Mario Wolczko and Ross Knippel.
|
||||
* @author Konstantin Kladko (ported to Bsd)
|
||||
* @author Martin Buchholz
|
||||
*/
|
||||
final class UNIXProcess extends Process {
|
||||
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
|
||||
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
private final int pid;
|
||||
private int exitcode;
|
||||
private boolean hasExited;
|
||||
|
||||
private /* final */ OutputStream stdin;
|
||||
private /* final */ InputStream stdout;
|
||||
private /* final */ InputStream stderr;
|
||||
|
||||
private static enum LaunchMechanism {
|
||||
FORK(1),
|
||||
POSIX_SPAWN(2);
|
||||
|
||||
private int value;
|
||||
LaunchMechanism(int x) {value = x;}
|
||||
};
|
||||
|
||||
/* On BSD, the default is to spawn */
|
||||
private static final LaunchMechanism launchMechanism;
|
||||
private static byte[] helperpath;
|
||||
|
||||
private static byte[] toCString(String s) {
|
||||
if (s == null)
|
||||
return null;
|
||||
byte[] bytes = s.getBytes();
|
||||
byte[] result = new byte[bytes.length + 1];
|
||||
System.arraycopy(bytes, 0,
|
||||
result, 0,
|
||||
bytes.length);
|
||||
result[result.length-1] = (byte)0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static {
|
||||
launchMechanism = AccessController.doPrivileged(
|
||||
new PrivilegedAction<LaunchMechanism>()
|
||||
{
|
||||
public LaunchMechanism run() {
|
||||
String javahome = System.getProperty("java.home");
|
||||
|
||||
helperpath = toCString(javahome + "/lib/jspawnhelper");
|
||||
String s = System.getProperty(
|
||||
"jdk.lang.Process.launchMechanism", "posix_spawn");
|
||||
|
||||
try {
|
||||
return LaunchMechanism.valueOf(s.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new Error(s + " is not a supported " +
|
||||
"process launch mechanism on this platform.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* this is for the reaping thread */
|
||||
private native int waitForProcessExit(int pid);
|
||||
|
||||
/**
|
||||
* Create a process. Depending on the mode flag, this is done by
|
||||
* one of the following mechanisms.
|
||||
* - fork(2) and exec(2)
|
||||
* - posix_spawn(2)
|
||||
*
|
||||
* @param fds an array of three file descriptors.
|
||||
* Indexes 0, 1, and 2 correspond to standard input,
|
||||
* standard output and standard error, respectively. On
|
||||
* input, a value of -1 means to create a pipe to connect
|
||||
* child and parent processes. On output, a value which
|
||||
* is not -1 is the parent pipe fd corresponding to the
|
||||
* pipe which has been created. An element of this array
|
||||
* is -1 on input if and only if it is <em>not</em> -1 on
|
||||
* output.
|
||||
* @return the pid of the subprocess
|
||||
*/
|
||||
private native int forkAndExec(int mode, byte[] helperpath,
|
||||
byte[] prog,
|
||||
byte[] argBlock, int argc,
|
||||
byte[] envBlock, int envc,
|
||||
byte[] dir,
|
||||
int[] fds,
|
||||
boolean redirectErrorStream)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* The thread factory used to create "process reaper" daemon threads.
|
||||
*/
|
||||
private static class ProcessReaperThreadFactory implements ThreadFactory {
|
||||
private final static ThreadGroup group = getRootThreadGroup();
|
||||
|
||||
private static ThreadGroup getRootThreadGroup() {
|
||||
return doPrivileged(new PrivilegedAction<ThreadGroup> () {
|
||||
public ThreadGroup run() {
|
||||
ThreadGroup root = Thread.currentThread().getThreadGroup();
|
||||
while (root.getParent() != null)
|
||||
root = root.getParent();
|
||||
return root;
|
||||
}});
|
||||
}
|
||||
|
||||
public Thread newThread(Runnable grimReaper) {
|
||||
// Our thread stack requirement is quite modest.
|
||||
Thread t = new Thread(group, grimReaper, "process reaper", 32768);
|
||||
t.setDaemon(true);
|
||||
// A small attempt (probably futile) to avoid priority inversion
|
||||
t.setPriority(Thread.MAX_PRIORITY);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The thread pool of "process reaper" daemon threads.
|
||||
*/
|
||||
private static final Executor processReaperExecutor =
|
||||
doPrivileged(new PrivilegedAction<Executor>() {
|
||||
public Executor run() {
|
||||
return Executors.newCachedThreadPool
|
||||
(new ProcessReaperThreadFactory());
|
||||
}});
|
||||
|
||||
UNIXProcess(final byte[] prog,
|
||||
final byte[] argBlock, final int argc,
|
||||
final byte[] envBlock, final int envc,
|
||||
final byte[] dir,
|
||||
final int[] fds,
|
||||
final boolean redirectErrorStream)
|
||||
throws IOException {
|
||||
|
||||
pid = forkAndExec(launchMechanism.value,
|
||||
helperpath,
|
||||
prog,
|
||||
argBlock, argc,
|
||||
envBlock, envc,
|
||||
dir,
|
||||
fds,
|
||||
redirectErrorStream);
|
||||
|
||||
try {
|
||||
doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws IOException {
|
||||
initStreams(fds);
|
||||
return null;
|
||||
}});
|
||||
} catch (PrivilegedActionException ex) {
|
||||
throw (IOException) ex.getException();
|
||||
}
|
||||
}
|
||||
|
||||
static FileDescriptor newFileDescriptor(int fd) {
|
||||
FileDescriptor fileDescriptor = new FileDescriptor();
|
||||
fdAccess.set(fileDescriptor, fd);
|
||||
return fileDescriptor;
|
||||
}
|
||||
|
||||
void initStreams(int[] fds) throws IOException {
|
||||
stdin = (fds[0] == -1) ?
|
||||
ProcessBuilder.NullOutputStream.INSTANCE :
|
||||
new ProcessPipeOutputStream(fds[0]);
|
||||
|
||||
stdout = (fds[1] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[1]);
|
||||
|
||||
stderr = (fds[2] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[2]);
|
||||
|
||||
processReaperExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
int exitcode = waitForProcessExit(pid);
|
||||
UNIXProcess.this.processExited(exitcode);
|
||||
}});
|
||||
}
|
||||
|
||||
void processExited(int exitcode) {
|
||||
synchronized (this) {
|
||||
this.exitcode = exitcode;
|
||||
hasExited = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
if (stdout instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stdout).processExited();
|
||||
|
||||
if (stderr instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stderr).processExited();
|
||||
|
||||
if (stdin instanceof ProcessPipeOutputStream)
|
||||
((ProcessPipeOutputStream) stdin).processExited();
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return stdin;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return stderr;
|
||||
}
|
||||
|
||||
public synchronized int waitFor() throws InterruptedException {
|
||||
while (!hasExited) {
|
||||
wait();
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean waitFor(long timeout, TimeUnit unit)
|
||||
throws InterruptedException
|
||||
{
|
||||
if (hasExited) return true;
|
||||
if (timeout <= 0) return false;
|
||||
|
||||
long timeoutAsNanos = unit.toNanos(timeout);
|
||||
long startTime = System.nanoTime();
|
||||
long rem = timeoutAsNanos;
|
||||
|
||||
while (!hasExited && (rem > 0)) {
|
||||
wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
|
||||
rem = timeoutAsNanos - (System.nanoTime() - startTime);
|
||||
}
|
||||
return hasExited;
|
||||
}
|
||||
|
||||
public synchronized int exitValue() {
|
||||
if (!hasExited) {
|
||||
throw new IllegalThreadStateException("process hasn't exited");
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
private static native void destroyProcess(int pid, boolean force);
|
||||
private void destroy(boolean force) {
|
||||
// There is a risk that pid will be recycled, causing us to
|
||||
// kill the wrong process! So we only terminate processes
|
||||
// that appear to still be running. Even with this check,
|
||||
// there is an unavoidable race condition here, but the window
|
||||
// is very small, and OSes try hard to not recycle pids too
|
||||
// soon, so this is quite safe.
|
||||
synchronized (this) {
|
||||
if (!hasExited)
|
||||
destroyProcess(pid, force);
|
||||
}
|
||||
try { stdin.close(); } catch (IOException ignored) {}
|
||||
try { stdout.close(); } catch (IOException ignored) {}
|
||||
try { stderr.close(); } catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
destroy(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process destroyForcibly() {
|
||||
destroy(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAlive() {
|
||||
return !hasExited;
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered input stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*
|
||||
* This is tricky because we do not want the user-level InputStream to be
|
||||
* closed until the user invokes close(), and we need to continue to be
|
||||
* able to read any buffered data lingering in the OS pipe buffer.
|
||||
*/
|
||||
static class ProcessPipeInputStream extends BufferedInputStream {
|
||||
private final Object closeLock = new Object();
|
||||
|
||||
ProcessPipeInputStream(int fd) {
|
||||
super(new FileInputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
private static byte[] drainInputStream(InputStream in)
|
||||
throws IOException {
|
||||
int n = 0;
|
||||
int j;
|
||||
byte[] a = null;
|
||||
while ((j = in.available()) > 0) {
|
||||
a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
|
||||
n += in.read(a, n, j);
|
||||
}
|
||||
return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
synchronized (closeLock) {
|
||||
try {
|
||||
InputStream in = this.in;
|
||||
// this stream is closed if and only if: in == null
|
||||
if (in != null) {
|
||||
byte[] stragglers = drainInputStream(in);
|
||||
in.close();
|
||||
this.in = (stragglers == null) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ByteArrayInputStream(stragglers);
|
||||
}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// BufferedInputStream#close() is not synchronized unlike most other methods.
|
||||
// Synchronizing helps avoid race with processExited().
|
||||
synchronized (closeLock) {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered output stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*/
|
||||
static class ProcessPipeOutputStream extends BufferedOutputStream {
|
||||
ProcessPipeOutputStream(int fd) {
|
||||
super(new FileOutputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
OutputStream out = this.out;
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {
|
||||
// We know of no reason to get an IOException, but if
|
||||
// we do, there's nothing else to do but carry on.
|
||||
}
|
||||
this.out = ProcessBuilder.NullOutputStream.INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,410 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.security.AccessController;
|
||||
import static java.security.AccessController.doPrivileged;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
/**
|
||||
* java.lang.Process subclass in the UNIX environment.
|
||||
*
|
||||
* @author Mario Wolczko and Ross Knippel.
|
||||
* @author Konstantin Kladko (ported to Linux)
|
||||
* @author Martin Buchholz
|
||||
*/
|
||||
final class UNIXProcess extends Process {
|
||||
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
|
||||
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
private final int pid;
|
||||
private int exitcode;
|
||||
private boolean hasExited;
|
||||
|
||||
private /* final */ OutputStream stdin;
|
||||
private /* final */ InputStream stdout;
|
||||
private /* final */ InputStream stderr;
|
||||
|
||||
private static enum LaunchMechanism {
|
||||
FORK(1),
|
||||
VFORK(3);
|
||||
|
||||
private int value;
|
||||
LaunchMechanism(int x) {value = x;}
|
||||
};
|
||||
|
||||
/* default is VFORK on Linux */
|
||||
private static final LaunchMechanism launchMechanism;
|
||||
private static byte[] helperpath;
|
||||
|
||||
private static byte[] toCString(String s) {
|
||||
if (s == null)
|
||||
return null;
|
||||
byte[] bytes = s.getBytes();
|
||||
byte[] result = new byte[bytes.length + 1];
|
||||
System.arraycopy(bytes, 0,
|
||||
result, 0,
|
||||
bytes.length);
|
||||
result[result.length-1] = (byte)0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static {
|
||||
launchMechanism = AccessController.doPrivileged(
|
||||
new PrivilegedAction<LaunchMechanism>()
|
||||
{
|
||||
public LaunchMechanism run() {
|
||||
String javahome = System.getProperty("java.home");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
|
||||
helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
|
||||
String s = System.getProperty(
|
||||
"jdk.lang.Process.launchMechanism", "vfork");
|
||||
|
||||
try {
|
||||
return LaunchMechanism.valueOf(s.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new Error(s + " is not a supported " +
|
||||
"process launch mechanism on this platform.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* this is for the reaping thread */
|
||||
private native int waitForProcessExit(int pid);
|
||||
|
||||
/**
|
||||
* Create a process. Depending on the mode flag, this is done by
|
||||
* one of the following mechanisms.
|
||||
* - fork(2) and exec(2)
|
||||
* - clone(2) and exec(2)
|
||||
* - vfork(2) and exec(2)
|
||||
*
|
||||
* @param fds an array of three file descriptors.
|
||||
* Indexes 0, 1, and 2 correspond to standard input,
|
||||
* standard output and standard error, respectively. On
|
||||
* input, a value of -1 means to create a pipe to connect
|
||||
* child and parent processes. On output, a value which
|
||||
* is not -1 is the parent pipe fd corresponding to the
|
||||
* pipe which has been created. An element of this array
|
||||
* is -1 on input if and only if it is <em>not</em> -1 on
|
||||
* output.
|
||||
* @return the pid of the subprocess
|
||||
*/
|
||||
private native int forkAndExec(int mode, byte[] helperpath,
|
||||
byte[] prog,
|
||||
byte[] argBlock, int argc,
|
||||
byte[] envBlock, int envc,
|
||||
byte[] dir,
|
||||
int[] fds,
|
||||
boolean redirectErrorStream)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* The thread factory used to create "process reaper" daemon threads.
|
||||
*/
|
||||
private static class ProcessReaperThreadFactory implements ThreadFactory {
|
||||
private final static ThreadGroup group = getRootThreadGroup();
|
||||
|
||||
private static ThreadGroup getRootThreadGroup() {
|
||||
return doPrivileged(new PrivilegedAction<ThreadGroup> () {
|
||||
public ThreadGroup run() {
|
||||
ThreadGroup root = Thread.currentThread().getThreadGroup();
|
||||
while (root.getParent() != null)
|
||||
root = root.getParent();
|
||||
return root;
|
||||
}});
|
||||
}
|
||||
|
||||
public Thread newThread(Runnable grimReaper) {
|
||||
// Our thread stack requirement is quite modest.
|
||||
Thread t = new Thread(group, grimReaper, "process reaper", 32768);
|
||||
t.setDaemon(true);
|
||||
// A small attempt (probably futile) to avoid priority inversion
|
||||
t.setPriority(Thread.MAX_PRIORITY);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The thread pool of "process reaper" daemon threads.
|
||||
*/
|
||||
private static final Executor processReaperExecutor =
|
||||
doPrivileged(new PrivilegedAction<Executor>() {
|
||||
public Executor run() {
|
||||
return Executors.newCachedThreadPool
|
||||
(new ProcessReaperThreadFactory());
|
||||
}});
|
||||
|
||||
UNIXProcess(final byte[] prog,
|
||||
final byte[] argBlock, final int argc,
|
||||
final byte[] envBlock, final int envc,
|
||||
final byte[] dir,
|
||||
final int[] fds,
|
||||
final boolean redirectErrorStream)
|
||||
throws IOException {
|
||||
|
||||
pid = forkAndExec(launchMechanism.value,
|
||||
helperpath,
|
||||
prog,
|
||||
argBlock, argc,
|
||||
envBlock, envc,
|
||||
dir,
|
||||
fds,
|
||||
redirectErrorStream);
|
||||
|
||||
try {
|
||||
doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws IOException {
|
||||
initStreams(fds);
|
||||
return null;
|
||||
}});
|
||||
} catch (PrivilegedActionException ex) {
|
||||
throw (IOException) ex.getException();
|
||||
}
|
||||
}
|
||||
|
||||
static FileDescriptor newFileDescriptor(int fd) {
|
||||
FileDescriptor fileDescriptor = new FileDescriptor();
|
||||
fdAccess.set(fileDescriptor, fd);
|
||||
return fileDescriptor;
|
||||
}
|
||||
|
||||
void initStreams(int[] fds) throws IOException {
|
||||
stdin = (fds[0] == -1) ?
|
||||
ProcessBuilder.NullOutputStream.INSTANCE :
|
||||
new ProcessPipeOutputStream(fds[0]);
|
||||
|
||||
stdout = (fds[1] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[1]);
|
||||
|
||||
stderr = (fds[2] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[2]);
|
||||
|
||||
processReaperExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
int exitcode = waitForProcessExit(pid);
|
||||
UNIXProcess.this.processExited(exitcode);
|
||||
}});
|
||||
}
|
||||
|
||||
void processExited(int exitcode) {
|
||||
synchronized (this) {
|
||||
this.exitcode = exitcode;
|
||||
hasExited = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
if (stdout instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stdout).processExited();
|
||||
|
||||
if (stderr instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stderr).processExited();
|
||||
|
||||
if (stdin instanceof ProcessPipeOutputStream)
|
||||
((ProcessPipeOutputStream) stdin).processExited();
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return stdin;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return stderr;
|
||||
}
|
||||
|
||||
public synchronized int waitFor() throws InterruptedException {
|
||||
while (!hasExited) {
|
||||
wait();
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean waitFor(long timeout, TimeUnit unit)
|
||||
throws InterruptedException
|
||||
{
|
||||
if (hasExited) return true;
|
||||
if (timeout <= 0) return false;
|
||||
|
||||
long timeoutAsNanos = unit.toNanos(timeout);
|
||||
long startTime = System.nanoTime();
|
||||
long rem = timeoutAsNanos;
|
||||
|
||||
while (!hasExited && (rem > 0)) {
|
||||
wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
|
||||
rem = timeoutAsNanos - (System.nanoTime() - startTime);
|
||||
}
|
||||
return hasExited;
|
||||
}
|
||||
|
||||
public synchronized int exitValue() {
|
||||
if (!hasExited) {
|
||||
throw new IllegalThreadStateException("process hasn't exited");
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
private static native void destroyProcess(int pid, boolean force);
|
||||
private void destroy(boolean force) {
|
||||
// There is a risk that pid will be recycled, causing us to
|
||||
// kill the wrong process! So we only terminate processes
|
||||
// that appear to still be running. Even with this check,
|
||||
// there is an unavoidable race condition here, but the window
|
||||
// is very small, and OSes try hard to not recycle pids too
|
||||
// soon, so this is quite safe.
|
||||
synchronized (this) {
|
||||
if (!hasExited)
|
||||
destroyProcess(pid, force);
|
||||
}
|
||||
try { stdin.close(); } catch (IOException ignored) {}
|
||||
try { stdout.close(); } catch (IOException ignored) {}
|
||||
try { stderr.close(); } catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
destroy(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process destroyForcibly() {
|
||||
destroy(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAlive() {
|
||||
return !hasExited;
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered input stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*
|
||||
* This is tricky because we do not want the user-level InputStream to be
|
||||
* closed until the user invokes close(), and we need to continue to be
|
||||
* able to read any buffered data lingering in the OS pipe buffer.
|
||||
*/
|
||||
static class ProcessPipeInputStream extends BufferedInputStream {
|
||||
private final Object closeLock = new Object();
|
||||
|
||||
ProcessPipeInputStream(int fd) {
|
||||
super(new FileInputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
private static byte[] drainInputStream(InputStream in)
|
||||
throws IOException {
|
||||
int n = 0;
|
||||
int j;
|
||||
byte[] a = null;
|
||||
while ((j = in.available()) > 0) {
|
||||
a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
|
||||
n += in.read(a, n, j);
|
||||
}
|
||||
return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
synchronized (closeLock) {
|
||||
try {
|
||||
InputStream in = this.in;
|
||||
// this stream is closed if and only if: in == null
|
||||
if (in != null) {
|
||||
byte[] stragglers = drainInputStream(in);
|
||||
in.close();
|
||||
this.in = (stragglers == null) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ByteArrayInputStream(stragglers);
|
||||
}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// BufferedInputStream#close() is not synchronized unlike most other methods.
|
||||
// Synchronizing helps avoid race with processExited().
|
||||
synchronized (closeLock) {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered output stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*/
|
||||
static class ProcessPipeOutputStream extends BufferedOutputStream {
|
||||
ProcessPipeOutputStream(int fd) {
|
||||
super(new FileOutputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
OutputStream out = this.out;
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {
|
||||
// We know of no reason to get an IOException, but if
|
||||
// we do, there's nothing else to do but carry on.
|
||||
}
|
||||
this.out = ProcessBuilder.NullOutputStream.INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,395 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/* java.lang.Process subclass in the UNIX environment.
|
||||
*
|
||||
* @author Mario Wolczko and Ross Knippel.
|
||||
*/
|
||||
|
||||
final class UNIXProcess extends Process {
|
||||
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
|
||||
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
private final int pid;
|
||||
private int exitcode;
|
||||
private boolean hasExited;
|
||||
|
||||
private OutputStream stdin_stream;
|
||||
private InputStream stdout_stream;
|
||||
private DeferredCloseInputStream stdout_inner_stream;
|
||||
private InputStream stderr_stream;
|
||||
|
||||
private static enum LaunchMechanism {
|
||||
FORK(1),
|
||||
POSIX_SPAWN(2);
|
||||
|
||||
private int value;
|
||||
LaunchMechanism(int x) {value = x;}
|
||||
};
|
||||
|
||||
/* On Solaris, the default is to spawn */
|
||||
private static final LaunchMechanism launchMechanism;
|
||||
private static byte[] helperpath;
|
||||
|
||||
private static byte[] toCString(String s) {
|
||||
if (s == null)
|
||||
return null;
|
||||
byte[] bytes = s.getBytes();
|
||||
byte[] result = new byte[bytes.length + 1];
|
||||
System.arraycopy(bytes, 0,
|
||||
result, 0,
|
||||
bytes.length);
|
||||
result[result.length-1] = (byte)0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static {
|
||||
launchMechanism = AccessController.doPrivileged(
|
||||
new PrivilegedAction<LaunchMechanism>()
|
||||
{
|
||||
public LaunchMechanism run() {
|
||||
String javahome = System.getProperty("java.home");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
if (osArch.equals("x86")) {
|
||||
osArch = "i386";
|
||||
} else if (osArch.equals("x86_64")) {
|
||||
osArch = "amd64";
|
||||
}
|
||||
|
||||
helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
|
||||
String s = System.getProperty(
|
||||
"jdk.lang.Process.launchMechanism", "posix_spawn");
|
||||
|
||||
try {
|
||||
return LaunchMechanism.valueOf(s.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new Error(s + " is not a supported " +
|
||||
"process launch mechanism on this platform.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* this is for the reaping thread */
|
||||
private native int waitForProcessExit(int pid);
|
||||
|
||||
/**
|
||||
* Create a process. Depending on the mode flag, this is done by
|
||||
* one of the following mechanisms.
|
||||
* - fork(2) and exec(2)
|
||||
* - posix_spawn(2)
|
||||
*
|
||||
* @param std_fds array of file descriptors. Indexes 0, 1, and
|
||||
* 2 correspond to standard input, standard output and
|
||||
* standard error, respectively. On input, a value of -1
|
||||
* means to create a pipe to connect child and parent
|
||||
* processes. On output, a value which is not -1 is the
|
||||
* parent pipe fd corresponding to the pipe which has
|
||||
* been created. An element of this array is -1 on input
|
||||
* if and only if it is <em>not</em> -1 on output.
|
||||
* @return the pid of the subprocess
|
||||
*/
|
||||
private native int forkAndExec(int mode, byte[] helperpath,
|
||||
byte[] prog,
|
||||
byte[] argBlock, int argc,
|
||||
byte[] envBlock, int envc,
|
||||
byte[] dir,
|
||||
int[] std_fds,
|
||||
boolean redirectErrorStream)
|
||||
throws IOException;
|
||||
|
||||
UNIXProcess(final byte[] prog,
|
||||
final byte[] argBlock, int argc,
|
||||
final byte[] envBlock, int envc,
|
||||
final byte[] dir,
|
||||
final int[] std_fds,
|
||||
final boolean redirectErrorStream)
|
||||
throws IOException {
|
||||
pid = forkAndExec(launchMechanism.value,
|
||||
helperpath,
|
||||
prog,
|
||||
argBlock, argc,
|
||||
envBlock, envc,
|
||||
dir,
|
||||
std_fds,
|
||||
redirectErrorStream);
|
||||
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() { public Void run() {
|
||||
if (std_fds[0] == -1)
|
||||
stdin_stream = ProcessBuilder.NullOutputStream.INSTANCE;
|
||||
else {
|
||||
FileDescriptor stdin_fd = new FileDescriptor();
|
||||
fdAccess.set(stdin_fd, std_fds[0]);
|
||||
stdin_stream = new BufferedOutputStream(
|
||||
new FileOutputStream(stdin_fd));
|
||||
}
|
||||
|
||||
if (std_fds[1] == -1)
|
||||
stdout_stream = ProcessBuilder.NullInputStream.INSTANCE;
|
||||
else {
|
||||
FileDescriptor stdout_fd = new FileDescriptor();
|
||||
fdAccess.set(stdout_fd, std_fds[1]);
|
||||
stdout_inner_stream = new DeferredCloseInputStream(stdout_fd);
|
||||
stdout_stream = new BufferedInputStream(stdout_inner_stream);
|
||||
}
|
||||
|
||||
if (std_fds[2] == -1)
|
||||
stderr_stream = ProcessBuilder.NullInputStream.INSTANCE;
|
||||
else {
|
||||
FileDescriptor stderr_fd = new FileDescriptor();
|
||||
fdAccess.set(stderr_fd, std_fds[2]);
|
||||
stderr_stream = new DeferredCloseInputStream(stderr_fd);
|
||||
}
|
||||
|
||||
return null; }});
|
||||
|
||||
/*
|
||||
* For each subprocess forked a corresponding reaper thread
|
||||
* is started. That thread is the only thread which waits
|
||||
* for the subprocess to terminate and it doesn't hold any
|
||||
* locks while doing so. This design allows waitFor() and
|
||||
* exitStatus() to be safely executed in parallel (and they
|
||||
* need no native code).
|
||||
*/
|
||||
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() { public Void run() {
|
||||
Thread t = new Thread("process reaper") {
|
||||
public void run() {
|
||||
int res = waitForProcessExit(pid);
|
||||
synchronized (UNIXProcess.this) {
|
||||
hasExited = true;
|
||||
exitcode = res;
|
||||
UNIXProcess.this.notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
return null; }});
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return stdin_stream;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return stdout_stream;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return stderr_stream;
|
||||
}
|
||||
|
||||
public synchronized int waitFor() throws InterruptedException {
|
||||
while (!hasExited) {
|
||||
wait();
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean waitFor(long timeout, TimeUnit unit)
|
||||
throws InterruptedException
|
||||
{
|
||||
if (hasExited) return true;
|
||||
if (timeout <= 0) return false;
|
||||
|
||||
long timeoutAsNanos = unit.toNanos(timeout);
|
||||
long startTime = System.nanoTime();
|
||||
long rem = timeoutAsNanos;
|
||||
|
||||
while (!hasExited && (rem > 0)) {
|
||||
wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
|
||||
rem = timeoutAsNanos - (System.nanoTime() - startTime);
|
||||
}
|
||||
return hasExited;
|
||||
}
|
||||
|
||||
public synchronized int exitValue() {
|
||||
if (!hasExited) {
|
||||
throw new IllegalThreadStateException("process hasn't exited");
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
private static native void destroyProcess(int pid, boolean force);
|
||||
private synchronized void destroy(boolean force) {
|
||||
// There is a risk that pid will be recycled, causing us to
|
||||
// kill the wrong process! So we only terminate processes
|
||||
// that appear to still be running. Even with this check,
|
||||
// there is an unavoidable race condition here, but the window
|
||||
// is very small, and OSes try hard to not recycle pids too
|
||||
// soon, so this is quite safe.
|
||||
if (!hasExited)
|
||||
destroyProcess(pid, force);
|
||||
try {
|
||||
stdin_stream.close();
|
||||
if (stdout_inner_stream != null)
|
||||
stdout_inner_stream.closeDeferred(stdout_stream);
|
||||
if (stderr_stream instanceof DeferredCloseInputStream)
|
||||
((DeferredCloseInputStream) stderr_stream)
|
||||
.closeDeferred(stderr_stream);
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
destroy(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process destroyForcibly() {
|
||||
destroy(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAlive() {
|
||||
return !hasExited;
|
||||
}
|
||||
|
||||
// A FileInputStream that supports the deferment of the actual close
|
||||
// operation until the last pending I/O operation on the stream has
|
||||
// finished. This is required on Solaris because we must close the stdin
|
||||
// and stdout streams in the destroy method in order to reclaim the
|
||||
// underlying file descriptors. Doing so, however, causes any thread
|
||||
// currently blocked in a read on one of those streams to receive an
|
||||
// IOException("Bad file number"), which is incompatible with historical
|
||||
// behavior. By deferring the close we allow any pending reads to see -1
|
||||
// (EOF) as they did before.
|
||||
//
|
||||
private static class DeferredCloseInputStream
|
||||
extends FileInputStream
|
||||
{
|
||||
|
||||
private DeferredCloseInputStream(FileDescriptor fd) {
|
||||
super(fd);
|
||||
}
|
||||
|
||||
private Object lock = new Object(); // For the following fields
|
||||
private boolean closePending = false;
|
||||
private int useCount = 0;
|
||||
private InputStream streamToClose;
|
||||
|
||||
private void raise() {
|
||||
synchronized (lock) {
|
||||
useCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void lower() throws IOException {
|
||||
synchronized (lock) {
|
||||
useCount--;
|
||||
if (useCount == 0 && closePending) {
|
||||
streamToClose.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stc is the actual stream to be closed; it might be this object, or
|
||||
// it might be an upstream object for which this object is downstream.
|
||||
//
|
||||
private void closeDeferred(InputStream stc) throws IOException {
|
||||
synchronized (lock) {
|
||||
if (useCount == 0) {
|
||||
stc.close();
|
||||
} else {
|
||||
closePending = true;
|
||||
streamToClose = stc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
synchronized (lock) {
|
||||
useCount = 0;
|
||||
closePending = false;
|
||||
}
|
||||
super.close();
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read();
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read(b);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.read(b, off, len);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
public long skip(long n) throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.skip(n);
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
raise();
|
||||
try {
|
||||
return super.available();
|
||||
} finally {
|
||||
lower();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
static {
|
||||
init();
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,14 +24,14 @@
|
||||
*/
|
||||
package sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.AttachOperationFailedException;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
|
||||
/*
|
||||
* Bsd implementation of HotSpotVirtualMachine
|
||||
@ -191,6 +191,8 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine {
|
||||
}
|
||||
|
||||
if (completionStatus != 0) {
|
||||
// read from the stream and use that as the error message
|
||||
String message = readErrorMessage(sis);
|
||||
sis.close();
|
||||
|
||||
// In the event of a protocol mismatch then the target VM
|
||||
@ -205,7 +207,11 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine {
|
||||
if (cmd.equals("load")) {
|
||||
throw new AgentLoadException("Failed to load agent library");
|
||||
} else {
|
||||
throw new IOException("Command failed in target VM");
|
||||
if (message == null) {
|
||||
throw new AttachOperationFailedException("Command failed in target VM");
|
||||
} else {
|
||||
throw new AttachOperationFailedException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,8 +243,9 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine {
|
||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0)
|
||||
} else if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BsdVirtualMachine.read(s, bs, off, len);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,14 +24,14 @@
|
||||
*/
|
||||
package sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.AttachOperationFailedException;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
|
||||
/*
|
||||
* Linux implementation of HotSpotVirtualMachine
|
||||
@ -207,6 +207,8 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
|
||||
}
|
||||
|
||||
if (completionStatus != 0) {
|
||||
// read from the stream and use that as the error message
|
||||
String message = readErrorMessage(sis);
|
||||
sis.close();
|
||||
|
||||
// In the event of a protocol mismatch then the target VM
|
||||
@ -221,7 +223,11 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
|
||||
if (cmd.equals("load")) {
|
||||
throw new AgentLoadException("Failed to load agent library");
|
||||
} else {
|
||||
throw new IOException("Command failed in target VM");
|
||||
if (message == null) {
|
||||
throw new AttachOperationFailedException("Command failed in target VM");
|
||||
} else {
|
||||
throw new AttachOperationFailedException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,15 +24,15 @@
|
||||
*/
|
||||
package sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.AttachOperationFailedException;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Properties;
|
||||
|
||||
/*
|
||||
* Solaris implementation of HotSpotVirtualMachine.
|
||||
@ -147,11 +147,17 @@ public class SolarisVirtualMachine extends HotSpotVirtualMachine {
|
||||
// If non-0 it means an error but we need to special-case the
|
||||
// "load" command to ensure that the right exception is thrown.
|
||||
if (completionStatus != 0) {
|
||||
// read from the stream and use that as the error message
|
||||
String message = readErrorMessage(sis);
|
||||
sis.close();
|
||||
if (cmd.equals("load")) {
|
||||
throw new AgentLoadException("Failed to load agent library");
|
||||
} else {
|
||||
throw new IOException("Command failed in target VM");
|
||||
if (message == null) {
|
||||
throw new AttachOperationFailedException("Command failed in target VM");
|
||||
} else {
|
||||
throw new AttachOperationFailedException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -200,14 +200,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_BsdVirtualMachine_read
|
||||
len = remaining;
|
||||
}
|
||||
|
||||
RESTARTABLE(read(fd, buf+off, len), n);
|
||||
RESTARTABLE(read(fd, buf, len), n);
|
||||
if (n == -1) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "read");
|
||||
} else {
|
||||
if (n == 0) {
|
||||
n = -1; // EOF
|
||||
} else {
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off));
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
|
||||
}
|
||||
}
|
||||
return n;
|
||||
|
||||
@ -418,14 +418,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_LinuxVirtualMachine_read
|
||||
len = remaining;
|
||||
}
|
||||
|
||||
RESTARTABLE(read(fd, buf+off, len), n);
|
||||
RESTARTABLE(read(fd, buf, len), n);
|
||||
if (n == -1) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "read");
|
||||
} else {
|
||||
if (n == 0) {
|
||||
n = -1; // EOF
|
||||
} else {
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off));
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
|
||||
}
|
||||
}
|
||||
return n;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -161,14 +161,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_SolarisVirtualMachine_read
|
||||
len = remaining;
|
||||
}
|
||||
|
||||
RESTARTABLE(read(fd, buf+off, len), n);
|
||||
RESTARTABLE(read(fd, buf, len), n);
|
||||
if (n == -1) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "read");
|
||||
} else {
|
||||
if (n == 0) {
|
||||
n = -1; // EOF
|
||||
} else {
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off));
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
|
||||
}
|
||||
}
|
||||
return n;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,15 +24,15 @@
|
||||
*/
|
||||
package sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.AttachOperationFailedException;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
|
||||
import sun.tools.attach.HotSpotVirtualMachine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
public class WindowsVirtualMachine extends HotSpotVirtualMachine {
|
||||
@ -105,11 +105,17 @@ public class WindowsVirtualMachine extends HotSpotVirtualMachine {
|
||||
// read completion status
|
||||
int status = readInt(is);
|
||||
if (status != 0) {
|
||||
// read from the stream and use that as the error message
|
||||
String message = readErrorMessage(is);
|
||||
// special case the load command so that the right exception is thrown
|
||||
if (cmd.equals("load")) {
|
||||
throw new AgentLoadException("Failed to load agent library");
|
||||
} else {
|
||||
throw new IOException("Command failed in target VM");
|
||||
if (message == null) {
|
||||
throw new AttachOperationFailedException("Command failed in target VM");
|
||||
} else {
|
||||
throw new AttachOperationFailedException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
jdk/src/windows/lib/security/java.policy
Normal file
3
jdk/src/windows/lib/security/java.policy
Normal file
@ -0,0 +1,3 @@
|
||||
grant codeBase "file:${java.home}/lib/ext/sunmscapi.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
@ -343,7 +343,7 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_WindowsVirtualMachine_readPipe
|
||||
if (nread == 0) {
|
||||
return (jint)-1; // EOF
|
||||
} else {
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)nread, (jbyte *)(buf+off));
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)nread, (jbyte *)(buf));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -97,7 +97,8 @@ jdk_io = \
|
||||
|
||||
jdk_nio = \
|
||||
java/nio \
|
||||
sun/nio
|
||||
sun/nio \
|
||||
jdk/nio
|
||||
|
||||
jdk_net = \
|
||||
java/net \
|
||||
@ -203,7 +204,6 @@ jdk_other = \
|
||||
com/sun/jndi \
|
||||
com/sun/corba \
|
||||
lib/testlibrary \
|
||||
jdk/nio/zipfs \
|
||||
sample
|
||||
|
||||
#
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
* @bug 8028994
|
||||
* @author Staffan Larsen
|
||||
* @library /lib/testlibrary
|
||||
* @build jdk.testlibrary.*
|
||||
* @run main CheckOrigin
|
||||
*/
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ import jdk.testlibrary.ProcessThread;
|
||||
* @bug 6173612 6273707 6277253 6335921 6348630 6342019 6381757
|
||||
* @summary Basic unit tests for the VM attach mechanism.
|
||||
* @library /lib/testlibrary
|
||||
* @run build Agent BadAgent RedefineAgent Application Shutdown RedefineDummy RunnerUtil
|
||||
* @run build jdk.testlibrary.* Agent BadAgent RedefineAgent Application Shutdown RedefineDummy RunnerUtil
|
||||
* @run main BasicTests
|
||||
*
|
||||
* This test will perform a number of basic attach tests.
|
||||
|
||||
@ -34,7 +34,7 @@ import jdk.testlibrary.ProcessThread;
|
||||
* @bug 6173612 6273707 6277253 6335921 6348630 6342019 6381757
|
||||
* @summary Basic unit tests for the VM attach mechanism.
|
||||
* @library /lib/testlibrary
|
||||
* @run build Application Shutdown
|
||||
* @run build jdk.testlibrary.* Application Shutdown
|
||||
* @run main PermissionTest
|
||||
*
|
||||
* Unit test for Attach API -
|
||||
|
||||
@ -33,7 +33,7 @@ import com.sun.tools.attach.spi.AttachProvider;
|
||||
* @bug 6173612 6273707 6277253 6335921 6348630 6342019 6381757
|
||||
* @summary Basic unit tests for the VM attach mechanism.
|
||||
* @library /lib/testlibrary
|
||||
* @run build SimpleProvider
|
||||
* @run build jdk.testlibrary.* SimpleProvider
|
||||
* @run main ProviderTest
|
||||
*
|
||||
* The test will attach and detach to/from the running Application.
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
* @summary BufferedInputStream calculates negative array size with large
|
||||
* streams and mark
|
||||
* @library /lib/testlibrary
|
||||
* @build jdk.testlibrary.*
|
||||
* @run main/othervm LargeCopyWithMark
|
||||
*/
|
||||
|
||||
|
||||
@ -54,9 +54,6 @@ public class SecurityManagerClinit {
|
||||
System.getProperty("java.home") +
|
||||
File.separator + "bin" + File.separator + "java";
|
||||
|
||||
// A funky contrived security setup, just for bug repro purposes.
|
||||
java.security.Security.setProperty("package.access", "java.util");
|
||||
|
||||
final Policy policy =
|
||||
new Policy
|
||||
(new FilePermission("<<ALL FILES>>", "execute"),
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
@test
|
||||
@bug 4217441 4533872 4900935 8020037 8032012
|
||||
@bug 4217441 4533872 4900935 8020037 8032012 8041791
|
||||
@summary toLowerCase should lower-case Greek Sigma correctly depending
|
||||
on the context (final/non-final). Also it should handle
|
||||
Locale specific (lt, tr, and az) lowercasings and supplementary
|
||||
@ -72,8 +72,10 @@ public class ToLowerCase {
|
||||
// I-dot tests
|
||||
test("\u0130", turkish, "i");
|
||||
test("\u0130", az, "i");
|
||||
test("\u0130", lt, "i");
|
||||
test("\u0130", Locale.US, "i");
|
||||
test("\u0130", lt, "\u0069\u0307");
|
||||
test("\u0130", Locale.US, "\u0069\u0307");
|
||||
test("\u0130", Locale.JAPAN, "\u0069\u0307");
|
||||
test("\u0130", Locale.ROOT, "\u0069\u0307");
|
||||
|
||||
// Remove dot_above in the sequence I + dot_above (Turkish and Azeri)
|
||||
test("I\u0307", turkish, "i");
|
||||
@ -111,6 +113,12 @@ public class ToLowerCase {
|
||||
if (cp >= Character.MIN_HIGH_SURROGATE && cp <= Character.MAX_HIGH_SURROGATE) {
|
||||
continue;
|
||||
}
|
||||
if (cp == 0x0130) {
|
||||
// Although UnicodeData.txt has the lower case char as \u0069, it should be
|
||||
// handled with the rules in SpecialCasing.txt, i.e., \u0069\u0307 in
|
||||
// non Turkic locales.
|
||||
continue;
|
||||
}
|
||||
int lowerCase = Character.toLowerCase(cp);
|
||||
if (lowerCase == -1) { //Character.ERROR
|
||||
continue;
|
||||
|
||||
@ -30,7 +30,7 @@ import jdk.testlibrary.Utils;
|
||||
* @bug 6289149
|
||||
* @summary test when the agent's class is missing the premain() function.
|
||||
* @library /lib/testlibrary
|
||||
* @run build DummyMain
|
||||
* @run build jdk.testlibrary.* DummyMain
|
||||
* @run shell ../MakeJAR3.sh NoPremainAgent
|
||||
* @run main NoPremainAgentTest
|
||||
*/
|
||||
|
||||
@ -30,7 +30,7 @@ import jdk.testlibrary.Utils;
|
||||
* @bug 5055293
|
||||
* @summary Test non ascii characters in the Premain-Class attribute.
|
||||
* @library /lib/testlibrary
|
||||
* @run build DummyMain
|
||||
* @run build jdk.testlibrary.* DummyMain
|
||||
* @run main PremainClassTest
|
||||
*/
|
||||
public class PremainClassTest {
|
||||
|
||||
@ -30,7 +30,7 @@ import jdk.testlibrary.Utils;
|
||||
* @bug 6289149
|
||||
* @summary test when the agent's class has a zero arg premain() function.
|
||||
* @library /lib/testlibrary
|
||||
* @run build DummyMain
|
||||
* @run build jdk.testlibrary.* DummyMain
|
||||
* @run shell ../MakeJAR3.sh ZeroArgPremainAgent
|
||||
* @run main ZeroArgPremainAgentTest
|
||||
*/
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
* @author Mandy Chung
|
||||
*
|
||||
* @library /lib/testlibrary/
|
||||
* @build CollectionUsageThreshold MemoryUtil RunUtil
|
||||
* @build jdk.testlibrary.* CollectionUsageThreshold MemoryUtil RunUtil
|
||||
* @run main/timeout=300 CollectionUsageThreshold
|
||||
*/
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
* @author Mandy Chung
|
||||
*
|
||||
* @library /lib/testlibrary/
|
||||
* @build LowMemoryTest MemoryUtil RunUtil
|
||||
* @build jdk.testlibrary.* LowMemoryTest MemoryUtil RunUtil
|
||||
* @run main/timeout=600 LowMemoryTest
|
||||
*/
|
||||
|
||||
|
||||
192
jdk/test/java/net/Authenticator/B8034170.java
Normal file
192
jdk/test/java/net/Authenticator/B8034170.java
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8034170
|
||||
* @summary Digest authentication interop issue
|
||||
* @run main/othervm B8034170 unquoted
|
||||
* @run main/othervm -Dhttp.auth.digest.quoteParameters=true B8034170 quoted
|
||||
*/
|
||||
|
||||
public class B8034170 {
|
||||
|
||||
static boolean expectQuotes;
|
||||
|
||||
static class BasicServer extends Thread {
|
||||
|
||||
ServerSocket server;
|
||||
|
||||
Socket s;
|
||||
InputStream is;
|
||||
OutputStream os;
|
||||
|
||||
static final String realm = "wallyworld";
|
||||
|
||||
String reply1 = "HTTP/1.1 401 Unauthorized\r\n"+
|
||||
"WWW-Authenticate: Digest realm=\""+realm+"\", qop=\"auth\"" +
|
||||
", nonce=\"8989de95ea2402b64d73cecdb15da255\"" +
|
||||
", opaque=\"bbfb4c9ee92ddccc73521c3e6e841ba2\"\r\n\r\n";
|
||||
|
||||
String OKreply = "HTTP/1.1 200 OK\r\n"+
|
||||
"Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" +
|
||||
"Server: Apache/1.3.14 (Unix)\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Content-Type: text/plain; charset=iso-8859-1\r\n" +
|
||||
"Content-Length: 10\r\n\r\n";
|
||||
|
||||
String ERRreply = "HTTP/1.1 500 Internal server error\r\n"+
|
||||
"Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" +
|
||||
"Server: Apache/1.3.14 (Unix)\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Content-Length: 0\r\n\r\n";
|
||||
|
||||
BasicServer (ServerSocket s) {
|
||||
server = s;
|
||||
}
|
||||
|
||||
int readAll (Socket s, byte[] buf) throws IOException {
|
||||
int pos = 0;
|
||||
InputStream is = s.getInputStream ();
|
||||
// wait two seconds for request, as client doesn't close
|
||||
// the connection
|
||||
s.setSoTimeout(2000);
|
||||
try {
|
||||
int n;
|
||||
while ((n=is.read(buf, pos, buf.length-pos)) > 0)
|
||||
pos +=n;
|
||||
} catch (SocketTimeoutException x) { }
|
||||
return pos;
|
||||
}
|
||||
|
||||
public void run () {
|
||||
byte[] buf = new byte[5000];
|
||||
try {
|
||||
System.out.println ("Server 1: accept");
|
||||
s = server.accept ();
|
||||
System.out.println ("accepted");
|
||||
os = s.getOutputStream();
|
||||
os.write (reply1.getBytes());
|
||||
readAll (s, buf);
|
||||
s.close ();
|
||||
|
||||
System.out.println ("Server 2: accept");
|
||||
s = server.accept ();
|
||||
System.out.println ("accepted");
|
||||
os = s.getOutputStream();
|
||||
int count = readAll (s, buf);
|
||||
String reply = new String(buf, 0, count);
|
||||
|
||||
boolean error;
|
||||
|
||||
if (expectQuotes) {
|
||||
error = false;
|
||||
if (!reply.contains("qop=\"auth\"")) {
|
||||
System.out.println ("Expecting quoted qop. Not found");
|
||||
error = true;
|
||||
}
|
||||
if (!reply.contains("algorithm=\"MD5\"")) {
|
||||
System.out.println ("Expecting quoted algorithm. Not found");
|
||||
error = true;
|
||||
}
|
||||
} else {
|
||||
error = false;
|
||||
if (!reply.contains("qop=auth")) {
|
||||
System.out.println ("Expecting unquoted qop. Not found");
|
||||
error = true;
|
||||
}
|
||||
if (!reply.contains("algorithm=MD5")) {
|
||||
System.out.println ("Expecting unquoted algorithm. Not found");
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
os.write(ERRreply.getBytes());
|
||||
os.flush();
|
||||
s.close();
|
||||
} else {
|
||||
os.write((OKreply+"HelloWorld").getBytes());
|
||||
os.flush();
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println (e);
|
||||
}
|
||||
finished ();
|
||||
}
|
||||
|
||||
public synchronized void finished () {
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MyAuthenticator3 extends Authenticator {
|
||||
PasswordAuthentication pw;
|
||||
MyAuthenticator3 () {
|
||||
super ();
|
||||
pw = new PasswordAuthentication ("user", "passwordNotCheckedAnyway".toCharArray());
|
||||
}
|
||||
|
||||
public PasswordAuthentication getPasswordAuthentication ()
|
||||
{
|
||||
System.out.println ("Auth called");
|
||||
return pw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void read (InputStream is) throws IOException {
|
||||
int c;
|
||||
System.out.println ("reading");
|
||||
while ((c=is.read()) != -1) {
|
||||
System.out.write (c);
|
||||
}
|
||||
System.out.println ("");
|
||||
System.out.println ("finished reading");
|
||||
}
|
||||
|
||||
public static void main (String args[]) throws Exception {
|
||||
expectQuotes = args[0].equals("quoted");
|
||||
|
||||
MyAuthenticator3 auth = new MyAuthenticator3 ();
|
||||
Authenticator.setDefault (auth);
|
||||
ServerSocket ss = new ServerSocket (0);
|
||||
int port = ss.getLocalPort ();
|
||||
BasicServer server = new BasicServer (ss);
|
||||
synchronized (server) {
|
||||
server.start();
|
||||
System.out.println ("client 1");
|
||||
URL url = new URL ("http://localhost:"+port+"/d1/d2/d3/foo.html");
|
||||
URLConnection urlc = url.openConnection ();
|
||||
InputStream is = urlc.getInputStream ();
|
||||
read (is);
|
||||
is.close ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,7 @@
|
||||
# @library /lib/testlibrary
|
||||
# @compile -XDignore.symbol.file=true SimpleNameService.java
|
||||
# LookupTest.java SimpleNameServiceDescriptor.java
|
||||
# @build jdk.testlibrary.Utils
|
||||
# @build jdk.testlibrary.*
|
||||
# @run shell/timeout=50 lookup.sh
|
||||
#
|
||||
|
||||
|
||||
@ -25,8 +25,6 @@
|
||||
* @test
|
||||
* @bug 8005280 8004371
|
||||
* @summary Compatibility test
|
||||
* @run main CompatibilityTest
|
||||
* @run main/othervm -Dsun.util.spi.XmlPropertiesProvider=jdk.internal.util.xml.BasicXmlPropertiesProvider CompatibilityTest
|
||||
*/
|
||||
|
||||
import java.io.FileInputStream;
|
||||
|
||||
@ -25,9 +25,6 @@
|
||||
* @bug 8005281
|
||||
* @summary Test that the Properties storeToXML and loadFromXML methods are
|
||||
* thread safe
|
||||
* @run main ConcurrentLoadAndStoreXML
|
||||
* @run main/othervm -Dsun.util.spi.XmlPropertiesProvider=jdk.internal.util.xml.BasicXmlPropertiesProvider ConcurrentLoadAndStoreXML
|
||||
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8000354
|
||||
* @summary Test
|
||||
* @compile -XDignore.symbol.file CustomProvider.java MyXmlPropertiesProvider.java
|
||||
* @run main/othervm -Dsun.util.spi.XmlPropertiesProvider=MyXmlPropertiesProvider CustomProvider
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Sanity test to verify that the property sun.util.spi.XmlPropertiesProvider
|
||||
* can be used to specify a custom provider for loading/storing properties
|
||||
* in XML format.
|
||||
*/
|
||||
public class CustomProvider {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String provider = System.getProperty("sun.util.spi.XmlPropertiesProvider");
|
||||
assertTrue(provider != null, "sun.util.spi.XmlPropertiesProvider not set");
|
||||
|
||||
OutputStream out = new ByteArrayOutputStream();
|
||||
InputStream in = new ByteArrayInputStream(new byte[100]);
|
||||
|
||||
Properties props;
|
||||
|
||||
props = new Properties();
|
||||
props.loadFromXML(in);
|
||||
|
||||
props = System.getProperties();
|
||||
props.storeToXML(out, "comment");
|
||||
props.storeToXML(out, "comment", "UTF-8");
|
||||
|
||||
// check that the provider's load and store methods have been invoked
|
||||
|
||||
assertTrue(MyXmlPropertiesProvider.createCount() == 1,
|
||||
"Provider should only be created once");
|
||||
assertTrue(MyXmlPropertiesProvider.loadCount() == 1,
|
||||
"load method expected to be called once");
|
||||
assertTrue(MyXmlPropertiesProvider.storeCount() == 2,
|
||||
"store method expected to be called twice");
|
||||
}
|
||||
|
||||
static void assertTrue(boolean b, String msg) {
|
||||
if (!b) throw new RuntimeException(msg);
|
||||
}
|
||||
}
|
||||
@ -23,16 +23,28 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8000354 8000685 8004371
|
||||
* @bug 8000354 8000685 8004371 8043119
|
||||
* @summary Basic test of storeToXML and loadToXML
|
||||
* @run main LoadAndStoreXML
|
||||
* @run main/othervm -Dsun.util.spi.XmlPropertiesProvider=jdk.internal.util.xml.BasicXmlPropertiesProvider LoadAndStoreXML
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
import java.nio.file.*;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.CodeSource;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
import java.security.Policy;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.InvalidPropertiesFormatException;
|
||||
import java.util.Properties;
|
||||
import java.util.PropertyPermission;
|
||||
|
||||
public class LoadAndStoreXML {
|
||||
|
||||
@ -65,6 +77,50 @@ public class LoadAndStoreXML {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@code ByteArrayInputStream} that allows testing if the
|
||||
* {@code close} method has been invoked.
|
||||
*/
|
||||
static class TestInputStream extends ByteArrayInputStream {
|
||||
private boolean closed;
|
||||
|
||||
TestInputStream(byte[] buf) {
|
||||
super(buf);
|
||||
}
|
||||
|
||||
boolean isOpen() {
|
||||
return !closed;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
super.close();
|
||||
} finally {
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@code ByteArrayOutputStream} that allows testing if the
|
||||
* {@code close} method has been invoked.
|
||||
*/
|
||||
static class TestOutputStream extends ByteArrayOutputStream {
|
||||
private boolean closed;
|
||||
|
||||
boolean isOpen() {
|
||||
return !closed;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
super.close();
|
||||
} finally {
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanity test that properties saved with Properties#storeToXML can be
|
||||
* read with Properties#loadFromXML.
|
||||
@ -79,12 +135,16 @@ public class LoadAndStoreXML {
|
||||
props.put("k4", "\u7532\u9aa8\u6587");
|
||||
props.put("k5", "<java.home>/lib/jaxp.properties");
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
TestOutputStream out = new TestOutputStream();
|
||||
props.storeToXML(out, null, encoding);
|
||||
if (!out.isOpen())
|
||||
throw new RuntimeException("OutputStream closed by storeToXML");
|
||||
|
||||
Properties p = new Properties();
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||
TestInputStream in = new TestInputStream(out.toByteArray());
|
||||
p.loadFromXML(in);
|
||||
if (in.isOpen())
|
||||
throw new RuntimeException("InputStream not closed by loadFromXML");
|
||||
|
||||
if (!p.equals(props)) {
|
||||
System.err.println("stored: " + props);
|
||||
|
||||
@ -35,58 +35,17 @@ import java.util.Properties;
|
||||
*/
|
||||
public class LoadAndStoreXMLWithDefaults {
|
||||
|
||||
public static enum StoreMethod {
|
||||
// Note: this case will test the default provider when available,
|
||||
// and the basic provider when it's not.
|
||||
PROPERTIES {
|
||||
@Override
|
||||
public String writeToXML(Properties p) throws IOException {
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
p.storeToXML(baos, "Test 8016344");
|
||||
return baos.toString();
|
||||
}
|
||||
@Override
|
||||
public Properties loadFromXML(String xml, Properties defaults)
|
||||
throws IOException {
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes("UTF-8"));
|
||||
Properties p = new Properties(defaults);
|
||||
p.loadFromXML(bais);
|
||||
return p;
|
||||
}
|
||||
},
|
||||
// Note: this case always test the basic provider, which is always available.
|
||||
// so sometimes it's just a dup with the previous case...
|
||||
BASICPROVIDER {
|
||||
@Override
|
||||
public String writeToXML(Properties p) throws IOException {
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
jdk.internal.util.xml.BasicXmlPropertiesProvider provider =
|
||||
new jdk.internal.util.xml.BasicXmlPropertiesProvider();
|
||||
provider.store(p, baos, "Test 8016344", "UTF-8");
|
||||
return baos.toString();
|
||||
}
|
||||
@Override
|
||||
public Properties loadFromXML(String xml, Properties defaults)
|
||||
throws IOException {
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes("UTF-8"));
|
||||
Properties p = new Properties(defaults);
|
||||
jdk.internal.util.xml.BasicXmlPropertiesProvider provider =
|
||||
new jdk.internal.util.xml.BasicXmlPropertiesProvider();
|
||||
provider.load(p, bais);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
public abstract String writeToXML(Properties p) throws IOException;
|
||||
public abstract Properties loadFromXML(String xml, Properties defaults)
|
||||
throws IOException;
|
||||
public String displayName() {
|
||||
switch(this) {
|
||||
case PROPERTIES: return "Properties.storeToXML";
|
||||
case BASICPROVIDER: return "BasicXmlPropertiesProvider.store";
|
||||
default:
|
||||
throw new UnsupportedOperationException(this.name());
|
||||
}
|
||||
}
|
||||
static String writeToXML(Properties props) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
props.storeToXML(baos, "Test 8016344");
|
||||
return baos.toString();
|
||||
}
|
||||
|
||||
static Properties loadFromXML(String xml, Properties defaults) throws IOException {
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes("UTF-8"));
|
||||
Properties props = new Properties(defaults);
|
||||
props.loadFromXML(bais);
|
||||
return props;
|
||||
}
|
||||
|
||||
static enum Objects { OBJ1, OBJ2, OBJ3 };
|
||||
@ -106,63 +65,59 @@ public class LoadAndStoreXMLWithDefaults {
|
||||
p3.setProperty("p1.and.p2.and.p3.prop", "prop9-p3");
|
||||
p3.setProperty("p2.and.p3.prop", "prop10-p3");
|
||||
|
||||
for (StoreMethod m : StoreMethod.values()) {
|
||||
System.out.println("Testing with " + m.displayName());
|
||||
Properties P1 = m.loadFromXML(m.writeToXML(p1), null);
|
||||
Properties P2 = m.loadFromXML(m.writeToXML(p2), P1);
|
||||
Properties P3 = m.loadFromXML(m.writeToXML(p3), P2);
|
||||
Properties P1 = loadFromXML(writeToXML(p1), null);
|
||||
Properties P2 = loadFromXML(writeToXML(p2), P1);
|
||||
Properties P3 = loadFromXML(writeToXML(p3), P2);
|
||||
|
||||
testResults(m, p1, P1, p2, P2, p3, P3);
|
||||
testResults(p1, P1, p2, P2, p3, P3);
|
||||
|
||||
// Now check that properties whose keys or values are objects
|
||||
// are skipped.
|
||||
// Now check that properties whose keys or values are objects
|
||||
// are skipped.
|
||||
|
||||
System.out.println("Testing with " + m.displayName() + " and Objects");
|
||||
P1.put("p1.object.prop", Objects.OBJ1);
|
||||
P1.put(Objects.OBJ1, "p1.object.prop");
|
||||
P1.put("p2.object.prop", "p2.object.prop");
|
||||
P2.put("p2.object.prop", Objects.OBJ2);
|
||||
P2.put(Objects.OBJ2, "p2.object.prop");
|
||||
P3.put("p3.object.prop", Objects.OBJ3);
|
||||
P3.put(Objects.OBJ3, "p3.object.prop");
|
||||
P1.put("p1.object.prop", Objects.OBJ1);
|
||||
P1.put(Objects.OBJ1, "p1.object.prop");
|
||||
P1.put("p2.object.prop", "p2.object.prop");
|
||||
P2.put("p2.object.prop", Objects.OBJ2);
|
||||
P2.put(Objects.OBJ2, "p2.object.prop");
|
||||
P3.put("p3.object.prop", Objects.OBJ3);
|
||||
P3.put(Objects.OBJ3, "p3.object.prop");
|
||||
|
||||
Properties PP1 = m.loadFromXML(m.writeToXML(P1), null);
|
||||
Properties PP2 = m.loadFromXML(m.writeToXML(P2), PP1);
|
||||
Properties PP3 = m.loadFromXML(m.writeToXML(P3), PP2);
|
||||
Properties PP1 = loadFromXML(writeToXML(P1), null);
|
||||
Properties PP2 = loadFromXML(writeToXML(P2), PP1);
|
||||
Properties PP3 = loadFromXML(writeToXML(P3), PP2);
|
||||
|
||||
p1.setProperty("p2.object.prop", "p2.object.prop");
|
||||
try {
|
||||
testResults(m, p1, PP1, p2, PP2, p3, PP3);
|
||||
} finally {
|
||||
p1.remove("p2.object.prop");
|
||||
}
|
||||
p1.setProperty("p2.object.prop", "p2.object.prop");
|
||||
try {
|
||||
testResults(p1, PP1, p2, PP2, p3, PP3);
|
||||
} finally {
|
||||
p1.remove("p2.object.prop");
|
||||
}
|
||||
}
|
||||
|
||||
public static void testResults(StoreMethod m, Properties... pps) {
|
||||
public static void testResults(Properties... pps) {
|
||||
for (int i=0 ; i < pps.length ; i += 2) {
|
||||
if (!pps[i].equals(pps[i+1])) {
|
||||
System.err.println(m.displayName() +": P" + (i/2+1)
|
||||
System.err.println("P" + (i/2+1)
|
||||
+ " Reloaded properties differ from original");
|
||||
System.err.println("\toriginal: " + pps[i]);
|
||||
System.err.println("\treloaded: " + pps[i+1]);
|
||||
throw new RuntimeException(m.displayName() +": P" + (i/2+1)
|
||||
throw new RuntimeException("P" + (i/2+1)
|
||||
+ " Reloaded properties differ from original");
|
||||
}
|
||||
if (!pps[i].keySet().equals(pps[i+1].keySet())) {
|
||||
System.err.println(m.displayName() +": P" + (i/2+1)
|
||||
System.err.println("P" + (i/2+1)
|
||||
+ " Reloaded property names differ from original");
|
||||
System.err.println("\toriginal: " + pps[i].keySet());
|
||||
System.err.println("\treloaded: " + pps[i+1].keySet());
|
||||
throw new RuntimeException(m.displayName() +": P" + (i/2+1)
|
||||
throw new RuntimeException("P" + (i/2+1)
|
||||
+ " Reloaded property names differ from original");
|
||||
}
|
||||
if (!pps[i].stringPropertyNames().equals(pps[i+1].stringPropertyNames())) {
|
||||
System.err.println(m.displayName() +": P" + (i/2+1)
|
||||
System.err.println("P" + (i/2+1)
|
||||
+ " Reloaded string property names differ from original");
|
||||
System.err.println("\toriginal: " + pps[i].stringPropertyNames());
|
||||
System.err.println("\treloaded: " + pps[i+1].stringPropertyNames());
|
||||
throw new RuntimeException(m.displayName() +": P" + (i/2+1)
|
||||
throw new RuntimeException("P" + (i/2+1)
|
||||
+ " Reloaded string property names differ from original");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class MyXmlPropertiesProvider
|
||||
extends sun.util.spi.XmlPropertiesProvider
|
||||
{
|
||||
private static int createCount;
|
||||
private static int loadCount;
|
||||
private static int storeCount;
|
||||
|
||||
static int createCount() { return createCount; }
|
||||
static int loadCount() { return loadCount; }
|
||||
static int storeCount() { return storeCount; }
|
||||
|
||||
public MyXmlPropertiesProvider() {
|
||||
createCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Properties props, InputStream in)
|
||||
throws IOException, InvalidPropertiesFormatException
|
||||
{
|
||||
loadCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(Properties props, OutputStream out,
|
||||
String comment, String encoding)
|
||||
throws IOException
|
||||
{
|
||||
storeCount++;
|
||||
}
|
||||
}
|
||||
@ -28,7 +28,7 @@
|
||||
* monitors are started and stopped in a loop.
|
||||
* @author Luis-Miguel Alventosa
|
||||
* @library /lib/testlibrary
|
||||
* @run build jdk.testlibrary.Utils
|
||||
* @build jdk.testlibrary.*
|
||||
* @run clean StartStopTest
|
||||
* @run build StartStopTest
|
||||
* @run main/othervm/timeout=300 StartStopTest 1
|
||||
|
||||
@ -31,8 +31,11 @@ import java.io.IOException;
|
||||
/**
|
||||
*
|
||||
* @test
|
||||
* @bug 8038500
|
||||
* @bug 8038500 8040059
|
||||
* @summary Basic test for zip provider
|
||||
*
|
||||
* @run main Basic
|
||||
* @run main/othervm/policy=test.policy Basic
|
||||
*/
|
||||
|
||||
public class Basic {
|
||||
|
||||
@ -29,8 +29,11 @@ import java.io.IOException;
|
||||
/**
|
||||
*
|
||||
* @test
|
||||
* @bug 8038500
|
||||
* @bug 8038500 8040059
|
||||
* @summary Tests path operations for zip provider.
|
||||
*
|
||||
* @run main PathOps
|
||||
* @run main/othervm/policy=test.policy.readonly PathOps
|
||||
*/
|
||||
|
||||
public class PathOps {
|
||||
|
||||
@ -22,8 +22,11 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 7156873
|
||||
@summary ZipFileSystem regression tests
|
||||
* @bug 7156873 8040059
|
||||
* @summary ZipFileSystem regression tests
|
||||
*
|
||||
* @run main ZFSTests
|
||||
* @run main/othervm/policy=test.policy ZFSTests
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@ -40,8 +40,10 @@ import static java.nio.file.StandardCopyOption.*;
|
||||
*
|
||||
* @test
|
||||
* @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
|
||||
* 7157656 8002390 7012868 7012856 8015728 8038500
|
||||
* 7157656 8002390 7012868 7012856 8015728 8038500 8040059
|
||||
* @summary Test Zip filesystem provider
|
||||
* @run main ZipFSTester
|
||||
* @run main/othervm/policy=test.policy ZipFSTester
|
||||
*/
|
||||
|
||||
public class ZipFSTester {
|
||||
|
||||
16
jdk/test/jdk/nio/zipfs/test.policy
Normal file
16
jdk/test/jdk/nio/zipfs/test.policy
Normal file
@ -0,0 +1,16 @@
|
||||
grant codeBase "file:${java.home}/lib/ext/zipfs.jar" {
|
||||
permission java.io.FilePermission "<<ALL FILES>>", "read,write";
|
||||
permission java.lang.RuntimePermission "fileSystemProvider";
|
||||
permission java.util.PropertyPermission "*", "read";
|
||||
};
|
||||
|
||||
grant codeBase "file:${java.home}/lib/ext/sunpkcs11.jar" {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*";
|
||||
};
|
||||
|
||||
grant {
|
||||
permission java.io.FilePermission "<<ALL FILES>>","read,write,delete";
|
||||
permission java.util.PropertyPermission "test.jdk","read";
|
||||
permission java.util.PropertyPermission "test.src","read";
|
||||
permission java.util.PropertyPermission "user.dir","read";
|
||||
};
|
||||
12
jdk/test/jdk/nio/zipfs/test.policy.readonly
Normal file
12
jdk/test/jdk/nio/zipfs/test.policy.readonly
Normal file
@ -0,0 +1,12 @@
|
||||
grant codeBase "file:${java.home}/lib/ext/zipfs.jar" {
|
||||
permission java.io.FilePermission "<<ALL FILES>>", "read,write";
|
||||
permission java.lang.RuntimePermission "fileSystemProvider";
|
||||
permission java.util.PropertyPermission "*", "read";
|
||||
};
|
||||
|
||||
grant {
|
||||
permission java.io.FilePermission "<<ALL FILES>>","read";
|
||||
permission java.util.PropertyPermission "test.jdk","read";
|
||||
permission java.util.PropertyPermission "test.src","read";
|
||||
permission java.util.PropertyPermission "user.dir","read";
|
||||
};
|
||||
@ -30,12 +30,24 @@ import java.io.*;
|
||||
import java.security.*;
|
||||
|
||||
public class Ext_AllPolicy {
|
||||
public static void main (String[] args) {
|
||||
FilePermission mine = new FilePermission("/tmp/bar", "read");
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
public static void main (String[] args) {
|
||||
boolean allPerms = args.length == 1 && args[0].equals("AllPermission");
|
||||
FilePermission mine = new FilePermission("/tmp/bar", "read");
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
|
||||
if (sm != null) {
|
||||
sm.checkPermission(mine);
|
||||
if (sm != null) {
|
||||
try {
|
||||
sm.checkPermission(mine);
|
||||
if (!allPerms) {
|
||||
// Default has no privilege.
|
||||
throw new RuntimeException(mine + " expected to deny access");
|
||||
}
|
||||
} catch (AccessControlException e) {
|
||||
if (allPerms) {
|
||||
// expected all permissions granted
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#
|
||||
|
||||
# @test
|
||||
# @bug 4215035
|
||||
# @bug 4215035 8040059
|
||||
# @summary standard extensions path is hard-coded in default system policy file
|
||||
#
|
||||
# @build Ext_AllPolicy
|
||||
@ -81,6 +81,9 @@ ${COMPILEJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS} -cvf Ext_AllPolicy.jar Ext_AllP
|
||||
|
||||
rm Ext_AllPolicy.class
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \
|
||||
-Djava.security.manager -Djava.ext.dirs="${TESTCLASSES}" Ext_AllPolicy
|
||||
-Djava.security.manager -Djava.ext.dirs="${TESTCLASSES}" Ext_AllPolicy || exit 10
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \
|
||||
-Djava.security.policy=${TESTSRC}${FS}test.policy \
|
||||
-Djava.security.manager -Djava.ext.dirs="${TESTCLASSES}" Ext_AllPolicy AllPermission
|
||||
exit $?
|
||||
|
||||
3
jdk/test/lib/security/java.policy/test.policy
Normal file
3
jdk/test/lib/security/java.policy/test.policy
Normal file
@ -0,0 +1,3 @@
|
||||
grant codeBase "file:${{java.ext.dirs}}/*" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
@ -41,7 +41,7 @@ import jdk.testlibrary.ProcessTools;
|
||||
* @test
|
||||
* @bug 6434402 8004926
|
||||
* @library /lib/testlibrary
|
||||
* @build jdk.testlibrary.ProcessTools
|
||||
* @build jdk.testlibrary.*
|
||||
* @build TestManager TestApplication CustomLauncherTest
|
||||
* @run main/othervm CustomLauncherTest
|
||||
* @author Jaroslav Bachorik
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -616,7 +616,7 @@ public class JMXStartStopTest {
|
||||
final boolean[] checks = new boolean[3];
|
||||
jcmd(
|
||||
line -> {
|
||||
if (line.equals("java.lang.RuntimeException: Invalid agent state")) {
|
||||
if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
|
||||
checks[0] = true;
|
||||
}
|
||||
},
|
||||
@ -627,7 +627,7 @@ public class JMXStartStopTest {
|
||||
|
||||
jcmd(
|
||||
line -> {
|
||||
if (line.equals("java.lang.RuntimeException: Invalid agent state")) {
|
||||
if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
|
||||
checks[1] = true;
|
||||
}
|
||||
},
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
* @author Robert Field
|
||||
* @library /lib/testlibrary
|
||||
* @compile -XDignore.symbol.file ManyNewInstanceAnonTest.java
|
||||
* @build jdk.testlibrary.*
|
||||
* @run main ClassFileInstaller ManyNewInstanceAnonTest
|
||||
* @run main/othervm -Xbootclasspath/a:. -Xverify:all ManyNewInstanceAnonTest
|
||||
* @run main/othervm -Xbootclasspath/a:. -Xverify:all -Dsun.reflection.noInflation=true ManyNewInstanceAnonTest
|
||||
|
||||
467
jdk/test/sun/security/validator/ConstructorTest.java
Normal file
467
jdk/test/sun/security/validator/ConstructorTest.java
Normal file
@ -0,0 +1,467 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6996377
|
||||
* @summary shrink duplicate code in the constructor of PKIXValidator
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.PKIXBuilderParameters;
|
||||
import java.security.cert.X509CertSelector;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Collection;
|
||||
import sun.security.validator.Validator;
|
||||
import sun.security.validator.PKIXValidator;
|
||||
|
||||
public class ConstructorTest {
|
||||
|
||||
// COMMON-OPTS: All certs created with the following common options:
|
||||
// -keystore <STORE> -storepass <PASS> -keypass <PASS> -keyalg rsa
|
||||
// -keysize 2048 -validity 720 -sigalg sha256withrsa
|
||||
|
||||
// keytool <COMMON-OPTS> -alias root -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String ROOT =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC3jCCAcagAwIBAgIEInKZgjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRS\n" +
|
||||
"b290MB4XDTE0MDUwODE4MjcwOFoXDTE2MDQyNzE4MjcwOFowDzENMAsGA1UEAxME\n" +
|
||||
"Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIzgMkrCZD7PuoFb\n" +
|
||||
"fmtAd2+Td6nA9sgBd8Z3NjQgP6nwyn79svaVV9XAVLTrLian72wV/1Kbq/6HUXQQ\n" +
|
||||
"AqyUAvobDwXeIAmE4+D7qcZxiEJgVNr2Ddv1bbS8Y0/Ta72qzjFiEPMO3Y2GP52C\n" +
|
||||
"ssKQpsdNttHfM9c73cKUspobc3p51k2lkynheshCSNOWxR/Rvsl/gcbEFg8vIEHV\n" +
|
||||
"oJPwKSrABc4sWiiXQj0yLVW+DKVEFuWNqqitcikQLZFpgOYv8P1SjhJFkcA9s0oN\n" +
|
||||
"sbvKO2VF141h161i0AFddTsGE85A3j42qEdwQ0cs9gyAoeU865TFvxCuhSqSgJ3a\n" +
|
||||
"Mdgn7ssCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw\n" +
|
||||
"HQYDVR0OBBYEFFQY2UJynMSoS7Tf/+DvNPp/ZxXfMA0GCSqGSIb3DQEBCwUAA4IB\n" +
|
||||
"AQAeXRQnEhxNl8lrcGY1U1LbIdrNMlGnc0JbgwiVYwRlE3+u4GvDae1VueXyY6nw\n" +
|
||||
"8m63H3Q/Do9/72aw2Q0FSwvDg+k5ssj+gXQ3Gyx8xsVPJEG0TizOSwnWiZtWu65w\n" +
|
||||
"14p5TB8P8wdPEs6sfE9oheiKhDRjBZHIfqMd4DaBiM9N9qHpSwTJc02BB2KnGwga\n" +
|
||||
"yiYNJbce7GFKn/exryj972n/Nl4xy1WdZrRwTBbV21/GINw+xdXn1+FD95EGqGlr\n" +
|
||||
"Sb4+G7U7Ydo+xFpVQnrqxZe98pI5W2bG7VSKvIzcPxfL5/tjwtNaqhiD7wIBNHVx\n" +
|
||||
"ZeJevm41O9qFQEdXNyVGpB+u\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias int -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String INTERMED =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC/jCCAeagAwIBAgIEDkzdijANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRS\n" +
|
||||
"b290MB4XDTE0MDUwODE4MjcyNFoXDTE2MDQyNzE4MjcyNFowDjEMMAoGA1UEAxMD\n" +
|
||||
"SW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwslILfgvXPxdRgu8\n" +
|
||||
"4SnrZJsSzb/XvYwYGAKTSvsDaI1nXypBbwDGz87+YPpZSJcExcS8I8GBKqN6kXIh\n" +
|
||||
"YvJ9yMGJX8wdwoMQpw2ZfJpzfw9Nqtlhv8/q5kPlaDghJ+nGNwy5lyYNOzDMVht0\n" +
|
||||
"1XQG65C+l7m52lDJ478tGRZEFkx0aTh2QUBI59iNji6r2Buyeiijhg4YBrvIlYLK\n" +
|
||||
"OAHxru4N/Y2Cq3ECUUvm7Lf8tM8yrINS8FLT+pmNcLj8AKkGW8cFFaiGPMyon0/m\n" +
|
||||
"4iJB7ZaeG+BGm9TvBv93cphAsM2tY+S+P/dLfI01ltucibPkSglmquUSA0xW9ilv\n" +
|
||||
"PEYWqQIDAQABo2MwYTAfBgNVHSMEGDAWgBRUGNlCcpzEqEu03//g7zT6f2cV3zAP\n" +
|
||||
"BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU1jeG+pzz\n" +
|
||||
"WnHa+0PfJNw9JTrZaoMwDQYJKoZIhvcNAQELBQADggEBABRshh0oJ8Dq87Tgcf3w\n" +
|
||||
"ERVZ/uDWKj76UXWQ3uvKMhnNxKN/vs1rCfhovkptn39CXndOb8m6UkvmMjDtJsiO\n" +
|
||||
"Oq/DiR6NngCy5yJ5hMuBsdQ2QVvdiqG4Sb+vOaQ2TNQNEHEWC7sB0ztImjxlqDtq\n" +
|
||||
"yvof5pd8pHeZJNyDo5cHw1cpoUI9GLz6CK5i0wUlBvsYERIX5aRqxqdtKgBefHFN\n" +
|
||||
"S2ChTRB16A5C1h+Lu79KnoeS33lZt1VeebIA7hvaHkqhGGpncutEYgT8QNFFpjM8\n" +
|
||||
"yFCjZG+ZuUD/s5hd/xHnPdJzR+RWVKMjjVCTpnni3+NHXo2fh0G8YFhdHQ2F/YFI\n" +
|
||||
"ig0=\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias user -ext ku:c=digitalSignature
|
||||
// -ext eku=clientAuth
|
||||
private static final String USER =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIDAjCCAeqgAwIBAgIEKgsK2DANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwNJ\n" +
|
||||
"bnQwHhcNMTQwNTA4MTgyNzI3WhcNMTYwNDI3MTgyNzI3WjAPMQ0wCwYDVQQDEwRV\n" +
|
||||
"c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArBFLJZ1liQAEkEyJ\n" +
|
||||
"9vAiViRXtDDV+lc62DR4DBj1/Vsw9djVOxmwDKM0+jj83F4Qn9vulr+xp2aZzx4Y\n" +
|
||||
"GiJgbtoxPvZmwNv4MPCNX+fgl/+C0nFKOoSYfHb/tK0Jj6u8HOmQqkbSmGJd/yRL\n" +
|
||||
"qavapRvhS94tFhiNK7wwLAK9AZ+r7cTEBtUSqfaS7mY7tUsERcZs6z3+rmsuxWw6\n" +
|
||||
"/xnNTIVWjdUSbEnjZCdkfZ0cjFONotL6aKoa6YXzohzgA5c3SJZqscEaz4yPkMvl\n" +
|
||||
"7bGy7cn6xjfbb5V3oNqo1dtF3Jm8zp0q8Zgvc47l+DAoGIHSpDhPGX+qSWOTwRla\n" +
|
||||
"QT6NDwIDAQABo2cwZTAfBgNVHSMEGDAWgBTWN4b6nPNacdr7Q98k3D0lOtlqgzAT\n" +
|
||||
"BgNVHSUEDDAKBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFE/p\n" +
|
||||
"UEn8+capIj2+V+7GoxUhdVnWMA0GCSqGSIb3DQEBCwUAA4IBAQBkEyFJ/1CCMoU3\n" +
|
||||
"C1sYoq4Wt36z3e4Z2rMjfpFXcagqOQaq+hq+/eG8gDE50tOp30nZF7BxSv0RKnxa\n" +
|
||||
"KSkrKcupwgPJOZZWVR6ycV3xWm4QleLuDJh3NdK0o8vvIwLQP47fXURzEXTpGodl\n" +
|
||||
"+hGx7jcghsOKftBDCaleywam4jcZ5YPfp5Ayev0pK/Euf0kZgZAhRM33uJVVfEns\n" +
|
||||
"UotoGK7SL6hZMCrreVlXygof19p531Ps5xMqu0y2u2xztjVQJ+gPU5zcYbjByUl+\n" +
|
||||
"pY+wDPb8XU1EoLl7J5UyayXlk0c3KG/5f+CrVi2HtRfCcKLBf8/MH6OFIpX9O77p\n" +
|
||||
"Qq3r+W/l\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias red-ta-key -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String RED_ROOT =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC5jCCAc6gAwIBAgIEWK8vRTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhS\n" +
|
||||
"ZWQgUm9vdDAeFw0xNDA1MDgxODI3MTNaFw0xNjA0MjcxODI3MTNaMBMxETAPBgNV\n" +
|
||||
"BAMTCFJlZCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjpMy\n" +
|
||||
"Qh5yq4R3DrwsWaBZoCR+gda4a1PjGpjlQW/Au6R3hwUDAunkQIz/sX1CnLLJ7cks\n" +
|
||||
"4m6ba2wjYE3NbVP9D3HozLAv2ErB75/F3evRu5UvzkGLkamyHJBY0xEyFyOaD4MC\n" +
|
||||
"hhlo8dDEY++YL8Od+m4i56fYXQlTT94u20I+6hZxeIpJxFSHyouZg06jb+URibi0\n" +
|
||||
"e7I3JApWghgcDfgEXZWlCmB8IswYPdd+XWRFDNc4rSWueRP+SeQOFx9x1jM6+skP\n" +
|
||||
"DGLpuaChO7cqsUxYnsEx9zhdxQ+v4V3vOye/GigpRaO7WvgPB4g5sYhFlwZ/tp+A\n" +
|
||||
"KQebXExXCGOOQUoFEwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB\n" +
|
||||
"/wQEAwIBBjAdBgNVHQ4EFgQUYL8o0Ku7Irg33xzCgA4q1PFz6IQwDQYJKoZIhvcN\n" +
|
||||
"AQELBQADggEBAGSVpI7Qmb0oupBCs+tXlJ4/+TX6eBGcHydaT/2hlgEEdT7S7y6O\n" +
|
||||
"iMC8C8wlEKTLZ6MJSxjeFTIO62OkTjCsGtk+BHTaE81QL5rxjGFkvtuQrwck8gHg\n" +
|
||||
"fAb7daF9ZVLz6B8+cX047xZHx9ZGM/ID+GJg/3fk17WA2BhW1Xkzskby5AWpBDol\n" +
|
||||
"i6+zEod0uZhpHiWwVSfHlEA+rnkhW632oVaVNNDkeUhsCxrU0k7nlQx8bG5bmUso\n" +
|
||||
"1MaPP1kRKvcy0UGx6q3s8pcrKw0X1S66n7HV+WbQebg83U0MVE1r/J0Cfi0jMS/x\n" +
|
||||
"ZUVXs7rjCGFhwfiT/kybKD8adrGHSmLhKs0=\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias orange-ta-key -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String ORANGE_ROOT =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC7DCCAdSgAwIBAgIEQPSszTANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDEwtP\n" +
|
||||
"cmFuZ2UgUm9vdDAeFw0xNDA1MDgxODI3MTRaFw0xNjA0MjcxODI3MTRaMBYxFDAS\n" +
|
||||
"BgNVBAMTC09yYW5nZSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n" +
|
||||
"AQEAknfh3lKWVQxl2w/eRSza6+0+zeTtMkQFCEFpGJsisDK5XOU1HcJMP4QUteWM\n" +
|
||||
"tg1SGO9bjpiKqJ7JVRnzOC3q6erBj2LmwpWW7p12tg6ENOQfsy6tRZLlQWMFGBkT\n" +
|
||||
"Tatsg9HwKpr6itvk2wERh18AcIqSjtN94kGTljP1qf9gMd31G5d/HyG6EwMZukJm\n" +
|
||||
"4/EFpzh3fVwr/EN1WzrYlsBOA+3Tru/k0p8wP6Bomrx1vAEUqRWSLWxsa7we76jL\n" +
|
||||
"H/kMkyWENyjd/A2c5CwscoG+KSx9cifYnSqrUAmpY88KKuZG2Y1+9ablUEwXW4Gh\n" +
|
||||
"RYLCGIgxp6NrtFG/eUcDBgtEwQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G\n" +
|
||||
"A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUPvRE9j3GPGcc3dNGrVrQoWDb9RMwDQYJ\n" +
|
||||
"KoZIhvcNAQELBQADggEBADjPTuHXMbXc2Kn+i+dnBiQCWcjzaox4KWV4MNO7vkvi\n" +
|
||||
"ADBk5/vVM+HTzwL+gZNwE96/agcOzwHZ8/Dz4aA3zzmAmQB4bt+pUa0iyGvX6+F5\n" +
|
||||
"IH1kd4kBnSBMc76fRcEJnebhrXFgTlps5VELMVcEOn3Q4nt+gVfXmPStTkFjM1/4\n" +
|
||||
"fQggsScLpE2TVkk3oS52NIzG/vyBIt3W0gX20hlQobA2vziJDx8xy/+qe5igyp5F\n" +
|
||||
"WScwSQE8qeuoDJYJRxpxZ7kq8NiHxfGPw5Hjn518zBz2VKJOsJYmckAMFIdS//kM\n" +
|
||||
"NUysH6gFksW/PHy75QkbtD4OFtb2zp01ERuf5OoJavs=\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias yellow-ta-key -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String YELLOW_ROOT =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC7DCCAdSgAwIBAgIEfLA7azANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDEwtZ\n" +
|
||||
"ZWxsb3cgUm9vdDAeFw0xNDA1MDgxODI3MTZaFw0xNjA0MjcxODI3MTZaMBYxFDAS\n" +
|
||||
"BgNVBAMTC1llbGxvdyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n" +
|
||||
"AQEAgLMOpzIR8LyALox2AvItM42VjFDp1EyHU0faJZCpwVbQPJ2f+8Gr7XuTv1uZ\n" +
|
||||
"Ixe6JjcyGNHZG0NuFmMFbK2Y7cg3PdQBjcm+x68iSWzyEUuhytSKSLUt6i+xAg+9\n" +
|
||||
"h9UGXlBNarVjWq63tPt8HK/YHxt9Ber0iriF3SEUsgMOzRrLw1mw35SmgidRp19y\n" +
|
||||
"yNXlgQfylEAVtYD9IYhxTm/j9NL3rTgqXiKjvNAVjAUrD2I2nK5WQqO2hmQr9x/9\n" +
|
||||
"EqgIK03dw0ps7/XL+gpd+zwGZqDr9pbFnko4badiE4AJqPlm6u/Tdc0dSkLu/oXq\n" +
|
||||
"Ex4iqtM0TP5+oeDXGZv6EprzKQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G\n" +
|
||||
"A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUp0/g/PqT9jDVGKSsBh997Kg9KBIwDQYJ\n" +
|
||||
"KoZIhvcNAQELBQADggEBAG4vr5UkWUEA9qNU6wBNg5yySS6KhNVyBDMReyX6qsz6\n" +
|
||||
"yUIeGU/UC8LwdB+Tl3S+FZyUlsx+gwh1n0ei7eOV58cCeWmZ3sUWvLTwsY9iBNyt\n" +
|
||||
"HkItOCDO+JEjgo7OhEBlzYkD4MkwAjaYnT4tU41BSnlTR4+jK77f/b1oMVzDv2tL\n" +
|
||||
"+JAiem04TEoGO97uZ94l6gKwwGO35uejGEUPhFPLtxo+yR2QQqX0S8smG88pCQ82\n" +
|
||||
"6XscdvRTjSfkuI3LiqNORS0fGZ3ykxDCkDLZZ1mSg1h2/3xOUEbFQ0phhMrnr2Rl\n" +
|
||||
"mWNGYCam2jns4qmMnbzPIwQduvRkz1O1lusbLNFpcdY=\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias green-ta-key -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String GREEN_ROOT =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC6jCCAdKgAwIBAgIENWwt8TANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpH\n" +
|
||||
"cmVlbiBSb290MB4XDTE0MDUwODE4MjcxOFoXDTE2MDQyNzE4MjcxOFowFTETMBEG\n" +
|
||||
"A1UEAxMKR3JlZW4gUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" +
|
||||
"AKHvh3FRJghpNtLqIk5UDSGkcA3rtEygRsFa51ucwNQ1x4SXOVnsNHZZW66RuKOn\n" +
|
||||
"6wjS8+xctNnMIy1XNXa2nlAswQVe75xX0jfGMB4w0MlaqLK9HrU479WrWmrBjz/P\n" +
|
||||
"vvHY8x1CIfTMjOtLO9yxbYQrXsEz6JKxAz6/+ErbkvUjBynezZdJNXgURVz5HmFx\n" +
|
||||
"e/SUbSALX+Kx+/+hXggaQdwlrpoDl/Nqm6S1iR5xtdZB1CEauIwFDSWOG1TjR1Hp\n" +
|
||||
"8OSGb0AhwwM5FzIxevwgKke6WHFKf5p4lcpiQZqmhgqyFbARUfUjYX3WzQTmrJ/q\n" +
|
||||
"87OMIJasvmkNEYkNbrSmI9kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n" +
|
||||
"HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHG7s0KrfUsnl/3/UGYbCrdXTZtcMA0GCSqG\n" +
|
||||
"SIb3DQEBCwUAA4IBAQBUe18kbDHeqsxM17ahr30hvjdxMkYLkLcGoSOlSI8sFBu6\n" +
|
||||
"jG4JZvvFXw2ZqMQTLSALvsSZ9wkfS8tDCNEHRvCB6aqW4tjp9ddkfe+56WINzTv6\n" +
|
||||
"Ibqwg2JGsOzWttpUA5OPLfODbMqOYzT101toF3sKteX0yyiF/SfMTXR5Jv0uo/dp\n" +
|
||||
"sFeJtWFfhy/Q0jiEAz945BBoSHCIF7Fs4vcls7gNJxfap66W8lamjzFyMDsnlz+b\n" +
|
||||
"sSLWZmvwM+R/RfL1Q3LPCcZWLiP9WSAO4hUoju1E9WeWHHjlPwJJ/iRECL9cnHRt\n" +
|
||||
"Z7/kOlNLGxKvpEbY4xqH0zE07UWPCCBlemk/6jlO\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias blue-ta-key -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String BLUE_ROOT =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC6DCCAdCgAwIBAgIEX3XC9zANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDEwlC\n" +
|
||||
"bHVlIFJvb3QwHhcNMTQwNTA4MTgyNzIwWhcNMTYwNDI3MTgyNzIwWjAUMRIwEAYD\n" +
|
||||
"VQQDEwlCbHVlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCY\n" +
|
||||
"pc4r8mfgGGeiYlvHSrEIlp6djHS489P7eqoQRqmS5U/I0lLGNu7QZsY240a9a84S\n" +
|
||||
"2t6VpZID5juK8AF2v4psShsqgfj+RjVev8FJE/D5j8B4QZ+HmbLJIl80f+YOPaLG\n" +
|
||||
"HX1eNktLx3S2gkIKHVdn7q3o4DdXBO+YdaBA56lL4l+dWFtto65+5Sjy4yfyvWJz\n" +
|
||||
"MylXjP/wiC0T3C0NcQX3AIu2tjY2u9lrVbem2rIi0kPFIoYvstKiqXMc/sRf2CfO\n" +
|
||||
"it5k629HsbvdACVRZFxU3Lz25oP4HGz1kq1cpiIS+W3gQQmCKu9XqzpNRThG0SEL\n" +
|
||||
"jaH9E4pZDnZiRCr+Mxm1AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P\n" +
|
||||
"AQH/BAQDAgEGMB0GA1UdDgQWBBS5ebHO4iamr3n0+KtxJYAitg9QcTANBgkqhkiG\n" +
|
||||
"9w0BAQsFAAOCAQEAGjh/UzERw+skEK4zM1zfL1RsZnUlFu7mTbOBGgccewHWC+MM\n" +
|
||||
"AQbLo0m4NTEbRoW6fFcAESgE61ZZBLkmhcjXBunNJq6O1hMDpppYA806eG6GcZmK\n" +
|
||||
"rLOZljxx4D1YC17vMEVsMF9XgIj5dLWceJjotZzNxe+miwXLEkxaGIMe/n2VtCoR\n" +
|
||||
"BSrGrAeCsFZ7G2NRWUxUEVJrhLnVZJDt6fHd43BCVnV191PyF5TuB08nijyCoJoS\n" +
|
||||
"/WJkYHxx3vUUfDE5E4UE+iY80BHnAPxiNKwO3XsWjeqbJ8PS+5AvShdG5QdFBhKe\n" +
|
||||
"/tJTZLs0UEubKdaWd5ZgsXP3913bJm/mBo+eJA==\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias indigo-ta-key -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String INDIGO_ROOT =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC7DCCAdSgAwIBAgIESdUmczANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDEwtJ\n" +
|
||||
"bmRpZ28gUm9vdDAeFw0xNDA1MDgxODI3MjFaFw0xNjA0MjcxODI3MjFaMBYxFDAS\n" +
|
||||
"BgNVBAMTC0luZGlnbyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n" +
|
||||
"AQEA2opDa3wDxQrX6GjffbDGtXyvKw0/vhZTeus4cxdZIYF3CWkGbeurDIhPUKRO\n" +
|
||||
"Azact0SECJuMXVxkB5vQKBmHRByNh8ugFfzXWi7/rteXTNjLNKnzVr8plbMvzwM7\n" +
|
||||
"zjIgm0mTRbwv6gZmUbgfmO9FCB8zlV4hYbYbFTJn7GlVPpqZkZNNMTyJkOPxMzXD\n" +
|
||||
"yaToxyR0uY3cMv9pmks3GxU2XoGTFuqptbL9XFSpwrm5BRfWuJDP1t8moLHQZ5iu\n" +
|
||||
"tkCz6MVYcrhTlV/UY0PSGcmUvAu83sNBfIGjme0RIiERy02gLJnSZ/M9r1ukCUJE\n" +
|
||||
"Z6At+9TsNCYNPgW5vcjNLO63/wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G\n" +
|
||||
"A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU8eJ+kMmanqF+IcAQTjxSMv+VR7kwDQYJ\n" +
|
||||
"KoZIhvcNAQELBQADggEBAGRB4C5qYXXJJnEGzJZf8S974SaeLmEvHlmaQPOuCxME\n" +
|
||||
"tCeBoWQqD9qTDVy39izzjA4uE/fCMVCkyr1QL+588dtMI8jJfbzx+TxnlDWlJcMM\n" +
|
||||
"5J8EJPNEy7eR6qqpFncvjmbXzf16XfzL9qSXwHYCvpo25nEEH801y2njJE2gGzZT\n" +
|
||||
"raYRFuwzsZLiSV5TyO5MbRXiZLebDXfE/wXukor87pjGpx1/kevjH/g66OpaIBzu\n" +
|
||||
"IfLePEOekTKXHF1zL89uYHwpUVCzfhO5hNQlSsTCuBkBifSTYm4ixoATi/C2kqze\n" +
|
||||
"WHUK179u1+7v6xRONLQxe1JDftdlHHVg7DSeTY59euo=\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// keytool <COMMON-OPTS> -alias violet-ta-key -ext bc:critical=ca:true
|
||||
// -ext ku:critical=keyCertSign,cRLSign
|
||||
private static final String VIOLET_ROOT =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC7DCCAdSgAwIBAgIEXwgmLDANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDEwtW\n" +
|
||||
"aW9sZXQgUm9vdDAeFw0xNDA1MDgxODI3MjNaFw0xNjA0MjcxODI3MjNaMBYxFDAS\n" +
|
||||
"BgNVBAMTC1Zpb2xldCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n" +
|
||||
"AQEAvElr11MoHUNfnx6nBy4NSXFFzA68g57ohTt+sspEn3wzuPErugMypReHLhtH\n" +
|
||||
"CTrs45T0KU8P4Gi5QHnsBs8yC3QCHNPugo2A4zP+ciTqp+1gRNxQ9wzKSzCoseJg\n" +
|
||||
"RMQflGFzuEe7gWwYfrsDfD1sJCubfBtBUFCSYf1ZSZbdEMrc3RPtC35Ge+3XRxFZ\n" +
|
||||
"KdzH8l7gQTtgAmRQmK+i4jwzSHV/Iu2yiRdhjqIZUezf3pYFfJlmfAY5ruQBKkc+\n" +
|
||||
"KRgdmKanpLbmAo/+3q6snt8V09CoQ+6Cz+P9P0yOxiiwr/6jg9WtHA3ujvtf3dGj\n" +
|
||||
"EeB8SmzXHFZErQIn+QbrJ3/izwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G\n" +
|
||||
"A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUlxlHI8JTrX86r4ezgDLICo6rApowDQYJ\n" +
|
||||
"KoZIhvcNAQELBQADggEBALnfWZx6LC9vDMI8vBH/vbyk2ZQtiQFRt3kbwKtlrw65\n" +
|
||||
"/bqeGXcQ1Lh9gDzp+uGYSfuDNvtJO6xmfny0W5j5WQVJxs+iWyoJfYxeG0kBZut+\n" +
|
||||
"hbxJPlehBwhveuznZbeTN3RXeBi8MSxnBD/WC1e2rnfnrxoLfYZ1BSUP8LaIzC32\n" +
|
||||
"vd6WCgnJRXputlGvnOoAT1WduWonhd7lCoqbtZksw7o0smuAn2mSnod8j948rzzt\n" +
|
||||
"uDQVao/3tCyoX4NSom2hWooPltk5FTdF9cZKfbaU5TPV+U30RN7/UWY/dCvL1fMq\n" +
|
||||
"1kvtJbkh+UMHvszHOxlgjk+3J76Wx0PFjNaIfbj2bmk=\n" +
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
public static final String[] rootArrayPEM = { RED_ROOT, ORANGE_ROOT,
|
||||
YELLOW_ROOT, GREEN_ROOT, BLUE_ROOT, INDIGO_ROOT, VIOLET_ROOT, ROOT };
|
||||
|
||||
/**
|
||||
* @param args {cacerts keystore, cert chain}
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
Set<X509Certificate> trustedCertSet = new HashSet<>();
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
|
||||
for (String pemCert : rootArrayPEM) {
|
||||
trustedCertSet.add(makeCertFromPEM(pemCert));
|
||||
}
|
||||
|
||||
testCtorByCollection(trustedCertSet);
|
||||
|
||||
testCtorByPKIXBuilderParams(trustedCertSet);
|
||||
}
|
||||
|
||||
public static X509Certificate makeCertFromPEM(String pemCert)
|
||||
throws CertificateException {
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(pemCert.getBytes());
|
||||
|
||||
return ((X509Certificate)cf.generateCertificate(is));
|
||||
}
|
||||
|
||||
public static void showValidatedChain(Validator v, X509Certificate[] chain,
|
||||
Set<X509Certificate> otherCerts) throws Exception {
|
||||
for (X509Certificate cert : v.validate(chain, otherCerts)) {
|
||||
System.out.println("\tSubj: " + cert.getSubjectX500Principal() +
|
||||
" Iss: " + cert.getIssuerX500Principal());
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<TrustAnchor> makeTrustAnchorSet(
|
||||
Set<X509Certificate> certSet) throws Exception {
|
||||
Set<TrustAnchor> anchors = new HashSet<>();
|
||||
|
||||
for (Certificate cert : certSet) {
|
||||
anchors.add(new TrustAnchor((X509Certificate)cert, null));
|
||||
}
|
||||
|
||||
return anchors;
|
||||
}
|
||||
|
||||
public static void testCtorByCollection(Set<X509Certificate> certSet)
|
||||
throws Exception {
|
||||
Validator valOK;
|
||||
Validator valNoGood;
|
||||
X509Certificate[] chain = new X509Certificate[1];
|
||||
Set<X509Certificate> intermeds = new HashSet<>();
|
||||
|
||||
// Case 1: Make a PKIXValidator with valid arguments
|
||||
// Expected result: Well-formed PKIXValidator
|
||||
System.out.println("Constructor test 1: Valid inputs");
|
||||
valOK = Validator.getInstance(Validator.TYPE_PKIX,
|
||||
Validator.VAR_GENERIC, certSet);
|
||||
|
||||
// Convert our user cert from PEM format, then do the same for
|
||||
// its intermediate signer and add that as a helper for path building
|
||||
chain[0] = makeCertFromPEM(USER);
|
||||
intermeds.add(makeCertFromPEM(INTERMED));
|
||||
PKIXBuilderParameters pbParams = ((PKIXValidator)valOK).getParameters();
|
||||
pbParams.setDate(new Date(1426399200000L)); // 03-15-2014 6:00:00 GMT
|
||||
|
||||
// See if we can build a trusted path to a root to make sure
|
||||
// everything still works as expected.
|
||||
showValidatedChain(valOK, chain, intermeds);
|
||||
|
||||
// Case 2: Make a PKIXValidator with null anchor list.
|
||||
// Expected result: throw NullPointerException
|
||||
System.out.println("Constructor test 2: null trustedCerts");
|
||||
try {
|
||||
valNoGood = Validator.getInstance(Validator.TYPE_PKIX,
|
||||
Validator.VAR_GENERIC, (Collection<X509Certificate>)null);
|
||||
// Throw something non Runtime-related to indicate we shouldn't
|
||||
// have succeeded on construction.
|
||||
throw new IOException(
|
||||
"Constructor did not throw NullPointerException");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("\tCaught Exception (" + npe.toString() +
|
||||
") [PASS])");
|
||||
}
|
||||
|
||||
// Case 3: Try putting a null reference into a populated TA List
|
||||
// Expected result: throw NullPointerException
|
||||
System.out.println("Constructor test 3: null in trustedCerts list");
|
||||
try {
|
||||
certSet.add(null);
|
||||
valNoGood = Validator.getInstance(Validator.TYPE_PKIX,
|
||||
Validator.VAR_GENERIC, certSet);
|
||||
// Throw something non Runtime-related to indicate we shouldn't
|
||||
// have succeeded on construction.
|
||||
throw new IOException("Constructor did not throw RuntimeException");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("\tCaught Exception (" + npe.toString() +
|
||||
") [PASS])");
|
||||
} finally {
|
||||
// Return the certSet list to its original state
|
||||
certSet.remove(null);
|
||||
}
|
||||
|
||||
// Case 4: Provide an empty List as the X509Certificate collection
|
||||
// Expected result: throw RuntimeException
|
||||
System.out.println("Constructor test 4: empty trustedCerts list");
|
||||
try {
|
||||
valNoGood = Validator.getInstance(Validator.TYPE_PKIX,
|
||||
Validator.VAR_GENERIC, new ArrayList<X509Certificate>());
|
||||
// Throw something non Runtime-related to indicate we shouldn't
|
||||
// have succeeded on construction.
|
||||
throw new IOException("Constructor did not throw RuntimeException");
|
||||
} catch (RuntimeException re) {
|
||||
System.out.println("\tCaught RuntimeException (" + re.toString() +
|
||||
") [PASS])");
|
||||
}
|
||||
|
||||
// Case 5: Provide an invalid variant
|
||||
// Expected result: successful construction.
|
||||
// Note: subsequent calls to validate may throw CertificateException
|
||||
// if the submitted chain has a length > 1.
|
||||
System.out.println("Constructor test 5: Unsupported variant");
|
||||
valNoGood = Validator.getInstance(Validator.TYPE_PKIX,
|
||||
"BogusVariant", certSet);
|
||||
System.out.println("\tSuccessful construction [PASS]");
|
||||
|
||||
// Case 6: Provide a null variant
|
||||
// Expected result: throw NullPointerException
|
||||
System.out.println("Constructor test 6: null variant");
|
||||
try {
|
||||
valNoGood = Validator.getInstance(Validator.TYPE_PKIX, null,
|
||||
certSet);
|
||||
// Throw something non Runtime-related to indicate we shouldn't
|
||||
// have succeeded on construction.
|
||||
throw new IOException(
|
||||
"Constructor did not throw NullPointerException");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("\tCaught RuntimeException (" + npe.toString() +
|
||||
") [PASS])");
|
||||
}
|
||||
}
|
||||
|
||||
public static void testCtorByPKIXBuilderParams(Set<X509Certificate> certSet)
|
||||
throws Exception {
|
||||
Set<TrustAnchor> taSet = makeTrustAnchorSet(certSet);
|
||||
Validator valOK;
|
||||
Validator valNoGood;
|
||||
X509Certificate[] chain = new X509Certificate[1];
|
||||
Set<X509Certificate> intermeds = new HashSet<>();
|
||||
|
||||
// Case 7: Make a PKIXValidator with valid arguments
|
||||
// Expected result: Well-formed PKIXValidator object
|
||||
System.out.println("Constructor test 7: Valid inputs");
|
||||
|
||||
// Set up the PKIXBuilderParameters
|
||||
X509CertSelector sel = new X509CertSelector();
|
||||
sel.setSubject("CN=User");
|
||||
PKIXBuilderParameters pbParams = new PKIXBuilderParameters(taSet, sel);
|
||||
pbParams.setRevocationEnabled(false);
|
||||
pbParams.setDate(new Date(1426399200000L)); // 03-15-2014 6:00:00 GMT
|
||||
|
||||
valOK = Validator.getInstance(Validator.TYPE_PKIX,
|
||||
Validator.VAR_GENERIC, pbParams);
|
||||
|
||||
// Convert our user cert from PEM format, then do the same for
|
||||
// its intermediate signer and add that as a helper for path building
|
||||
chain[0] = makeCertFromPEM(USER);
|
||||
intermeds.add(makeCertFromPEM(INTERMED));
|
||||
|
||||
showValidatedChain(valOK, chain, intermeds);
|
||||
|
||||
// Case 8: Make a PKIXValidator but provide a null PKIXBuilderParameters
|
||||
// Expected result: throw NullPointerException
|
||||
System.out.println("Constructor test 8: null params");
|
||||
try {
|
||||
valNoGood = Validator.getInstance(Validator.TYPE_PKIX,
|
||||
Validator.VAR_GENERIC, (PKIXBuilderParameters)null);
|
||||
// Throw something non Runtime-related to indicate we shouldn't
|
||||
// have succeeded on construction.
|
||||
throw new IOException(
|
||||
"Constructor did not throw NullPointerException");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("\tCaught RuntimeException (" + npe.toString() +
|
||||
") [PASS])");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user