This commit is contained in:
Jesper Wilhelmsson 2017-12-02 06:51:10 +01:00
commit 48d81c1e0c
286 changed files with 10129 additions and 2688 deletions

View file

@ -1813,7 +1813,7 @@ public abstract class ClassLoader {
}
/**
* Returns the platform class loader for delegation. All
* Returns the platform class loader. All
* <a href="#builtinLoaders">platform classes</a> are visible to
* the platform class loader.
*
@ -1843,7 +1843,7 @@ public abstract class ClassLoader {
}
/**
* Returns the system class loader for delegation. This is the default
* Returns the system class loader. This is the default
* delegation parent for new {@code ClassLoader} instances, and is
* typically the class loader used to start the application.
*
@ -1884,7 +1884,7 @@ public abstract class ClassLoader {
* the application module path then the class path defaults to
* the current working directory.
*
* @return The system {@code ClassLoader} for delegation
* @return The system {@code ClassLoader}
*
* @throws SecurityException
* If a security manager is present, and the caller's class loader

View file

@ -101,7 +101,7 @@ import sun.security.util.SecurityConstants;
* <code>checkPermission</code> returns quietly. If denied, a
* <code>SecurityException</code> is thrown.
* <p>
* As of Java 2 SDK v1.2, the default implementation of each of the other
* The default implementation of each of the other
* <code>check</code> methods in <code>SecurityManager</code> is to
* call the <code>SecurityManager checkPermission</code> method
* to determine if the calling thread has permission to perform the requested
@ -197,10 +197,10 @@ import sun.security.util.SecurityConstants;
* See {@extLink security_guide_permissions
* Permissions in the Java Development Kit (JDK)}
* for permission-related information.
* This document includes, for example, a table listing the various SecurityManager
* This document includes a table listing the various SecurityManager
* <code>check</code> methods and the permission(s) the default
* implementation of each such method requires.
* It also contains a table of all the version 1.2 methods
* It also contains a table of the methods
* that require permissions, and for each such method tells
* which permission it requires.
*
@ -228,20 +228,7 @@ import sun.security.util.SecurityConstants;
*
* @since 1.0
*/
public
class SecurityManager {
/**
* This field is <code>true</code> if there is a security check in
* progress; <code>false</code> otherwise.
*
* @deprecated This type of security checking is not recommended.
* It is recommended that the <code>checkPermission</code>
* call be used instead. This field is subject to removal in a
* future version of Java SE.
*/
@Deprecated(since="1.2", forRemoval=true)
protected boolean inCheck;
public class SecurityManager {
/*
* Have we been initialized. Effective against finalizer attacks.
@ -261,24 +248,6 @@ class SecurityManager {
}
}
/**
* Tests if there is a security check in progress.
*
* @return the value of the <code>inCheck</code> field. This field
* should contain <code>true</code> if a security check is
* in progress,
* <code>false</code> otherwise.
* @see java.lang.SecurityManager#inCheck
* @deprecated This type of security checking is not recommended.
* It is recommended that the <code>checkPermission</code>
* call be used instead. This method is subject to removal in a
* future version of Java SE.
*/
@Deprecated(since="1.2", forRemoval=true)
public boolean getInCheck() {
return inCheck;
}
/**
* Constructs a new <code>SecurityManager</code>.
*
@ -321,198 +290,6 @@ class SecurityManager {
*/
protected native Class<?>[] getClassContext();
/**
* Returns the class loader of the most recently executing method from
* a class defined using a non-system class loader. A non-system
* class loader is defined as being a class loader that is not equal to
* the system class loader (as returned
* by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors.
* <p>
* This method will return
* <code>null</code> in the following three cases:
* <ol>
* <li>All methods on the execution stack are from classes
* defined using the system class loader or one of its ancestors.
*
* <li>All methods on the execution stack up to the first
* "privileged" caller
* (see {@link java.security.AccessController#doPrivileged})
* are from classes
* defined using the system class loader or one of its ancestors.
*
* <li> A call to <code>checkPermission</code> with
* <code>java.security.AllPermission</code> does not
* result in a SecurityException.
*
* </ol>
*
* @return the class loader of the most recent occurrence on the stack
* of a method from a class defined using a non-system class
* loader.
*
* @deprecated This type of security checking is not recommended.
* It is recommended that the <code>checkPermission</code>
* call be used instead. This method is subject to removal in a
* future version of Java SE.
*
* @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
* @see #checkPermission(java.security.Permission) checkPermission
*/
@Deprecated(since="1.2", forRemoval=true)
protected ClassLoader currentClassLoader() {
ClassLoader cl = currentClassLoader0();
if ((cl != null) && hasAllPermission())
cl = null;
return cl;
}
private native ClassLoader currentClassLoader0();
/**
* Returns the class of the most recently executing method from
* a class defined using a non-system class loader. A non-system
* class loader is defined as being a class loader that is not equal to
* the system class loader (as returned
* by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors.
* <p>
* This method will return
* <code>null</code> in the following three cases:
* <ol>
* <li>All methods on the execution stack are from classes
* defined using the system class loader or one of its ancestors.
*
* <li>All methods on the execution stack up to the first
* "privileged" caller
* (see {@link java.security.AccessController#doPrivileged})
* are from classes
* defined using the system class loader or one of its ancestors.
*
* <li> A call to <code>checkPermission</code> with
* <code>java.security.AllPermission</code> does not
* result in a SecurityException.
*
* </ol>
*
* @return the class of the most recent occurrence on the stack
* of a method from a class defined using a non-system class
* loader.
*
* @deprecated This type of security checking is not recommended.
* It is recommended that the <code>checkPermission</code>
* call be used instead. This method is subject to removal in a
* future version of Java SE.
*
* @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
* @see #checkPermission(java.security.Permission) checkPermission
*/
@Deprecated(since="1.2", forRemoval=true)
protected Class<?> currentLoadedClass() {
Class<?> c = currentLoadedClass0();
if ((c != null) && hasAllPermission())
c = null;
return c;
}
/**
* Returns the stack depth of the specified class.
*
* @param name the fully qualified name of the class to search for.
* @return the depth on the stack frame of the first occurrence of a
* method from a class with the specified name;
* <code>-1</code> if such a frame cannot be found.
* @deprecated This type of security checking is not recommended.
* It is recommended that the <code>checkPermission</code>
* call be used instead. This method is subject to removal in a
* future version of Java SE.
*/
@Deprecated(since="1.2", forRemoval=true)
protected native int classDepth(String name);
/**
* Returns the stack depth of the most recently executing method
* from a class defined using a non-system class loader. A non-system
* class loader is defined as being a class loader that is not equal to
* the system class loader (as returned
* by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors.
* <p>
* This method will return
* -1 in the following three cases:
* <ol>
* <li>All methods on the execution stack are from classes
* defined using the system class loader or one of its ancestors.
*
* <li>All methods on the execution stack up to the first
* "privileged" caller
* (see {@link java.security.AccessController#doPrivileged})
* are from classes
* defined using the system class loader or one of its ancestors.
*
* <li> A call to <code>checkPermission</code> with
* <code>java.security.AllPermission</code> does not
* result in a SecurityException.
*
* </ol>
*
* @return the depth on the stack frame of the most recent occurrence of
* a method from a class defined using a non-system class loader.
*
* @deprecated This type of security checking is not recommended.
* It is recommended that the <code>checkPermission</code>
* call be used instead. This method is subject to removal in a
* future version of Java SE.
*
* @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
* @see #checkPermission(java.security.Permission) checkPermission
*/
@Deprecated(since="1.2", forRemoval=true)
protected int classLoaderDepth() {
int depth = classLoaderDepth0();
if (depth != -1) {
if (hasAllPermission())
depth = -1;
else
depth--; // make sure we don't include ourself
}
return depth;
}
private native int classLoaderDepth0();
/**
* Tests if a method from a class with the specified
* name is on the execution stack.
*
* @param name the fully qualified name of the class.
* @return <code>true</code> if a method from a class with the specified
* name is on the execution stack; <code>false</code> otherwise.
* @deprecated This type of security checking is not recommended.
* It is recommended that the <code>checkPermission</code>
* call be used instead. This method is subject to removal in a
* future version of Java SE.
*/
@Deprecated(since="1.2", forRemoval=true)
protected boolean inClass(String name) {
return classDepth(name) >= 0;
}
/**
* Basically, tests if a method from a class defined using a
* class loader is on the execution stack.
*
* @return <code>true</code> if a call to <code>currentClassLoader</code>
* has a non-null return value.
*
* @deprecated This type of security checking is not recommended.
* It is recommended that the <code>checkPermission</code>
* call be used instead. This method is subject to removal in a
* future version of Java SE.
* @see #currentClassLoader() currentClassLoader
*/
@Deprecated(since="1.2", forRemoval=true)
protected boolean inClassLoader() {
return currentClassLoader() != null;
}
/**
* Creates an object that encapsulates the current execution
* environment. The result of this method is used, for example, by the
@ -1698,64 +1475,32 @@ class SecurityManager {
}
/**
* Throws a <code>SecurityException</code> if the
* calling thread is not allowed to access members.
* <p>
* The default policy is to allow access to PUBLIC members, as well
* as access to classes that have the same class loader as the caller.
* In all other cases, this method calls <code>checkPermission</code>
* with the <code>RuntimePermission("accessDeclaredMembers")
* </code> permission.
* <p>
* If this method is overridden, then a call to
* <code>super.checkMemberAccess</code> cannot be made,
* as the default implementation of <code>checkMemberAccess</code>
* relies on the code being checked being at a stack depth of
* 4.
* Throws a {@code SecurityException} if the calling thread does
* not have {@code AllPermission}.
*
* @param clazz the class that reflection is to be performed on.
*
* @param which type of access, PUBLIC or DECLARED.
*
* @exception SecurityException if the caller does not have
* permission to access members.
* @exception NullPointerException if the <code>clazz</code> argument is
* <code>null</code>.
*
* @deprecated This method relies on the caller being at a stack depth
* of 4 which is error-prone and cannot be enforced by the runtime.
* Users of this method should instead invoke {@link #checkPermission}
* directly.
* This method is subject to removal in a future version of Java SE.
*
* @see java.lang.reflect.Member
* @throws SecurityException if the caller does not have
* {@code AllPermission}
* @throws NullPointerException if the {@code clazz} argument is
* {@code null}
* @deprecated This method was originally used to check if the calling
* thread was allowed to access members. It relied on the
* caller being at a stack depth of 4 which is error-prone and
* cannot be enforced by the runtime. The method has been
* obsoleted and code should instead use
* {@link #checkPermission} to check
* {@code RuntimePermission("accessDeclaredMembers")}. This
* method is subject to removal in a future version of Java SE.
* @since 1.1
* @see #checkPermission(java.security.Permission) checkPermission
*/
@Deprecated(since="1.8", forRemoval=true)
@CallerSensitive
public void checkMemberAccess(Class<?> clazz, int which) {
if (clazz == null) {
throw new NullPointerException("class can't be null");
}
if (which != Member.PUBLIC) {
Class<?> stack[] = getClassContext();
/*
* stack depth of 4 should be the caller of one of the
* methods in java.lang.Class that invoke checkMember
* access. The stack should look like:
*
* someCaller [3]
* java.lang.Class.someReflectionAPI [2]
* java.lang.Class.checkMemberAccess [1]
* SecurityManager.checkMemberAccess [0]
*
*/
if ((stack.length<4) ||
(stack[3].getClassLoader() != clazz.getClassLoader())) {
checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
}
checkPermission(SecurityConstants.ALL_PERMISSION);
}
/**
@ -1792,8 +1537,6 @@ class SecurityManager {
checkPermission(new SecurityPermission(target));
}
private native Class<?> currentLoadedClass0();
/**
* Returns the thread group into which to instantiate any new
* thread being created at the time this is being called.

View file

@ -263,8 +263,12 @@ public final class LambdaMetafactory {
* methods from {@code Object}.
*
* @param caller Represents a lookup context with the accessibility
* privileges of the caller. When used with {@code invokedynamic},
* this is stacked automatically by the VM.
* privileges of the caller. Specifically, the lookup context
* must have
* <a href="MethodHandles.Lookup.html#privacc">private access</a>
* privileges.
* When used with {@code invokedynamic}, this is stacked
* automatically by the VM.
* @param invokedName The name of the method to implement. When used with
* {@code invokedynamic}, this is provided by the
* {@code NameAndType} of the {@code InvokeDynamic}
@ -294,7 +298,8 @@ public final class LambdaMetafactory {
* instances of the interface named by {@code invokedType}
* @throws LambdaConversionException If any of the linkage invariants
* described {@link LambdaMetafactory above}
* are violated
* are violated, or the lookup context
* does not have private access privileges.
*/
public static CallSite metafactory(MethodHandles.Lookup caller,
String invokedName,
@ -404,8 +409,12 @@ public final class LambdaMetafactory {
* </ul>
*
* @param caller Represents a lookup context with the accessibility
* privileges of the caller. When used with {@code invokedynamic},
* this is stacked automatically by the VM.
* privileges of the caller. Specifically, the lookup context
* must have
* <a href="MethodHandles.Lookup.html#privacc">private access</a>
* privileges.
* When used with {@code invokedynamic}, this is stacked
* automatically by the VM.
* @param invokedName The name of the method to implement. When used with
* {@code invokedynamic}, this is provided by the
* {@code NameAndType} of the {@code InvokeDynamic}
@ -429,7 +438,8 @@ public final class LambdaMetafactory {
* instances of the interface named by {@code invokedType}
* @throws LambdaConversionException If any of the linkage invariants
* described {@link LambdaMetafactory above}
* are violated
* are violated, or the lookup context
* does not have private access privileges.
*/
public static CallSite altMetafactory(MethodHandles.Lookup caller,
String invokedName,

View file

@ -385,9 +385,16 @@ public final class StringConcatFactory {
* invoked, it returns the result of String concatenation, taking all
* function arguments passed to the linkage method as inputs for
* concatenation. The target signature is given by {@code concatType}.
* The arguments are concatenated as per requirements stated in JLS 15.18.1
* "String Concatenation Operator +". Notably, the inputs are converted as
* per JLS 5.1.11 "String Conversion", and combined from left to right.
* For a target accepting:
* <ul>
* <li>zero inputs, concatenation results in an empty string;</li>
* <li>one input, concatenation results in the single
* input converted as per JLS 5.1.11 "String Conversion"; otherwise</li>
* <li>two or more inputs, the inputs are concatenated as per
* requirements stated in JLS 15.18.1 "String Concatenation Operator +".
* The inputs are converted as per JLS 5.1.11 "String Conversion",
* and combined from left to right.</li>
* </ul>
*
* <p>Assume the linkage arguments are as follows:
*
@ -404,8 +411,12 @@ public final class StringConcatFactory {
* </ul>
*
* @param lookup Represents a lookup context with the accessibility
* privileges of the caller. When used with {@code
* invokedynamic}, this is stacked automatically by the VM.
* privileges of the caller. Specifically, the lookup
* context must have
* <a href="MethodHandles.Lookup.html#privacc">private access</a>
* privileges.
* When used with {@code invokedynamic}, this is stacked
* automatically by the VM.
* @param name The name of the method to implement. This name is
* arbitrary, and has no meaning for this linkage method.
* When used with {@code invokedynamic}, this is provided by
@ -422,7 +433,8 @@ public final class StringConcatFactory {
* concatenation, with dynamic concatenation arguments described by the given
* {@code concatType}.
* @throws StringConcatException If any of the linkage invariants described
* here are violated.
* here are violated, or the lookup context
* does not have private access privileges.
* @throws NullPointerException If any of the incoming arguments is null.
* This will never happen when a bootstrap method
* is called with invokedynamic.
@ -452,10 +464,17 @@ public final class StringConcatFactory {
* invoked, it returns the result of String concatenation, taking all
* function arguments and constants passed to the linkage method as inputs for
* concatenation. The target signature is given by {@code concatType}, and
* does not include constants. The arguments are concatenated as per requirements
* stated in JLS 15.18.1 "String Concatenation Operator +". Notably, the inputs
* are converted as per JLS 5.1.11 "String Conversion", and combined from left
* to right.
* does not include constants.
* For a target accepting:
* <ul>
* <li>zero inputs, concatenation results in an empty string;</li>
* <li>one input, concatenation results in the single
* input converted as per JLS 5.1.11 "String Conversion"; otherwise</li>
* <li>two or more inputs, the inputs are concatenated as per
* requirements stated in JLS 15.18.1 "String Concatenation Operator +".
* The inputs are converted as per JLS 5.1.11 "String Conversion",
* and combined from left to right.</li>
* </ul>
*
* <p>The concatenation <em>recipe</em> is a String description for the way to
* construct a concatenated String from the arguments and constants. The
@ -502,9 +521,12 @@ public final class StringConcatFactory {
* </ul>
*
* @param lookup Represents a lookup context with the accessibility
* privileges of the caller. When used with {@code
* invokedynamic}, this is stacked automatically by the
* VM.
* privileges of the caller. Specifically, the lookup
* context must have
* <a href="MethodHandles.Lookup.html#privacc">private access</a>
* privileges.
* When used with {@code invokedynamic}, this is stacked
* automatically by the VM.
* @param name The name of the method to implement. This name is
* arbitrary, and has no meaning for this linkage method.
* When used with {@code invokedynamic}, this is provided
@ -524,7 +546,8 @@ public final class StringConcatFactory {
* concatenation, with dynamic concatenation arguments described by the given
* {@code concatType}.
* @throws StringConcatException If any of the linkage invariants described
* here are violated.
* here are violated, or the lookup context
* does not have private access privileges.
* @throws NullPointerException If any of the incoming arguments is null, or
* any constant in {@code recipe} is null.
* This will never happen when a bootstrap method

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -32,9 +32,12 @@ import java.security.*;
*
* <p>The {@code initialize} methods may each be called any number
* of times. If no {@code initialize} method is called on a
* DSAKeyPairGenerator, the default is to generate 1024-bit keys, using
* precomputed p, q and g parameters and an instance of SecureRandom as
* the random bit source.
* DSAKeyPairGenerator, each provider that implements this interface
* should supply (and document) a default initialization. Note that
* defaults may vary across different providers. Additionally, the default
* value for a provider may change in a future version. Therefore, it is
* recommended to explicitly initialize the DSAKeyPairGenerator instead
* of relying on provider-specific defaults.
*
* <p>Users wishing to indicate DSA-specific parameters, and to generate a key
* pair suitable for use with the DSA algorithm typically
@ -45,12 +48,13 @@ import java.security.*;
* KeyPairGenerator {@code getInstance} method with "DSA"
* as its argument.
*
* <li>Initialize the generator by casting the result to a DSAKeyPairGenerator
* and calling one of the
* {@code initialize} methods from this DSAKeyPairGenerator interface.
* <li>Check if the returned key pair generator is an instance of
* DSAKeyPairGenerator before casting the result to a DSAKeyPairGenerator
* and calling one of the {@code initialize} methods from this
* DSAKeyPairGenerator interface.
*
* <li>Generate a key pair by calling the {@code generateKeyPair}
* method from the KeyPairGenerator class.
* method of the KeyPairGenerator class.
*
* </ol>
*
@ -63,7 +67,7 @@ import java.security.*;
* parameters.
*
* <p>Note: Some earlier implementations of this interface may not support
* larger sizes of DSA parameters such as 2048 and 3072-bit.
* larger values of DSA parameters such as 3072-bit.
*
* @since 1.1
* @see java.security.KeyPairGenerator
@ -97,8 +101,7 @@ public interface DSAKeyPairGenerator {
* p, q and g parameters. If it is false, the method uses precomputed
* parameters for the modulus length requested. If there are no
* precomputed parameters for that modulus length, an exception will be
* thrown. It is guaranteed that there will always be
* default parameters for modulus lengths of 512 and 1024 bits.
* thrown.
*
* @param modlen the modulus length in bits. Valid values are any
* multiple of 64 between 512 and 1024, inclusive, 2048, and 3072.

View file

@ -294,28 +294,27 @@ public abstract class DateFormat extends Format {
private static final long serialVersionUID = 7218322306649953788L;
/**
* Overrides Format.
* Formats a time object into a time string. Examples of time objects
* are a time value expressed in milliseconds and a Date object.
* @param obj must be a Number or a Date.
* @param toAppendTo the string buffer for the returning time string.
* @return the string buffer passed in as toAppendTo, with formatted text appended.
* @param fieldPosition keeps track of the position of the field
* within the returned string.
* On input: an alignment field,
* if desired. On output: the offsets of the alignment field. For
* example, given a time text "1996.07.10 AD at 15:08:56 PDT",
* if the given fieldPosition is DateFormat.YEAR_FIELD, the
* begin index and end index of fieldPosition will be set to
* 0 and 4, respectively.
* Notice that if the same time field appears
* more than once in a pattern, the fieldPosition will be set for the first
* occurrence of that time field. For instance, formatting a Date to
* the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
* "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
* the begin index and end index of fieldPosition will be set to
* 5 and 8, respectively, for the first occurrence of the timezone
* pattern character 'z'.
* Formats the given {@code Object} into a date-time string. The formatted
* string is appended to the given {@code StringBuffer}.
*
* @param obj Must be a {@code Date} or a {@code Number} representing a
* millisecond offset from the <a href="../util/Calendar.html#Epoch">Epoch</a>.
* @param toAppendTo The string buffer for the returning date-time string.
* @param fieldPosition keeps track on the position of the field within
* the returned string. For example, given a date-time text
* {@code "1996.07.10 AD at 15:08:56 PDT"}, if the given {@code fieldPosition}
* is {@link DateFormat#YEAR_FIELD}, the begin index and end index of
* {@code fieldPosition} will be set to 0 and 4, respectively.
* Notice that if the same date-time field appears more than once in a
* pattern, the {@code fieldPosition} will be set for the first occurrence
* of that date-time field. For instance, formatting a {@code Date} to the
* date-time string {@code "1 PM PDT (Pacific Daylight Time)"} using the
* pattern {@code "h a z (zzzz)"} and the alignment field
* {@link DateFormat#TIMEZONE_FIELD}, the begin index and end index of
* {@code fieldPosition} will be set to 5 and 8, respectively, for the
* first occurrence of the timezone pattern character {@code 'z'}.
* @return the string buffer passed in as {@code toAppendTo},
* with formatted text appended.
* @exception IllegalArgumentException if the {@code Format} cannot format
* the given {@code obj}.
* @see java.text.Format
@ -333,34 +332,35 @@ public abstract class DateFormat extends Format {
}
/**
* Formats a Date into a date/time string.
* @param date a Date to be formatted into a date/time string.
* @param toAppendTo the string buffer for the returning date/time string.
* @param fieldPosition keeps track of the position of the field
* within the returned string.
* On input: an alignment field,
* if desired. On output: the offsets of the alignment field. For
* example, given a time text "1996.07.10 AD at 15:08:56 PDT",
* if the given fieldPosition is DateFormat.YEAR_FIELD, the
* begin index and end index of fieldPosition will be set to
* 0 and 4, respectively.
* Notice that if the same time field appears
* more than once in a pattern, the fieldPosition will be set for the first
* occurrence of that time field. For instance, formatting a Date to
* the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
* "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
* the begin index and end index of fieldPosition will be set to
* 5 and 8, respectively, for the first occurrence of the timezone
* pattern character 'z'.
* @return the string buffer passed in as toAppendTo, with formatted text appended.
* Formats a {@link Date} into a date-time string. The formatted
* string is appended to the given {@code StringBuffer}.
*
* @param date a Date to be formatted into a date-time string.
* @param toAppendTo the string buffer for the returning date-time string.
* @param fieldPosition keeps track on the position of the field within
* the returned string. For example, given a date-time text
* {@code "1996.07.10 AD at 15:08:56 PDT"}, if the given {@code fieldPosition}
* is {@link DateFormat#YEAR_FIELD}, the begin index and end index of
* {@code fieldPosition} will be set to 0 and 4, respectively.
* Notice that if the same date-time field appears more than once in a
* pattern, the {@code fieldPosition} will be set for the first occurrence
* of that date-time field. For instance, formatting a {@code Date} to the
* date-time string {@code "1 PM PDT (Pacific Daylight Time)"} using the
* pattern {@code "h a z (zzzz)"} and the alignment field
* {@link DateFormat#TIMEZONE_FIELD}, the begin index and end index of
* {@code fieldPosition} will be set to 5 and 8, respectively, for the
* first occurrence of the timezone pattern character {@code 'z'}.
* @return the string buffer passed in as {@code toAppendTo}, with formatted
* text appended.
*/
public abstract StringBuffer format(Date date, StringBuffer toAppendTo,
FieldPosition fieldPosition);
/**
* Formats a Date into a date/time string.
* @param date the time value to be formatted into a time string.
* @return the formatted time string.
* Formats a {@link Date} into a date-time string.
*
* @param date the time value to be formatted into a date-time string.
* @return the formatted date-time string.
*/
public final String format(Date date)
{

View file

@ -480,8 +480,14 @@ public class DecimalFormat extends NumberFormat {
* @param number the number to format
* @param toAppendTo the <code>StringBuffer</code> to which the formatted
* text is to be appended
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param pos keeps track on the position of the field within the
* returned string. For example, for formatting a number
* {@code 1234567.89} in {@code Locale.US} locale,
* if the given {@code fieldPosition} is
* {@link NumberFormat#INTEGER_FIELD}, the begin index
* and end index of {@code fieldPosition} will be set
* to 0 and 9, respectively for the output string
* {@code 1,234,567.89}.
* @return the value passed in as <code>toAppendTo</code>
* @exception IllegalArgumentException if <code>number</code> is
* null or not an instance of <code>Number</code>.
@ -517,8 +523,14 @@ public class DecimalFormat extends NumberFormat {
* Formats a double to produce a string.
* @param number The double to format
* @param result where the text is to be appended
* @param fieldPosition On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param fieldPosition keeps track on the position of the field within
* the returned string. For example, for formatting
* a number {@code 1234567.89} in {@code Locale.US}
* locale, if the given {@code fieldPosition} is
* {@link NumberFormat#INTEGER_FIELD}, the begin index
* and end index of {@code fieldPosition} will be set
* to 0 and 9, respectively for the output string
* {@code 1,234,567.89}.
* @exception NullPointerException if {@code result} or
* {@code fieldPosition} is {@code null}
* @exception ArithmeticException if rounding is needed with rounding
@ -637,8 +649,14 @@ public class DecimalFormat extends NumberFormat {
* Format a long to produce a string.
* @param number The long to format
* @param result where the text is to be appended
* @param fieldPosition On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param fieldPosition keeps track on the position of the field within
* the returned string. For example, for formatting
* a number {@code 123456789} in {@code Locale.US}
* locale, if the given {@code fieldPosition} is
* {@link NumberFormat#INTEGER_FIELD}, the begin index
* and end index of {@code fieldPosition} will be set
* to 0 and 11, respectively for the output string
* {@code 123,456,789}.
* @exception NullPointerException if {@code result} or
* {@code fieldPosition} is {@code null}
* @exception ArithmeticException if rounding is needed with rounding
@ -727,8 +745,14 @@ public class DecimalFormat extends NumberFormat {
* Formats a BigDecimal to produce a string.
* @param number The BigDecimal to format
* @param result where the text is to be appended
* @param fieldPosition On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param fieldPosition keeps track on the position of the field within
* the returned string. For example, for formatting
* a number {@code 1234567.89} in {@code Locale.US}
* locale, if the given {@code fieldPosition} is
* {@link NumberFormat#INTEGER_FIELD}, the begin index
* and end index of {@code fieldPosition} will be set
* to 0 and 9, respectively for the output string
* {@code 1,234,567.89}.
* @return The formatted number string
* @exception ArithmeticException if rounding is needed with rounding
* mode being set to RoundingMode.UNNECESSARY
@ -780,8 +804,14 @@ public class DecimalFormat extends NumberFormat {
* Format a BigInteger to produce a string.
* @param number The BigInteger to format
* @param result where the text is to be appended
* @param fieldPosition On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param fieldPosition keeps track on the position of the field within
* the returned string. For example, for formatting
* a number {@code 123456789} in {@code Locale.US}
* locale, if the given {@code fieldPosition} is
* {@link NumberFormat#INTEGER_FIELD}, the begin index
* and end index of {@code fieldPosition} will be set
* to 0 and 11, respectively for the output string
* {@code 123,456,789}.
* @return The formatted number string
* @exception ArithmeticException if rounding is needed with rounding
* mode being set to RoundingMode.UNNECESSARY

View file

@ -820,8 +820,8 @@ public class MessageFormat extends Format {
*
* @param arguments an array of objects to be formatted and substituted.
* @param result where text is appended.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param pos keeps track on the position of the first replaced argument
in the output string.
* @return the string buffer passed in as {@code result}, with formatted
* text appended
* @exception IllegalArgumentException if an argument in the
@ -868,8 +868,8 @@ public class MessageFormat extends Format {
*
* @param arguments an array of objects to be formatted and substituted.
* @param result where text is appended.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param pos keeps track on the position of the first replaced argument
* in the output string.
* @exception IllegalArgumentException if an argument in the
* <code>arguments</code> array is not of the type
* expected by the format element(s) that use it.
@ -1239,11 +1239,11 @@ public class MessageFormat extends Format {
private int maxOffset = -1;
/**
* Internal routine used by format. If <code>characterIterators</code> is
* non-null, AttributedCharacterIterator will be created from the
* subformats as necessary. If <code>characterIterators</code> is null
* and <code>fp</code> is non-null and identifies
* <code>Field.MESSAGE_ARGUMENT</code>, the location of
* Internal routine used by format. If {@code characterIterators} is
* {@code non-null}, AttributedCharacterIterator will be created from the
* subformats as necessary. If {@code characterIterators} is {@code null}
* and {@code fp} is {@code non-null} and identifies
* {@code Field.ARGUMENT} as the field attribute, the location of
* the first replaced argument will be set in it.
*
* @exception IllegalArgumentException if an argument in the

View file

@ -240,8 +240,14 @@ public abstract class NumberFormat extends Format {
* @param number the number to format
* @param toAppendTo the <code>StringBuffer</code> to which the formatted
* text is to be appended
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param pos keeps track on the position of the field within the
* returned string. For example, for formatting a number
* {@code 1234567.89} in {@code Locale.US} locale,
* if the given {@code fieldPosition} is
* {@link NumberFormat#INTEGER_FIELD}, the begin index
* and end index of {@code fieldPosition} will be set
* to 0 and 9, respectively for the output string
* {@code 1,234,567.89}.
* @return the value passed in as <code>toAppendTo</code>
* @exception IllegalArgumentException if <code>number</code> is
* null or not an instance of <code>Number</code>.
@ -342,7 +348,14 @@ public abstract class NumberFormat extends Format {
* @param number the double number to format
* @param toAppendTo the StringBuffer to which the formatted text is to be
* appended
* @param pos the field position
* @param pos keeps track on the position of the field within the
* returned string. For example, for formatting a number
* {@code 1234567.89} in {@code Locale.US} locale,
* if the given {@code fieldPosition} is
* {@link NumberFormat#INTEGER_FIELD}, the begin index
* and end index of {@code fieldPosition} will be set
* to 0 and 9, respectively for the output string
* {@code 1,234,567.89}.
* @return the formatted StringBuffer
* @exception ArithmeticException if rounding is needed with rounding
* mode being set to RoundingMode.UNNECESSARY
@ -358,7 +371,14 @@ public abstract class NumberFormat extends Format {
* @param number the long number to format
* @param toAppendTo the StringBuffer to which the formatted text is to be
* appended
* @param pos the field position
* @param pos keeps track on the position of the field within the
* returned string. For example, for formatting a number
* {@code 123456789} in {@code Locale.US} locale,
* if the given {@code fieldPosition} is
* {@link NumberFormat#INTEGER_FIELD}, the begin index
* and end index of {@code fieldPosition} will be set
* to 0 and 11, respectively for the output string
* {@code 123,456,789}.
* @return the formatted StringBuffer
* @exception ArithmeticException if rounding is needed with rounding
* mode being set to RoundingMode.UNNECESSARY

View file

@ -942,8 +942,19 @@ public class SimpleDateFormat extends DateFormat {
*
* @param date the date-time value to be formatted into a date-time string.
* @param toAppendTo where the new date-time text is to be appended.
* @param pos the formatting position. On input: an alignment field,
* if desired. On output: the offsets of the alignment field.
* @param pos keeps track on the position of the field within
* the returned string. For example, given a date-time text
* {@code "1996.07.10 AD at 15:08:56 PDT"}, if the given {@code fieldPosition}
* is {@link DateFormat#YEAR_FIELD}, the begin index and end index of
* {@code fieldPosition} will be set to 0 and 4, respectively.
* Notice that if the same date-time field appears more than once in a
* pattern, the {@code fieldPosition} will be set for the first occurrence
* of that date-time field. For instance, formatting a {@code Date} to the
* date-time string {@code "1 PM PDT (Pacific Daylight Time)"} using the
* pattern {@code "h a z (zzzz)"} and the alignment field
* {@link DateFormat#TIMEZONE_FIELD}, the begin index and end index of
* {@code fieldPosition} will be set to 5 and 8, respectively, for the
* first occurrence of the timezone pattern character {@code 'z'}.
* @return the formatted date-time string.
* @exception NullPointerException if any of the parameters is {@code null}.
*/

View file

@ -192,7 +192,8 @@ public interface Collection<E> extends Iterable<E> {
* Returns an array containing all of the elements in this collection.
* If this collection makes any guarantees as to what order its elements
* are returned by its iterator, this method must return the elements in
* the same order.
* the same order. The returned array's {@linkplain Class#getComponentType
* runtime component type} is {@code Object}.
*
* <p>The returned array will be "safe" in that no references to it are
* maintained by this collection. (In other words, this method must
@ -202,7 +203,8 @@ public interface Collection<E> extends Iterable<E> {
* <p>This method acts as bridge between array-based and collection-based
* APIs.
*
* @return an array containing all of the elements in this collection
* @return an array, whose {@linkplain Class#getComponentType runtime component
* type} is {@code Object}, containing all of the elements in this collection
*/
Object[] toArray();
@ -239,14 +241,14 @@ public interface Collection<E> extends Iterable<E> {
* Note that {@code toArray(new Object[0])} is identical in function to
* {@code toArray()}.
*
* @param <T> the runtime type of the array to contain the collection
* @param <T> the component type of the array to contain the collection
* @param a the array into which the elements of this collection are to be
* stored, if it is big enough; otherwise, a new array of the same
* runtime type is allocated for this purpose.
* @return an array containing all of the elements in this collection
* @throws ArrayStoreException if the runtime type of the specified array
* is not a supertype of the runtime type of every element in
* this collection
* @throws ArrayStoreException if the runtime type of any element in this
* collection is not assignable to the {@linkplain Class#getComponentType
* runtime component type} of the specified array
* @throws NullPointerException if the specified array is null
*/
<T> T[] toArray(T[] a);

View file

@ -128,4 +128,25 @@ class JarEntry extends ZipEntry {
public CodeSigner[] getCodeSigners() {
return signers == null ? null : signers.clone();
}
/**
* Returns the real name of this {@code JarEntry}.
*
* If this {@code JarEntry} is an entry of a
* <a href="JarFile.html#multirelease">multi-release jar file</a> and the
* {@code JarFile} is configured to be processed as such, the name returned
* by this method is the path name of the versioned entry that the
* {@code JarEntry} represents, rather than the path name of the base entry
* that {@link #getName()} returns. If the {@code JarEntry} does not represent
* a versioned entry of a multi-release {@code JarFile} or the {@code JarFile}
* is not configured for processing a multi-release jar file, this method
* returns the same name that {@link #getName()} returns.
*
* @return the real name of the JarEntry
*
* @since 10
*/
public String getRealName() {
return super.getName();
}
}

View file

@ -26,6 +26,7 @@
package java.util.jar;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaUtilZipFileAccess;
import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier;
import sun.security.util.SignatureFileVerifier;
@ -45,10 +46,12 @@ import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Collector;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import java.util.zip.ZipEntry;
@ -163,9 +166,13 @@ class JarFile extends ZipFile {
// true if manifest checked for special attributes
private volatile boolean hasCheckedSpecialAttributes;
private static final JavaUtilZipFileAccess JUZFA;
static {
// Set up JavaUtilJarAccess in SharedSecrets
SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
// Get JavaUtilZipFileAccess from SharedSecrets
JUZFA = jdk.internal.misc.SharedSecrets.getJavaUtilZipFileAccess();
// multi-release jar file versions >= 9
BASE_VERSION = Runtime.Version.parse(Integer.toString(8));
BASE_VERSION_MAJOR = BASE_VERSION.major();
@ -424,8 +431,7 @@ class JarFile extends ZipFile {
}
private String[] getMetaInfEntryNames() {
return jdk.internal.misc.SharedSecrets.getJavaUtilZipFileAccess()
.getMetaInfEntryNames((ZipFile)this);
return JUZFA.getMetaInfEntryNames((ZipFile)this);
}
/**
@ -497,47 +503,11 @@ class JarFile extends ZipFile {
* </div>
*/
public ZipEntry getEntry(String name) {
ZipEntry ze = super.getEntry(name);
if (ze != null) {
return new JarFileEntry(ze);
}
// no matching base entry, but maybe there is a versioned entry,
// like a new private class
JarFileEntry je = getEntry0(name);
if (isMultiRelease()) {
ze = new ZipEntry(name);
ZipEntry vze = getVersionedEntry(ze);
if (ze != vze) {
return new JarFileEntry(name, vze);
}
}
return null;
}
private class JarEntryIterator implements Enumeration<JarEntry>,
Iterator<JarEntry>
{
final Enumeration<? extends ZipEntry> e = JarFile.super.entries();
public boolean hasNext() {
return e.hasMoreElements();
}
public JarEntry next() {
ZipEntry ze = e.nextElement();
return new JarFileEntry(ze.getName(), ze);
}
public boolean hasMoreElements() {
return hasNext();
}
public JarEntry nextElement() {
return next();
}
public Iterator<JarEntry> asIterator() {
return this;
return getVersionedEntry(name, je);
}
return je;
}
/**
@ -548,7 +518,7 @@ class JarFile extends ZipFile {
* may be thrown if the jar file has been closed
*/
public Enumeration<JarEntry> entries() {
return new JarEntryIterator();
return JUZFA.entries(this, JarFileEntry::new);
}
/**
@ -561,68 +531,100 @@ class JarFile extends ZipFile {
* @since 1.8
*/
public Stream<JarEntry> stream() {
return StreamSupport.stream(Spliterators.spliterator(
new JarEntryIterator(), size(),
Spliterator.ORDERED | Spliterator.DISTINCT |
Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
}
private ZipEntry searchForVersionedEntry(final int version, String name) {
ZipEntry vze = null;
String sname = "/" + name;
int i = version;
while (i > BASE_VERSION_MAJOR) {
vze = super.getEntry(META_INF_VERSIONS + i + sname);
if (vze != null) break;
i--;
}
return vze;
}
private ZipEntry getVersionedEntry(ZipEntry ze) {
ZipEntry vze = null;
if (BASE_VERSION_MAJOR < versionMajor) {
String name = ze.getName();
if (!name.startsWith(META_INF)) {
vze = searchForVersionedEntry(versionMajor, name);
}
}
return vze == null ? ze : vze;
return JUZFA.stream(this, JarFileEntry::new);
}
/**
* Returns the real name of a {@code JarEntry}. If this {@code JarFile} is
* a multi-release jar file and is configured to be processed as such, the
* name returned by this method is the path name of the versioned entry
* that the {@code JarEntry} represents, rather than the path name of the
* base entry that {@link JarEntry#getName()} returns. If the
* {@code JarEntry} does not represent a versioned entry, or the
* jar file is not a multi-release jar file or {@code JarFile} is not
* configured for processing a multi-release jar file, this method returns
* the same name that {@link JarEntry#getName()} returns.
* Returns a {@code Stream} of the versioned jar file entries.
*
* @param entry the JarEntry
* @return the real name of the JarEntry
* @since 9
* <p>If this {@code JarFile} is a multi-release jar file and is configured to
* be processed as such, then an entry in the stream is the latest versioned entry
* associated with the corresponding base entry name. The maximum version of the
* latest versioned entry is the version returned by {@link #getVersion()}.
* The returned stream may include an entry that only exists as a versioned entry.
*
* If the jar file is not a multi-release jar file or the {@code JarFile} is not
* configured for processing a multi-release jar file, this method returns the
* same stream that {@link #stream()} returns.
*
* @return stream of versioned entries
* @since 10
*/
String getRealName(JarEntry entry) {
if (entry instanceof JarFileEntry) {
return ((JarFileEntry)entry).realName();
public Stream<JarEntry> versionedStream() {
if (isMultiRelease()) {
return JUZFA.entryNameStream(this).map(this::getBasename)
.filter(Objects::nonNull)
.distinct()
.map(this::getJarEntry);
}
return entry.getName();
return stream();
}
/*
* Invokes {@ZipFile}'s getEntry to Return a {@code JarFileEntry} for the
* given entry name or {@code null} if not found.
*/
private JarFileEntry getEntry0(String name) {
return (JarFileEntry)JUZFA.getEntry(this, name, JarFileEntry::new);
}
private String getBasename(String name) {
if (name.startsWith(META_INF_VERSIONS)) {
int off = META_INF_VERSIONS.length();
int index = name.indexOf('/', off);
try {
// filter out dir META-INF/versions/ and META-INF/versions/*/
// and any entry with version > 'version'
if (index == -1 || index == (name.length() - 1) ||
Integer.parseInt(name, off, index, 10) > versionMajor) {
return null;
}
} catch (NumberFormatException x) {
return null; // remove malformed entries silently
}
// map to its base name
return name.substring(index + 1);
}
return name;
}
private JarEntry getVersionedEntry(String name, JarEntry je) {
if (BASE_VERSION_MAJOR < versionMajor) {
if (!name.startsWith(META_INF)) {
// search for versioned entry
int v = versionMajor;
while (v > BASE_VERSION_MAJOR) {
JarFileEntry vje = getEntry0(META_INF_VERSIONS + v + "/" + name);
if (vje != null) {
return vje.withBasename(name);
}
v--;
}
}
}
return je;
}
// placeholder for now
String getRealName(JarEntry entry) {
return entry.getRealName();
}
private class JarFileEntry extends JarEntry {
final private String name;
private String basename;
JarFileEntry(ZipEntry ze) {
super(isMultiRelease() ? getVersionedEntry(ze) : ze);
this.name = ze.getName();
JarFileEntry(String name) {
super(name);
this.basename = name;
}
JarFileEntry(String name, ZipEntry vze) {
super(vze);
this.name = name;
this.basename = name;
}
@Override
public Attributes getAttributes() throws IOException {
Manifest man = JarFile.this.getManifest();
if (man != null) {
@ -631,6 +633,8 @@ class JarFile extends ZipFile {
return null;
}
}
@Override
public Certificate[] getCertificates() {
try {
maybeInstantiateVerifier();
@ -642,6 +646,8 @@ class JarFile extends ZipFile {
}
return certs == null ? null : certs.clone();
}
@Override
public CodeSigner[] getCodeSigners() {
try {
maybeInstantiateVerifier();
@ -653,20 +659,30 @@ class JarFile extends ZipFile {
}
return signers == null ? null : signers.clone();
}
JarFileEntry realEntry() {
if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) {
String entryName = super.getName();
return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this);
}
return this;
}
String realName() {
@Override
public String getRealName() {
return super.getName();
}
@Override
public String getName() {
return name;
return basename;
}
JarFileEntry realEntry() {
if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) {
String entryName = super.getName();
return entryName == basename || entryName.equals(basename) ?
this : new JarFileEntry(entryName, this);
}
return this;
}
// changes the basename, returns "this"
JarFileEntry withBasename(String name) {
basename = name;
return this;
}
}
@ -704,7 +720,6 @@ class JarFile extends ZipFile {
}
}
/*
* Initializes the verifier object by reading all the manifest
* entries and passing them to the verifier.
@ -904,7 +919,7 @@ class JarFile extends ZipFile {
private JarEntry getManEntry() {
if (manEntry == null) {
// First look up manifest entry using standard name
ZipEntry manEntry = super.getEntry(MANIFEST_NAME);
JarEntry manEntry = getEntry0(MANIFEST_NAME);
if (manEntry == null) {
// If not found, then iterate through all the "META-INF/"
// entries to find a match.
@ -912,15 +927,13 @@ class JarFile extends ZipFile {
if (names != null) {
for (String name : names) {
if (MANIFEST_NAME.equals(name.toUpperCase(Locale.ENGLISH))) {
manEntry = super.getEntry(name);
manEntry = getEntry0(name);
break;
}
}
}
}
this.manEntry = (manEntry == null)
? null
: new JarFileEntry(manEntry.getName(), manEntry);
this.manEntry = manEntry;
}
return manEntry;
}
@ -1032,8 +1045,32 @@ class JarFile extends ZipFile {
}
}
JarEntry newEntry(ZipEntry ze) {
return new JarFileEntry(ze);
/*
* Returns a versioned {@code JarFileEntry} for the given entry,
* if there is one. Otherwise returns the original entry. This
* is invoked by the {@code entries2} for verifier.
*/
JarEntry newEntry(JarEntry je) {
if (isMultiRelease()) {
return getVersionedEntry(je.getName(), je);
}
return je;
}
/*
* Returns a versioned {@code JarFileEntry} for the given entry
* name, if there is one. Otherwise returns a {@code JarFileEntry}
* with the given name. It is invoked from JarVerifier's entries2
* for {@code singers}.
*/
JarEntry newEntry(String name) {
if (isMultiRelease()) {
JarEntry vje = getVersionedEntry(name, (JarEntry)null);
if (vje != null) {
return vje;
}
}
return new JarFileEntry(name);
}
Enumeration<String> entryNames(CodeSource[] cs) {
@ -1077,35 +1114,37 @@ class JarFile extends ZipFile {
Enumeration<JarEntry> entries2() {
ensureInitialization();
if (jv != null) {
return jv.entries2(this, super.entries());
return jv.entries2(this, JUZFA.entries(JarFile.this,
JarFileEntry::new));
}
// screen out entries which are never signed
final Enumeration<? extends ZipEntry> enum_ = super.entries();
final var unfilteredEntries = JUZFA.entries(JarFile.this, JarFileEntry::new);
return new Enumeration<>() {
ZipEntry entry;
JarEntry entry;
public boolean hasMoreElements() {
if (entry != null) {
return true;
}
while (enum_.hasMoreElements()) {
ZipEntry ze = enum_.nextElement();
if (JarVerifier.isSigningRelated(ze.getName())) {
while (unfilteredEntries.hasMoreElements()) {
JarEntry je = unfilteredEntries.nextElement();
if (JarVerifier.isSigningRelated(je.getName())) {
continue;
}
entry = ze;
entry = je;
return true;
}
return false;
}
public JarFileEntry nextElement() {
public JarEntry nextElement() {
if (hasMoreElements()) {
ZipEntry ze = entry;
JarEntry je = entry;
entry = null;
return new JarFileEntry(ze);
return newEntry(je);
}
throw new NoSuchElementException();
}

View file

@ -724,10 +724,10 @@ class JarVerifier {
* Like entries() but screens out internal JAR mechanism entries
* and includes signed entries with no ZIP data.
*/
public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration<? extends ZipEntry> e) {
public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration<JarEntry> e) {
final Map<String, CodeSigner[]> map = new HashMap<>();
map.putAll(signerMap());
final Enumeration<? extends ZipEntry> enum_ = e;
final Enumeration<JarEntry> enum_ = e;
return new Enumeration<>() {
Enumeration<String> signers = null;
@ -738,11 +738,11 @@ class JarVerifier {
return true;
}
while (enum_.hasMoreElements()) {
ZipEntry ze = enum_.nextElement();
if (JarVerifier.isSigningRelated(ze.getName())) {
JarEntry je = enum_.nextElement();
if (JarVerifier.isSigningRelated(je.getName())) {
continue;
}
entry = jar.newEntry(ze);
entry = jar.newEntry(je);
return true;
}
if (signers == null) {
@ -750,7 +750,7 @@ class JarVerifier {
}
while (signers.hasMoreElements()) {
String name = signers.nextElement();
entry = jar.newEntry(new ZipEntry(name));
entry = jar.newEntry(name);
return true;
}

View file

@ -60,8 +60,4 @@ class JavaUtilJarAccessImpl implements JavaUtilJarAccess {
public List<Object> getManifestDigests(JarFile jar) {
return jar.getManifestDigests();
}
public String getRealName(JarFile jar, JarEntry entry) {
return jar.getRealName(entry);
}
}

View file

@ -1089,11 +1089,27 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked.
*
* <p>This method operates on the two input streams and binds each stream
* to its source. As a result subsequent modifications to an input stream
* source may not be reflected in the concatenated stream result.
*
* @implNote
* Use caution when constructing streams from repeated concatenation.
* Accessing an element of a deeply concatenated stream can result in deep
* call chains, or even {@code StackOverflowError}.
*
* @apiNote
* To preserve optimization opportunities this method binds each stream to
* its source and accepts only two streams as parameters. For example, the
* exact size of the concatenated stream source can be computed if the exact
* size of each input stream source is known.
* To concatenate more streams without binding, or without nested calls to
* this method, try creating a stream of streams and flat-mapping with the
* identity function, for example:
* <pre>{@code
* DoubleStream concat = Stream.of(s1, s2, s3, s4).flatMapToDouble(s -> s);
* }</pre>
*
* @param a the first stream
* @param b the second stream
* @return the concatenation of the two input streams

View file

@ -1081,11 +1081,27 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked.
*
* <p>This method operates on the two input streams and binds each stream
* to its source. As a result subsequent modifications to an input stream
* source may not be reflected in the concatenated stream result.
*
* @implNote
* Use caution when constructing streams from repeated concatenation.
* Accessing an element of a deeply concatenated stream can result in deep
* call chains, or even {@code StackOverflowError}.
*
* @apiNote
* To preserve optimization opportunities this method binds each stream to
* its source and accepts only two streams as parameters. For example, the
* exact size of the concatenated stream source can be computed if the exact
* size of each input stream source is known.
* To concatenate more streams without binding, or without nested calls to
* this method, try creating a stream of streams and flat-mapping with the
* identity function, for example:
* <pre>{@code
* IntStream concat = Stream.of(s1, s2, s3, s4).flatMapToInt(s -> s);
* }</pre>
*
* @param a the first stream
* @param b the second stream
* @return the concatenation of the two input streams

View file

@ -1086,11 +1086,27 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked.
*
* <p>This method operates on the two input streams and binds each stream
* to its source. As a result subsequent modifications to an input stream
* source may not be reflected in the concatenated stream result.
*
* @implNote
* Use caution when constructing streams from repeated concatenation.
* Accessing an element of a deeply concatenated stream can result in deep
* call chains, or even {@code StackOverflowError}.
*
* @apiNote
* To preserve optimization opportunities this method binds each stream to
* its source and accepts only two streams as parameters. For example, the
* exact size of the concatenated stream source can be computed if the exact
* size of each input stream source is known.
* To concatenate more streams without binding, or without nested calls to
* this method, try creating a stream of streams and flat-mapping with the
* identity function, for example:
* <pre>{@code
* LongStream concat = Stream.of(s1, s2, s3, s4).flatMapToLong(s -> s);
* }</pre>
*
* @param a the first stream
* @param b the second stream
* @return the concatenation of the two input streams

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, 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
@ -1341,6 +1341,10 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked.
*
* <p>This method operates on the two input streams and binds each stream
* to its source. As a result subsequent modifications to an input stream
* source may not be reflected in the concatenated stream result.
*
* @implNote
* Use caution when constructing streams from repeated concatenation.
* Accessing an element of a deeply concatenated stream can result in deep
@ -1349,6 +1353,18 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>Subsequent changes to the sequential/parallel execution mode of the
* returned stream are not guaranteed to be propagated to the input streams.
*
* @apiNote
* To preserve optimization opportunities this method binds each stream to
* its source and accepts only two streams as parameters. For example, the
* exact size of the concatenated stream source can be computed if the exact
* size of each input stream source is known.
* To concatenate more streams without binding, or without nested calls to
* this method, try creating a stream of streams and flat-mapping with the
* identity function, for example:
* <pre>{@code
* Stream<T> concat = Stream.of(s1, s2, s3, s4).flatMap(s -> s);
* }</pre>
*
* @param <T> The type of stream elements
* @param a the first stream
* @param b the second stream

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2017, 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
@ -43,7 +43,34 @@ import sun.nio.cs.ArrayEncoder;
final class ZipCoder {
private static boolean isASCII(byte[] ba, int off, int len) {
for (int i = off; i < off + len; i++) {
if (ba[i] < 0)
return false;
}
return true;
}
private static boolean hasReplaceChar(byte[] ba) {
for (int i = 0; i < ba.length; i++) {
if (ba[i] == (byte)'?')
return true;
}
return false;
}
String toString(byte[] ba, int off, int length) {
// fastpath for UTF-8 cs and ascii only name, leverage the
// compact string impl to avoid the unnecessary char[] copy/
// paste. A temporary workaround before we have better approach,
// such as a String constructor that throws exception for
// malformed and/or unmappable characters, instead of silently
// replacing with repl char
if (isUTF8 && isASCII(ba, off, length)) {
return new String(ba, off, length, cs);
}
CharsetDecoder cd = decoder().reset();
int len = (int)(length * cd.maxCharsPerByte());
char[] ca = new char[len];
@ -78,6 +105,15 @@ final class ZipCoder {
}
byte[] getBytes(String s) {
if (isUTF8) {
// fastpath for UTF8. should only occur when the string
// has malformed surrogates. A postscan should still be
// faster and use less memory.
byte[] ba = s.getBytes(cs);
if (!hasReplaceChar(ba)) {
return ba;
}
}
CharsetEncoder ce = encoder().reset();
char[] ca = s.toCharArray();
int len = (int)(ca.length * ce.maxBytesPerChar());

View file

@ -50,11 +50,15 @@ import java.util.NoSuchElementException;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.WeakHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.jar.JarEntry;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jdk.internal.misc.JavaUtilZipFileAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaIORandomAccessFileAccess;
import jdk.internal.misc.VM;
import jdk.internal.perf.PerfCounter;
@ -296,13 +300,27 @@ class ZipFile implements ZipConstants, Closeable {
* @throws IllegalStateException if the zip file has been closed
*/
public ZipEntry getEntry(String name) {
return getEntry(name, ZipEntry::new);
}
/*
* Returns the zip file entry for the specified name, or null
* if not found.
*
* @param name the name of the entry
* @param func the function that creates the returned entry
*
* @return the zip file entry, or null if not found
* @throws IllegalStateException if the zip file has been closed
*/
private ZipEntry getEntry(String name, Function<String, ? extends ZipEntry> func) {
Objects.requireNonNull(name, "name");
synchronized (this) {
ensureOpen();
byte[] bname = zc.getBytes(name);
int pos = zsrc.getEntryPos(bname, true);
if (pos != -1) {
return getZipEntry(name, bname, pos);
return getZipEntry(name, bname, pos, func);
}
}
return null;
@ -374,12 +392,10 @@ class ZipFile implements ZipConstants, Closeable {
private class ZipFileInflaterInputStream extends InflaterInputStream {
private volatile boolean closeRequested;
private boolean eof = false;
private final ZipFileInputStream zfin;
ZipFileInflaterInputStream(ZipFileInputStream zfin, Inflater inf,
int size) {
super(zfin, inf, size);
this.zfin = zfin;
}
public void close() throws IOException {
@ -416,7 +432,7 @@ class ZipFile implements ZipConstants, Closeable {
public int available() throws IOException {
if (closeRequested)
return 0;
long avail = zfin.size() - inf.getBytesWritten();
long avail = ((ZipFileInputStream)in).size() - inf.getBytesWritten();
return (avail > (long) Integer.MAX_VALUE ?
Integer.MAX_VALUE : (int) avail);
}
@ -466,41 +482,48 @@ class ZipFile implements ZipConstants, Closeable {
return name;
}
private class ZipEntryIterator implements Enumeration<ZipEntry>, Iterator<ZipEntry> {
private class ZipEntryIterator<T extends ZipEntry>
implements Enumeration<T>, Iterator<T> {
private int i = 0;
private final int entryCount;
private final Function<String, T> gen;
public ZipEntryIterator() {
synchronized (ZipFile.this) {
ensureOpen();
this.entryCount = zsrc.total;
}
public ZipEntryIterator(int entryCount, Function<String, T> gen) {
this.entryCount = entryCount;
this.gen = gen;
}
@Override
public boolean hasMoreElements() {
return hasNext();
}
@Override
public boolean hasNext() {
return i < entryCount;
}
public ZipEntry nextElement() {
@Override
public T nextElement() {
return next();
}
public ZipEntry next() {
@Override
@SuppressWarnings("unchecked")
public T next() {
synchronized (ZipFile.this) {
ensureOpen();
if (!hasNext()) {
throw new NoSuchElementException();
}
// each "entry" has 3 ints in table entries
return getZipEntry(null, null, zsrc.getEntryPos(i++ * 3));
return (T)getZipEntry(null, null, zsrc.getEntryPos(i++ * 3), gen);
}
}
public Iterator<ZipEntry> asIterator() {
@Override
public Iterator<T> asIterator() {
return this;
}
}
@ -511,11 +534,51 @@ class ZipFile implements ZipConstants, Closeable {
* @throws IllegalStateException if the zip file has been closed
*/
public Enumeration<? extends ZipEntry> entries() {
return new ZipEntryIterator();
synchronized (this) {
ensureOpen();
return new ZipEntryIterator<ZipEntry>(zsrc.total, ZipEntry::new);
}
}
private Enumeration<JarEntry> entries(Function<String, JarEntry> func) {
synchronized (this) {
ensureOpen();
return new ZipEntryIterator<JarEntry>(zsrc.total, func);
}
}
private class EntrySpliterator<T> extends Spliterators.AbstractSpliterator<T> {
private int index;
private final int fence;
private final IntFunction<T> gen;
EntrySpliterator(int index, int fence, IntFunction<T> gen) {
super((long)fence,
Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.IMMUTABLE |
Spliterator.NONNULL);
this.index = index;
this.fence = fence;
this.gen = gen;
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
if (action == null)
throw new NullPointerException();
if (index >= 0 && index < fence) {
synchronized (ZipFile.this) {
ensureOpen();
action.accept(gen.apply(zsrc.getEntryPos(index++ * 3)));
}
return true;
}
return false;
}
}
/**
* Returns an ordered {@code Stream} over the ZIP file entries.
*
* Entries appear in the {@code Stream} in the order they appear in
* the central directory of the ZIP file.
*
@ -524,17 +587,68 @@ class ZipFile implements ZipConstants, Closeable {
* @since 1.8
*/
public Stream<? extends ZipEntry> stream() {
return StreamSupport.stream(Spliterators.spliterator(
new ZipEntryIterator(), size(),
Spliterator.ORDERED | Spliterator.DISTINCT |
Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
synchronized (this) {
ensureOpen();
return StreamSupport.stream(new EntrySpliterator<>(0, zsrc.total,
pos -> getZipEntry(null, null, pos, ZipEntry::new)), false);
}
}
private String getEntryName(int pos) {
byte[] cen = zsrc.cen;
int nlen = CENNAM(cen, pos);
int clen = CENCOM(cen, pos);
int flag = CENFLG(cen, pos);
if (!zc.isUTF8() && (flag & EFS) != 0) {
return zc.toStringUTF8(cen, pos + CENHDR, nlen);
} else {
return zc.toString(cen, pos + CENHDR, nlen);
}
}
/*
* Returns an ordered {@code Stream} over the zip file entry names.
*
* Entry names appear in the {@code Stream} in the order they appear in
* the central directory of the ZIP file.
*
* @return an ordered {@code Stream} of entry names in this zip file
* @throws IllegalStateException if the zip file has been closed
* @since 10
*/
private Stream<String> entryNameStream() {
synchronized (this) {
ensureOpen();
return StreamSupport.stream(
new EntrySpliterator<>(0, zsrc.total, this::getEntryName), false);
}
}
/*
* Returns an ordered {@code Stream} over the zip file entries.
*
* Entries appear in the {@code Stream} in the order they appear in
* the central directory of the jar file.
*
* @param func the function that creates the returned entry
* @return an ordered {@code Stream} of entries in this zip file
* @throws IllegalStateException if the zip file has been closed
* @since 10
*/
private Stream<JarEntry> stream(Function<String, JarEntry> func) {
synchronized (this) {
ensureOpen();
return StreamSupport.stream(new EntrySpliterator<>(0, zsrc.total,
pos -> (JarEntry)getZipEntry(null, null, pos, func)), false);
}
}
private String lastEntryName;
private int lastEntryPos;
/* Checks ensureOpen() before invoke this method */
private ZipEntry getZipEntry(String name, byte[] bname, int pos) {
private ZipEntry getZipEntry(String name, byte[] bname, int pos,
Function<String, ? extends ZipEntry> func) {
byte[] cen = zsrc.cen;
int nlen = CENNAM(cen, pos);
int elen = CENEXT(cen, pos);
@ -551,7 +665,7 @@ class ZipFile implements ZipConstants, Closeable {
name = zc.toString(cen, pos + CENHDR, nlen);
}
}
ZipEntry e = new ZipEntry(name);
ZipEntry e = func.apply(name); //ZipEntry e = new ZipEntry(name);
e.flag = flag;
e.xdostime = CENTIM(cen, pos);
e.crc = CENCRC(cen, pos);
@ -791,7 +905,6 @@ class ZipFile implements ZipConstants, Closeable {
public long skip(long n) throws IOException {
synchronized (ZipFile.this) {
ensureOpenOrZipException();
initDataOffset();
if (n > rem) {
n = rem;
@ -857,12 +970,33 @@ class ZipFile implements ZipConstants, Closeable {
static {
SharedSecrets.setJavaUtilZipFileAccess(
new JavaUtilZipFileAccess() {
@Override
public boolean startsWithLocHeader(ZipFile zip) {
return zip.zsrc.startsWithLoc;
}
@Override
public String[] getMetaInfEntryNames(ZipFile zip) {
return zip.getMetaInfEntryNames();
}
@Override
public JarEntry getEntry(ZipFile zip, String name,
Function<String, JarEntry> func) {
return (JarEntry)zip.getEntry(name, func);
}
@Override
public Enumeration<JarEntry> entries(ZipFile zip,
Function<String, JarEntry> func) {
return zip.entries(func);
}
@Override
public Stream<JarEntry> stream(ZipFile zip,
Function<String, JarEntry> func) {
return zip.stream(func);
}
@Override
public Stream<String> entryNameStream(ZipFile zip) {
return zip.entryNameStream();
}
}
);
isWindows = VM.getSavedProperty("os.name").contains("Windows");

View file

@ -274,7 +274,7 @@ final class JrtPath implements Path {
if (o.path.length() == 0) {
return this;
}
StringBuilder sb = new StringBuilder(path.length() + o.path.length());
StringBuilder sb = new StringBuilder(path.length() + o.path.length() + 1);
sb.append(path);
if (path.charAt(path.length() - 1) != '/')
sb.append('/');
@ -478,12 +478,15 @@ final class JrtPath implements Path {
// Remove DotSlash(./) and resolve DotDot (..) components
private String getResolved() {
if (path.length() == 0) {
return path;
}
if (path.indexOf('.') == -1) {
int length = path.length();
if (length == 0 || (path.indexOf("./") == -1 && path.charAt(length - 1) != '.')) {
return path;
} else {
return resolvePath();
}
}
private String resolvePath() {
int length = path.length();
char[] to = new char[length];
int nc = getNameCount();

View file

@ -834,7 +834,7 @@ public class URLClassPath {
try {
String nm;
if (jar.isMultiRelease()) {
nm = SharedSecrets.javaUtilJarAccess().getRealName(jar, entry);
nm = entry.getRealName();
} else {
nm = name;
}

View file

@ -41,5 +41,4 @@ public interface JavaUtilJarAccess {
public Enumeration<JarEntry> entries2(JarFile jar);
public void setEagerValidation(JarFile jar, boolean eager);
public List<Object> getManifestDigests(JarFile jar);
public String getRealName(JarFile jar, JarEntry entry);
}

View file

@ -25,10 +25,19 @@
package jdk.internal.misc;
import java.io.IOException;
import java.util.Enumeration;
import java.util.function.Function;
import java.util.jar.JarEntry;
import java.util.stream.Stream;
import java.util.zip.ZipFile;
public interface JavaUtilZipFileAccess {
public boolean startsWithLocHeader(ZipFile zip);
public String[] getMetaInfEntryNames(ZipFile zip);
public JarEntry getEntry(ZipFile zip, String name, Function<String, JarEntry> func);
public Enumeration<JarEntry> entries(ZipFile zip, Function<String, JarEntry> func);
public Stream<JarEntry> stream(ZipFile zip, Function<String, JarEntry> func);
public Stream<String> entryNameStream(ZipFile zip);
}

View file

@ -66,8 +66,6 @@ import java.util.zip.ZipFile;
import jdk.internal.jmod.JmodFile;
import jdk.internal.jmod.JmodFile.Section;
import jdk.internal.perf.PerfCounter;
import jdk.internal.util.jar.VersionedStream;
/**
* A {@code ModuleFinder} that locates modules on the file system by searching
@ -515,7 +513,7 @@ public class ModulePath implements ModuleFinder {
builder.version(vs);
// scan the names of the entries in the JAR file
Map<Boolean, Set<String>> map = VersionedStream.stream(jf)
Map<Boolean, Set<String>> map = jf.versionedStream()
.filter(e -> !e.isDirectory())
.map(JarEntry::getName)
.filter(e -> (e.endsWith(".class") ^ e.startsWith(SERVICES_PREFIX)))
@ -615,7 +613,7 @@ public class ModulePath implements ModuleFinder {
}
private Set<String> jarPackages(JarFile jf) {
return VersionedStream.stream(jf)
return jf.versionedStream()
.filter(e -> !e.isDirectory())
.map(JarEntry::getName)
.map(this::toPackageName)

View file

@ -50,9 +50,7 @@ import java.util.stream.Stream;
import java.util.zip.ZipFile;
import jdk.internal.jmod.JmodFile;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleHashes.HashSupplier;
import jdk.internal.util.jar.VersionedStream;
import sun.net.www.ParseUtil;
@ -250,7 +248,7 @@ class ModuleReferences {
JarEntry je = getEntry(name);
if (je != null) {
if (jf.isMultiRelease())
name = SharedSecrets.javaUtilJarAccess().getRealName(jf, je);
name = je.getRealName();
if (je.isDirectory() && !name.endsWith("/"))
name += "/";
String encodedPath = ParseUtil.encodePath(name, false);
@ -274,7 +272,7 @@ class ModuleReferences {
@Override
Stream<String> implList() throws IOException {
// take snapshot to avoid async close
List<String> names = VersionedStream.stream(jf)
List<String> names = jf.versionedStream()
.map(JarEntry::getName)
.collect(Collectors.toList());
return names.stream();

View file

@ -1,85 +0,0 @@
/*
* Copyright (c) 2016, 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 jdk.internal.util.jar;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Stream;
public class VersionedStream {
private static final String META_INF_VERSIONS = "META-INF/versions/";
/**
* Returns a stream of versioned entries, derived from the base names of
* all entries in a multi-release {@code JarFile} that are present either in
* the base directory or in any versioned directory with a version number
* less than or equal to the {@code Runtime.Version::major} that the
* {@code JarFile} was opened with. These versioned entries are aliases
* for the real entries -- i.e. the names are base names and the content
* may come from a versioned directory entry. If the {@code jarFile} is not
* a multi-release jar, a stream of all entries is returned.
*
* @param jf the input JarFile
* @return stream of entries
* @since 9
*/
public static Stream<JarEntry> stream(JarFile jf) {
if (jf.isMultiRelease()) {
int version = jf.getVersion().major();
return jf.stream()
.map(je -> getBaseSuffix(je, version))
.filter(Objects::nonNull)
.distinct()
.map(jf::getJarEntry);
}
return jf.stream();
}
private static String getBaseSuffix(JarEntry je, int version) {
String name = je.getName();
if (name.startsWith(META_INF_VERSIONS)) {
int len = META_INF_VERSIONS.length();
int index = name.indexOf('/', len);
if (index == -1 || index == (name.length() - 1)) {
// filter out META-INF/versions/* and META-INF/versions/*/
return null;
}
try {
if (Integer.parseInt(name, len, index, 10) > version) {
// not an integer
return null;
}
} catch (NumberFormatException x) {
// silently remove malformed entries
return null;
}
// We know name looks like META-INF/versions/*/*
return name.substring(index + 1);
}
return name;
}
}

View file

@ -210,9 +210,7 @@ module java.base {
jdk.internal.vm.ci,
jdk.incubator.httpclient;
exports jdk.internal.util.jar to
jdk.jartool,
jdk.jdeps,
jdk.jlink;
jdk.jartool;
exports sun.net to
jdk.incubator.httpclient;
exports sun.net.ext to

View file

@ -262,21 +262,9 @@ JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads);
/*
* java.lang.SecurityManager
*/
JNIEXPORT jclass JNICALL
JVM_CurrentLoadedClass(JNIEnv *env);
JNIEXPORT jobject JNICALL
JVM_CurrentClassLoader(JNIEnv *env);
JNIEXPORT jobjectArray JNICALL
JVM_GetClassContext(JNIEnv *env);
JNIEXPORT jint JNICALL
JVM_ClassDepth(JNIEnv *env, jstring name);
JNIEXPORT jint JNICALL
JVM_ClassLoaderDepth(JNIEnv *env);
/*
* java.lang.Package
*/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2017, 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
@ -76,53 +76,3 @@ Java_java_lang_SecurityManager_getClassContext(JNIEnv *env, jobject this)
return JVM_GetClassContext(env);
}
JNIEXPORT jclass JNICALL
Java_java_lang_SecurityManager_currentLoadedClass0(JNIEnv *env, jobject this)
{
/* Make sure the security manager instance is initialized */
if (!check(env, this)) {
return NULL; /* exception */
}
return JVM_CurrentLoadedClass(env);
}
JNIEXPORT jobject JNICALL
Java_java_lang_SecurityManager_currentClassLoader0(JNIEnv *env, jobject this)
{
/* Make sure the security manager instance is initialized */
if (!check(env, this)) {
return NULL; /* exception */
}
return JVM_CurrentClassLoader(env);
}
JNIEXPORT jint JNICALL
Java_java_lang_SecurityManager_classDepth(JNIEnv *env, jobject this,
jstring name)
{
/* Make sure the security manager instance is initialized */
if (!check(env, this)) {
return -1; /* exception */
}
if (name == NULL) {
JNU_ThrowNullPointerException(env, 0);
return -1;
}
return JVM_ClassDepth(env, name);
}
JNIEXPORT jint JNICALL
Java_java_lang_SecurityManager_classLoaderDepth0(JNIEnv *env, jobject this)
{
/* Make sure the security manager instance is initialized */
if (!check(env, this)) {
return -1; /* exception */
}
return JVM_ClassLoaderDepth(env);
}