提交 331bd38a 编写于 作者: C coleenp

Merge

......@@ -28,7 +28,6 @@ package java.lang.reflect;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
......@@ -53,16 +52,14 @@ import sun.security.util.SecurityConstants;
* <p>To create a proxy for some interface {@code Foo}:
* <pre>
* InvocationHandler handler = new MyInvocationHandler(...);
* Class proxyClass = Proxy.getProxyClass(
* Foo.class.getClassLoader(), new Class[] { Foo.class });
* Foo f = (Foo) proxyClass.
* getConstructor(new Class[] { InvocationHandler.class }).
* newInstance(new Object[] { handler });
* Class&lt;?&gt; proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
* Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
* newInstance(handler);
* </pre>
* or more simply:
* <pre>
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
* new Class[] { Foo.class },
* new Class&lt;?&gt;[] { Foo.class },
* handler);
* </pre>
*
......@@ -91,7 +88,11 @@ import sun.security.util.SecurityConstants;
* <p>A proxy class has the following properties:
*
* <ul>
* <li>Proxy classes are public, final, and not abstract.
* <li>Proxy classes are <em>public, final, and not abstract</em> if
* all proxy interfaces are public.</li>
*
* <li>Proxy classes are <em>non-public, final, and not abstract</em> if
* any of the proxy interfaces is non-public.</li>
*
* <li>The unqualified name of a proxy class is unspecified. The space
* of class names that begin with the string {@code "$Proxy"}
......@@ -273,76 +274,17 @@ public class Proxy implements java.io.Serializable {
* @param h the invocation handler for this proxy instance
*/
protected Proxy(InvocationHandler h) {
doNewInstanceCheck();
this.h = h;
}
private static class ProxyAccessHelper {
// The permission is implementation specific.
static final Permission PROXY_PERMISSION =
new ReflectPermission("proxyConstructorNewInstance");
// These system properties are defined to provide a short-term
// workaround if customers need to disable the new security checks.
static final boolean allowNewInstance;
static final boolean allowNullLoader;
static {
allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
}
private static boolean getBooleanProperty(final String key) {
String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(key);
}
});
return Boolean.valueOf(s);
}
static boolean needsNewInstanceCheck(Class<?> proxyClass) {
if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
return false;
}
if (proxyClass.getName().startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
// all proxy interfaces are public
return false;
}
for (Class<?> intf : proxyClass.getInterfaces()) {
if (!Modifier.isPublic(intf.getModifiers())) {
return true;
}
}
return false;
}
}
/*
* Access check on a proxy class that implements any non-public interface.
*
* @throws SecurityException if a security manager exists, and
* the caller does not have the permission.
*/
private void doNewInstanceCheck() {
SecurityManager sm = System.getSecurityManager();
Class<?> proxyClass = this.getClass();
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
try {
sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
} catch (SecurityException e) {
throw new SecurityException("Not allowed to construct a Proxy "
+ "instance that implements a non-public interface", e);
}
}
}
/**
* Returns the {@code java.lang.Class} object for a proxy class
* given a class loader and an array of interfaces. The proxy class
* will be defined by the specified class loader and will implement
* all of the supplied interfaces. If a proxy class for the same
* permutation of interfaces has already been defined by the class
* loader, then the existing proxy class will be returned; otherwise,
* all of the supplied interfaces. If any of the given interfaces
* is non-public, the proxy class will be non-public. If a proxy class
* for the same permutation of interfaces has already been defined by the
* class loader, then the existing proxy class will be returned; otherwise,
* a proxy class for those interfaces will be generated dynamically
* and defined by the class loader.
*
......@@ -407,6 +349,22 @@ public class Proxy implements java.io.Serializable {
* @throws IllegalArgumentException if any of the restrictions on the
* parameters that may be passed to {@code getProxyClass}
* are violated
* @throws SecurityException if a security manager, <em>s</em>, is present
* and any of the following conditions is met:
* <ul>
* <li> the given {@code loader} is {@code null} and
* the caller's class loader is not {@code null} and the
* invocation of {@link SecurityManager#checkPermission
* s.checkPermission} with
* {@code RuntimePermission("getClassLoader")} permission
* denies access.</li>
* <li> the caller's class loader is not the same as or an
* ancestor of the class loader for the current class and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to any one of the
* given proxy interfaces.</li>
* </ul>
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}
*/
......@@ -449,9 +407,7 @@ public class Proxy implements java.io.Serializable {
if (sm != null) {
ClassLoader ccl = caller.getClassLoader();
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
if (!ProxyAccessHelper.allowNullLoader) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
......@@ -593,6 +549,7 @@ public class Proxy implements java.io.Serializable {
try {
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
/*
* Record the package of a non-public proxy interface so that the
......@@ -602,6 +559,7 @@ public class Proxy implements java.io.Serializable {
for (int i = 0; i < interfaces.length; i++) {
int flags = interfaces[i].getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = interfaces[i].getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
......@@ -637,7 +595,7 @@ public class Proxy implements java.io.Serializable {
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces);
proxyName, interfaces, accessFlags);
try {
proxyClass = defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
......@@ -678,12 +636,7 @@ public class Proxy implements java.io.Serializable {
/**
* Returns an instance of a proxy class for the specified interfaces
* that dispatches method invocations to the specified invocation
* handler. This method is equivalent to:
* <pre>
* Proxy.getProxyClass(loader, interfaces).
* getConstructor(new Class[] { InvocationHandler.class }).
* newInstance(new Object[] { handler });
* </pre>
* handler.
*
* <p>{@code Proxy.newProxyInstance} throws
* {@code IllegalArgumentException} for the same reasons that
......@@ -699,6 +652,27 @@ public class Proxy implements java.io.Serializable {
* @throws IllegalArgumentException if any of the restrictions on the
* parameters that may be passed to {@code getProxyClass}
* are violated
* @throws SecurityException if a security manager, <em>s</em>, is present
* and any of the following conditions is met:
* <ul>
* <li> the given {@code loader} is {@code null} and
* the caller's class loader is not {@code null} and the
* invocation of {@link SecurityManager#checkPermission
* s.checkPermission} with
* {@code RuntimePermission("getClassLoader")} permission
* denies access;</li>
* <li> the caller's class loader is not the same as or an
* ancestor of the class loader for the current class and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to any one of the
* given proxy interfaces.</li>
* <li> any of the given proxy interfaces is non-public and the
* caller class is not in the same {@linkplain Package runtime package}
* as the non-public interface and the invocation of
* {@link SecurityManager#checkPermission s.checkPermission} with
* {@code ReflectPermission("newProxyInPackage.{package name}")}
* permission denies access.</li>
* </ul>
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}, or
* if the invocation handler, {@code h}, is
......@@ -728,24 +702,61 @@ public class Proxy implements java.io.Serializable {
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
// create proxy instance with doPrivilege as the proxy class may
// implement non-public interfaces that requires a special permission
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return newInstance(cons, ih);
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
return newInstance(cons, ih);
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
String pcn = proxyClass.getName();
if (pcn.startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
// all proxy interfaces are public
return;
}
ClassLoader ccl = caller.getClassLoader();
ClassLoader pcl = proxyClass.getClassLoader();
// do permission check if the caller is in a different runtime package
// of the proxy class
int n = pcn.lastIndexOf('.');
String pkg = (n == -1) ? "" : pcn.substring(0, n);
n = caller.getName().lastIndexOf('.');
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
if (pcl != ccl || !pkg.equals(callerPkg)) {
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
}
}
}
private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
try {
return cons.newInstance(new Object[] {h} );
......
......@@ -26,12 +26,7 @@
package java.lang.reflect;
/**
* The Permission class for reflective operations. A
* ReflectPermission is a <em>named permission</em> and has no
* actions. The only name currently defined is {@code suppressAccessChecks},
* which allows suppressing the standard Java language access checks
* -- for public, default (package) access, protected, and private
* members -- performed by reflected objects at their point of use.
* The Permission class for reflective operations.
* <P>
* The following table
* provides a summary description of what the permission allows,
......@@ -47,11 +42,21 @@ package java.lang.reflect;
*
* <tr>
* <td>suppressAccessChecks</td>
* <td>ability to access
* fields and invoke methods in a class. Note that this includes
* not only public, but protected and private fields and methods as well.</td>
* <td>ability to suppress the standard Java language access checks
* on fields and methods in a class; allow access not only public members
* but also allow access to default (package) access, protected,
* and private members.</td>
* <td>This is dangerous in that information (possibly confidential) and
* methods normally unavailable would be accessible to malicious code.</td>
* methods normally unavailable would be accessible to malicious code.</td>
* </tr>
* <tr>
* <td>newProxyInPackage.{package name}</td>
* <td>ability to create a proxy instance in the specified package of which
* the non-public interface that the proxy class implements.</td>
* <td>This gives code access to classes in packages to which it normally
* does not have access and the dynamic proxy class is in the system
* protection domain. Malicious code may use these classes to
* help in its attempt to compromise security in the system.</td>
* </tr>
*
* </table>
......@@ -63,6 +68,7 @@ package java.lang.reflect;
* @see Field#set
* @see Method#invoke
* @see Constructor#newInstance
* @see Proxy#newProxyInstance
*
* @since 1.2
*/
......
/*
* Copyright (c) 2012, 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.util;
import java.util.function.DoubleConsumer;
/**
* A state object for collecting statistics such as count, min, max, sum, and
* average.
*
* <p>This class is designed to work with (though does not require)
* {@linkplain java.util.stream streams}. For example, you can compute
* summary statistics on a stream of doubles with:
* <pre> {@code
* DoubleSummaryStatistics stats = doubleStream.collect(DoubleSummaryStatistics::new,
* DoubleSummaryStatistics::accept,
* DoubleSummaryStatistics::combine);
* }</pre>
*
* <p>{@code DoubleSummaryStatistics} can be used as a
* {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction}
* target for a {@linkplain java.util.stream.Stream stream}. For example:
*
* <pre> {@code
* DoubleSummaryStatistics stats = people.stream()
* .collect(Collectors.toDoubleSummaryStatistics(Person::getWeight));
*}</pre>
*
* This computes, in a single pass, the count of people, as well as the minimum,
* maximum, sum, and average of their weights.
*
* @implNote This implementation is not thread safe. However, it is safe to use
* {@link java.util.stream.Collectors#toDoubleSummaryStatistics(java.util.function.ToDoubleFunction)
* Collectors.toDoubleStatistics()} on a parallel stream, because the parallel
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
* provides the necessary partitioning, isolation, and merging of results for
* safe and efficient parallel execution.
* @since 1.8
*/
public class DoubleSummaryStatistics implements DoubleConsumer {
private long count;
private double sum;
private double min = Double.POSITIVE_INFINITY;
private double max = Double.NEGATIVE_INFINITY;
/**
* Construct an empty instance with zero count, zero sum,
* {@code Double.POSITIVE_INFINITY} min, {@code Double.NEGATIVE_INFINITY}
* max and zero average.
*/
public DoubleSummaryStatistics() { }
/**
* Records another value into the summary information.
*
* @param value the input value
*/
@Override
public void accept(double value) {
++count;
sum += value;
min = Math.min(min, value);
max = Math.max(max, value);
}
/**
* Combines the state of another {@code DoubleSummaryStatistics} into this
* one.
*
* @param other another {@code DoubleSummaryStatistics}
* @throws NullPointerException if {@code other} is null
*/
public void combine(DoubleSummaryStatistics other) {
count += other.count;
sum += other.sum;
min = Math.min(min, other.min);
max = Math.max(max, other.max);
}
/**
* Return the count of values recorded.
*
* @return the count of values
*/
public final long getCount() {
return count;
}
/**
* Returns the sum of values recorded, or zero if no values have been
* recorded. The sum returned can vary depending upon the order in which
* values are recorded. This is due to accumulated rounding error in
* addition of values of differing magnitudes. Values sorted by increasing
* absolute magnitude tend to yield more accurate results. If any recorded
* value is a {@code NaN} or the sum is at any point a {@code NaN} then the
* sum will be {@code NaN}.
*
* @return the sum of values, or zero if none
*/
public final double getSum() {
return sum;
}
/**
* Returns the minimum recorded value, {@code Double.NaN} if any recorded
* value was NaN or {@code Double.POSITIVE_INFINITY} if no values were
* recorded. Unlike the numerical comparison operators, this method
* considers negative zero to be strictly smaller than positive zero.
*
* @return the minimum recorded value, {@code Double.NaN} if any recorded
* value was NaN or {@code Double.POSITIVE_INFINITY} if no values were
* recorded
*/
public final double getMin() {
return min;
}
/**
* Returns the maximum recorded value, {@code Double.NaN} if any recorded
* value was NaN or {@code Double.NEGATIVE_INFINITY} if no values were
* recorded. Unlike the numerical comparison operators, this method
* considers negative zero to be strictly smaller than positive zero.
*
* @return the maximum recorded value, {@code Double.NaN} if any recorded
* value was NaN or {@code Double.NEGATIVE_INFINITY} if no values were
* recorded
*/
public final double getMax() {
return max;
}
/**
* Returns the average of values recorded, or zero if no values have been
* recorded. The average returned can vary depending upon the order in
* which values are recorded. This is due to accumulated rounding error in
* addition of values of differing magnitudes. Values sorted by increasing
* absolute magnitude tend to yield more accurate results. If any recorded
* value is a {@code NaN} or the sum is at any point a {@code NaN} then the
* average will be {@code NaN}.
*
* @return the average of values, or zero if none
*/
public final double getAverage() {
return getCount() > 0 ? getSum() / getCount() : 0.0d;
}
/**
* {@inheritDoc}
*
* Returns a non-empty string representation of this object suitable for
* debugging. The exact presentation format is unspecified and may vary
* between implementations and versions.
*/
@Override
public String toString() {
return String.format(
"%s{count=%d, sum=%f, min=%f, average=%f, max=%f}",
this.getClass().getSimpleName(),
getCount(),
getSum(),
getMin(),
getAverage(),
getMax());
}
}
/*
* Copyright (c) 2012, 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.util;
import java.util.function.IntConsumer;
/**
* A state object for collecting statistics such as count, min, max, sum, and
* average.
*
* <p>This class is designed to work with (though does not require)
* {@linkplain java.util.stream streams}. For example, you can compute
* summary statistics on a stream of ints with:
* <pre> {@code
* IntSummaryStatistics stats = intStream.collect(IntSummaryStatistics::new,
* IntSummaryStatistics::accept,
* IntSummaryStatistics::combine);
* }</pre>
*
* <p>{@code IntSummaryStatistics} can be used as a
* {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction}
* target for a {@linkplain java.util.stream.Stream stream}. For example:
*
* <pre> {@code
* IntSummaryStatistics stats = people.stream()
* .collect(Collectors.toIntSummaryStatistics(Person::getDependents));
*}</pre>
*
* This computes, in a single pass, the count of people, as well as the minimum,
* maximum, sum, and average of their number of dependents.
*
* @implNote This implementation is not thread safe. However, it is safe to use
* {@link java.util.stream.Collectors#toIntSummaryStatistics(java.util.function.ToIntFunction)
* Collectors.toIntStatistics()} on a parallel stream, because the parallel
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
* provides the necessary partitioning, isolation, and merging of results for
* safe and efficient parallel execution.
*
* <p>This implementation does not check for overflow of the sum.
* @since 1.8
*/
public class IntSummaryStatistics implements IntConsumer {
private long count;
private long sum;
private int min = Integer.MAX_VALUE;
private int max = Integer.MIN_VALUE;
/**
* Construct an empty instance with zero count, zero sum,
* {@code Integer.MAX_VALUE} min, {@code Integer.MIN_VALUE} max and zero
* average.
*/
public IntSummaryStatistics() { }
/**
* Records a new value into the summary information
*
* @param value the input value
*/
@Override
public void accept(int value) {
++count;
sum += value;
min = Math.min(min, value);
max = Math.max(max, value);
}
/**
* Combines the state of another {@code IntSummaryStatistics} into this one.
*
* @param other another {@code IntSummaryStatistics}
* @throws NullPointerException if {@code other} is null
*/
public void combine(IntSummaryStatistics other) {
count += other.count;
sum += other.sum;
min = Math.min(min, other.min);
max = Math.max(max, other.max);
}
/**
* Returns the count of values recorded.
*
* @return the count of values
*/
public final long getCount() {
return count;
}
/**
* Returns the sum of values recorded, or zero if no values have been
* recorded.
*
* @return the sum of values, or zero if none
*/
public final long getSum() {
return sum;
}
/**
* Returns the minimum value recorded, or {@code Integer.MAX_VALUE} if no
* values have been recorded.
*
* @return the minimum value, or {@code Integer.MAX_VALUE} if none
*/
public final int getMin() {
return min;
}
/**
* Returns the maximum value recorded, or {@code Integer.MIN_VALUE} if no
* values have been recorded.
*
* @return the maximum value, or {@code Integer.MIN_VALUE} if none
*/
public final int getMax() {
return max;
}
/**
* Returns the average of values recorded, or zero if no values have been
* recorded.
*
* @return the average of values, or zero if none
*/
public final double getAverage() {
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
}
@Override
/**
* {@inheritDoc}
*
* Returns a non-empty string representation of this object suitable for
* debugging. The exact presentation format is unspecified and may vary
* between implementations and versions.
*/
public String toString() {
return String.format(
"%s{count=%d, sum=%d, min=%d, average=%d, max=%d}",
this.getClass().getSimpleName(),
getCount(),
getSum(),
getMin(),
getAverage(),
getMax());
}
}
/*
* Copyright (c) 2012, 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.util;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
/**
* A state object for collecting statistics such as count, min, max, sum, and
* average.
*
* <p>This class is designed to work with (though does not require)
* {@linkplain java.util.stream streams}. For example, you can compute
* summary statistics on a stream of longs with:
* <pre> {@code
* LongSummaryStatistics stats = longStream.collect(LongSummaryStatistics::new,
* LongSummaryStatistics::accept,
* LongSummaryStatistics::combine);
* }</pre>
*
* <p>{@code LongSummaryStatistics} can be used as a
* {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction}
* target for a {@linkplain java.util.stream.Stream stream}. For example:
*
* <pre> {@code
* LongSummaryStatistics stats = people.stream()
* .collect(Collectors.toLongSummaryStatistics(Person::getAge));
*}</pre>
*
* This computes, in a single pass, the count of people, as well as the minimum,
* maximum, sum, and average of their ages in milliseconds.
*
* @implNote This implementation is not thread safe. However, it is safe to use
* {@link java.util.stream.Collectors#toLongSummaryStatistics(java.util.function.ToLongFunction)
* Collectors.toLongStatistics()} on a parallel stream, because the parallel
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
* provides the necessary partitioning, isolation, and merging of results for
* safe and efficient parallel execution.
*
* <p>This implementation does not check for overflow of the sum.
* @since 1.8
*/
public class LongSummaryStatistics implements LongConsumer, IntConsumer {
private long count;
private long sum;
private long min = Long.MAX_VALUE;
private long max = Long.MIN_VALUE;
/**
* Construct an empty instance with zero count, zero sum,
* {@code Long.MAX_VALUE} min, {@code Long.MIN_VALUE} max and zero
* average.
*/
public LongSummaryStatistics() { }
/**
* Records a new {@code int} value into the summary information.
*
* @param value the input value
*/
@Override
public void accept(int value) {
accept((long) value);
}
/**
* Records a new {@code long} value into the summary information.
*
* @param value the input value
*/
@Override
public void accept(long value) {
++count;
sum += value;
min = Math.min(min, value);
max = Math.max(max, value);
}
/**
* Combines the state of another {@code LongSummaryStatistics} into this
* one.
*
* @param other another {@code LongSummaryStatistics}
* @throws NullPointerException if {@code other} is null
*/
public void combine(LongSummaryStatistics other) {
count += other.count;
sum += other.sum;
min = Math.min(min, other.min);
max = Math.max(max, other.max);
}
/**
* Returns the count of values recorded.
*
* @return the count of values
*/
public final long getCount() {
return count;
}
/**
* Returns the sum of values recorded, or zero if no values have been
* recorded.
*
* @return the sum of values, or zero if none
*/
public final long getSum() {
return sum;
}
/**
* Returns the minimum value recorded, or {@code Long.MAX_VALUE} if no
* values have been recorded.
*
* @return the minimum value, or {@code Long.MAX_VALUE} if none
*/
public final long getMin() {
return min;
}
/**
* Returns the maximum value recorded, or {@code Long.MIN_VALUE} if no
* values have been recorded
*
* @return the maximum value, or {@code Long.MIN_VALUE} if none
*/
public final long getMax() {
return max;
}
/**
* Returns the average of values recorded, or zero if no values have been
* recorded.
*
* @return The average of values, or zero if none
*/
public final double getAverage() {
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
}
@Override
/**
* {@inheritDoc}
*
* Returns a non-empty string representation of this object suitable for
* debugging. The exact presentation format is unspecified and may vary
* between implementations and versions.
*/
public String toString() {
return String.format(
"%s{count=%d, sum=%d, min=%d, average=%d, max=%d}",
this.getClass().getSimpleName(),
getCount(),
getSum(),
getMin(),
getAverage(),
getMax());
}
}
......@@ -27,11 +27,14 @@ package sun.misc;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
......@@ -314,12 +317,25 @@ public class ProxyGenerator {
"sun.misc.ProxyGenerator.saveGeneratedFiles")).booleanValue();
/**
* Generate a proxy class given a name and a list of proxy interfaces.
* Generate a public proxy class given a name and a list of proxy interfaces.
*/
public static byte[] generateProxyClass(final String name,
Class[] interfaces)
Class<?>[] interfaces) {
return generateProxyClass(name, interfaces, (ACC_PUBLIC | ACC_FINAL | ACC_SUPER));
}
/**
* Generate a proxy class given a name and a list of proxy interfaces.
*
* @param name the class name of the proxy class
* @param interfaces proxy interfaces
* @param accessFlags access flags of the proxy class
*/
public static byte[] generateProxyClass(final String name,
Class<?>[] interfaces,
int accessFlags)
{
ProxyGenerator gen = new ProxyGenerator(name, interfaces);
ProxyGenerator gen = new ProxyGenerator(name, interfaces, accessFlags);
final byte[] classFile = gen.generateClassFile();
if (saveGeneratedFiles) {
......@@ -327,10 +343,16 @@ public class ProxyGenerator {
new java.security.PrivilegedAction<Void>() {
public Void run() {
try {
FileOutputStream file =
new FileOutputStream(dotToSlash(name) + ".class");
file.write(classFile);
file.close();
int i = name.lastIndexOf('.');
Path path;
if (i > 0) {
Path dir = Paths.get(name.substring(0, i).replace('.', File.separatorChar));
Files.createDirectories(dir);
path = dir.resolve(name.substring(i+1, name.length()) + ".class");
} else {
path = Paths.get(name + ".class");
}
Files.write(path, classFile);
return null;
} catch (IOException e) {
throw new InternalError(
......@@ -364,21 +386,23 @@ public class ProxyGenerator {
/** proxy interfaces */
private Class[] interfaces;
/** proxy class access flags */
private int accessFlags;
/** constant pool of class being generated */
private ConstantPool cp = new ConstantPool();
/** FieldInfo struct for each field of generated class */
private List<FieldInfo> fields = new ArrayList<FieldInfo>();
private List<FieldInfo> fields = new ArrayList<>();
/** MethodInfo struct for each method of generated class */
private List<MethodInfo> methods = new ArrayList<MethodInfo>();
private List<MethodInfo> methods = new ArrayList<>();
/**
* maps method signature string to list of ProxyMethod objects for
* proxy methods with that signature
*/
private Map<String, List<ProxyMethod>> proxyMethods =
new HashMap<String,List<ProxyMethod>>();
private Map<String, List<ProxyMethod>> proxyMethods = new HashMap<>();
/** count of ProxyMethod objects added to proxyMethods */
private int proxyMethodCount = 0;
......@@ -390,9 +414,10 @@ public class ProxyGenerator {
* A ProxyGenerator object contains the state for the ongoing
* generation of a particular proxy class.
*/
private ProxyGenerator(String className, Class[] interfaces) {
private ProxyGenerator(String className, Class<?>[] interfaces, int accessFlags) {
this.className = className;
this.interfaces = interfaces;
this.accessFlags = accessFlags;
}
/**
......@@ -422,10 +447,9 @@ public class ProxyGenerator {
* earlier interfaces precedence over later ones with duplicate
* methods.
*/
for (int i = 0; i < interfaces.length; i++) {
Method[] methods = interfaces[i].getMethods();
for (int j = 0; j < methods.length; j++) {
addProxyMethod(methods[j], interfaces[i]);
for (Class<?> intf : interfaces) {
for (Method m : intf.getMethods()) {
addProxyMethod(m, intf);
}
}
......@@ -480,8 +504,8 @@ public class ProxyGenerator {
*/
cp.getClass(dotToSlash(className));
cp.getClass(superclassName);
for (int i = 0; i < interfaces.length; i++) {
cp.getClass(dotToSlash(interfaces[i].getName()));
for (Class<?> intf: interfaces) {
cp.getClass(dotToSlash(intf.getName()));
}
/*
......@@ -508,7 +532,7 @@ public class ProxyGenerator {
cp.write(dout); // (write constant pool)
// u2 access_flags;
dout.writeShort(ACC_PUBLIC | ACC_FINAL | ACC_SUPER);
dout.writeShort(accessFlags);
// u2 this_class;
dout.writeShort(cp.getClass(dotToSlash(className)));
// u2 super_class;
......@@ -517,9 +541,9 @@ public class ProxyGenerator {
// u2 interfaces_count;
dout.writeShort(interfaces.length);
// u2 interfaces[interfaces_count];
for (int i = 0; i < interfaces.length; i++) {
for (Class<?> intf : interfaces) {
dout.writeShort(cp.getClass(
dotToSlash(interfaces[i].getName())));
dotToSlash(intf.getName())));
}
// u2 fields_count;
......@@ -576,7 +600,7 @@ public class ProxyGenerator {
* compatibly with the throws clauses of both
* overridden methods.
*/
List<Class<?>> legalExceptions = new ArrayList<Class<?>>();
List<Class<?>> legalExceptions = new ArrayList<>();
collectCompatibleTypes(
exceptionTypes, pm.exceptionTypes, legalExceptions);
collectCompatibleTypes(
......@@ -588,7 +612,7 @@ public class ProxyGenerator {
}
}
} else {
sigmethods = new ArrayList<ProxyMethod>(3);
sigmethods = new ArrayList<>(3);
proxyMethods.put(sig, sigmethods);
}
sigmethods.add(new ProxyMethod(name, parameterTypes, returnType,
......@@ -618,7 +642,7 @@ public class ProxyGenerator {
* List of return types that are not yet known to be
* assignable from ("covered" by) any of the others.
*/
LinkedList<Class<?>> uncoveredReturnTypes = new LinkedList<Class<?>>();
LinkedList<Class<?>> uncoveredReturnTypes = new LinkedList<>();
nextNewReturnType:
for (ProxyMethod pm : methods) {
......@@ -833,8 +857,8 @@ public class ProxyGenerator {
// u2 number_of_exceptions;
out.writeShort(declaredExceptions.length);
// u2 exception_index_table[number_of_exceptions];
for (int i = 0; i < declaredExceptions.length; i++) {
out.writeShort(declaredExceptions[i]);
for (short value : declaredExceptions) {
out.writeShort(value);
}
}
......@@ -1525,11 +1549,11 @@ public class ProxyGenerator {
Class<?>[] with,
List<Class<?>> list)
{
for (int i = 0; i < from.length; i++) {
if (!list.contains(from[i])) {
for (int j = 0; j < with.length; j++) {
if (with[j].isAssignableFrom(from[i])) {
list.add(from[i]);
for (Class<?> fc: from) {
if (!list.contains(fc)) {
for (Class<?> wc: with) {
if (wc.isAssignableFrom(fc)) {
list.add(fc);
break;
}
}
......@@ -1559,15 +1583,14 @@ public class ProxyGenerator {
* need to be caught.
*/
private static List<Class<?>> computeUniqueCatchList(Class<?>[] exceptions) {
List<Class<?>> uniqueList = new ArrayList<Class<?>>();
List<Class<?>> uniqueList = new ArrayList<>();
// unique exceptions to catch
uniqueList.add(Error.class); // always catch/rethrow these
uniqueList.add(RuntimeException.class);
nextException:
for (int i = 0; i < exceptions.length; i++) {
Class<?> ex = exceptions[i];
for (Class<?> ex: exceptions) {
if (ex.isAssignableFrom(Throwable.class)) {
/*
* If Throwable is declared to be thrown by the proxy method,
......
......@@ -30,6 +30,8 @@ import java.util.*;
import java.nio.ByteBuffer;
import java.nio.BufferUnderflowException;
import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.reflect.ConstantPool;
import sun.reflect.generics.parser.SignatureParser;
......@@ -253,12 +255,15 @@ public class AnnotationParser {
* Returns an annotation of the given type backed by the given
* member -> value map.
*/
public static Annotation annotationForMap(
Class<? extends Annotation> type, Map<String, Object> memberValues)
public static Annotation annotationForMap(final Class<? extends Annotation> type,
final Map<String, Object> memberValues)
{
return (Annotation) Proxy.newProxyInstance(
type.getClassLoader(), new Class<?>[] { type },
new AnnotationInvocationHandler(type, memberValues));
return AccessController.doPrivileged(new PrivilegedAction<Annotation>() {
public Annotation run() {
return (Annotation) Proxy.newProxyInstance(
type.getClassLoader(), new Class<?>[] { type },
new AnnotationInvocationHandler(type, memberValues));
}});
}
/**
......
......@@ -48,6 +48,7 @@ import java.security.AccessController;
import java.security.MessageDigest;
import java.security.DigestOutputStream;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
......@@ -140,17 +141,20 @@ public final class Util {
return createStub(remoteClass, clientRef);
}
ClassLoader loader = implClass.getClassLoader();
Class[] interfaces = getRemoteInterfaces(implClass);
InvocationHandler handler =
final ClassLoader loader = implClass.getClassLoader();
final Class[] interfaces = getRemoteInterfaces(implClass);
final InvocationHandler handler =
new RemoteObjectInvocationHandler(clientRef);
/* REMIND: private remote interfaces? */
try {
return (Remote) Proxy.newProxyInstance(loader,
interfaces,
handler);
return AccessController.doPrivileged(new PrivilegedAction<Remote>() {
public Remote run() {
return (Remote) Proxy.newProxyInstance(loader,
interfaces,
handler);
}});
} catch (IllegalArgumentException e) {
throw new StubNotFoundException("unable to create proxy", e);
}
......
......@@ -130,8 +130,12 @@ public abstract class ProviderSkeleton implements InvocationHandler, Provider {
*/
@SuppressWarnings("unchecked")
public <T extends Provider> T newProxyInstance() {
return (T)Proxy.newProxyInstance(providerType.getClassLoader(),
new Class<?>[] { providerType }, this);
final InvocationHandler ih = this;
return AccessController.doPrivileged(new PrivilegedAction<T>() {
public T run() {
return (T)Proxy.newProxyInstance(providerType.getClassLoader(),
new Class<?>[] { providerType }, ih);
}});
}
/**
......
/*
* Copyright (c) 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.
*
* 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.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.lang.reflect.ReflectPermission;
import java.security.AccessControlException;
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.security.SecurityPermission;
import java.util.*;
/*
* @test
* @bug 8004260
* @summary Test proxy classes that implement non-public interface
*
* @build p.Foo
* @run main/othervm NonPublicProxyClass grant
* @run main/othervm NonPublicProxyClass deny
* @run main/othervm NonPublicProxyClass
*/
public class NonPublicProxyClass {
public interface PublicInterface {
void foo();
}
interface NonPublicInterface {
void bar();
}
public static void main(String[] args) throws Exception {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class<?> zipConstantsClass = Class.forName("java.util.zip.ZipConstants", false, null);
Class<?> fooClass = Class.forName("p.Foo");
NonPublicProxyClass test1 =
new NonPublicProxyClass(loader, PublicInterface.class, NonPublicInterface.class);
NonPublicProxyClass test2 =
new NonPublicProxyClass(loader, fooClass, PublicInterface.class);
NonPublicProxyClass test3 =
new NonPublicProxyClass(null, zipConstantsClass);
if (args.length == 1) {
switch (args[0]) {
case "grant": Policy.setPolicy(new NewInstancePolicy(true));
break;
case "deny" : Policy.setPolicy(new NewInstancePolicy(false));
break;
default: throw new IllegalArgumentException(args[0]);
}
System.setSecurityManager(new SecurityManager());
}
test1.run();
test2.run();
test3.run();
System.out.format("Test passed: security %s%n",
(args.length == 0 ? "manager not installed" : Policy.getPolicy()));
}
private final ClassLoader loader;
private final Class<?>[] interfaces;
private final InvocationHandler handler = newInvocationHandler();
private Class<?> proxyClass;
public NonPublicProxyClass(ClassLoader loader, Class<?> ... intfs) {
this.loader = loader;
this.interfaces = intfs;
}
public void run() throws Exception {
boolean hasAccess = loader != null || hasAccess();
try {
proxyClass = Proxy.getProxyClass(loader, interfaces);
if (!hasAccess) {
throw new RuntimeException("should have no permission to create proxy class");
}
} catch (AccessControlException e) {
if (hasAccess) {
throw e;
}
if (e.getPermission().getClass() != RuntimePermission.class ||
!e.getPermission().getName().equals("getClassLoader")) {
throw e;
}
return;
}
if (Modifier.isPublic(proxyClass.getModifiers())) {
throw new RuntimeException(proxyClass + " must be non-public");
}
newProxyInstance();
newInstanceFromConstructor(proxyClass);
}
private boolean hasAccess() {
if (System.getSecurityManager() == null) {
return true;
}
NewInstancePolicy policy = NewInstancePolicy.class.cast(Policy.getPolicy());
return policy.grant;
}
private final static String NEW_PROXY_IN_PKG = "newProxyInPackage.";
private void newProxyInstance() {
// expect newProxyInstance to succeed if it's in the same runtime package
int i = proxyClass.getName().lastIndexOf('.');
String pkg = (i != -1) ? proxyClass.getName().substring(0, i) : "";
boolean hasAccess = pkg.isEmpty() || hasAccess();
try {
Proxy.newProxyInstance(loader, interfaces, handler);
if (!hasAccess) {
throw new RuntimeException("ERROR: Proxy.newProxyInstance should fail " + proxyClass);
}
} catch (AccessControlException e) {
if (hasAccess) {
throw e;
}
if (e.getPermission().getClass() != ReflectPermission.class ||
!e.getPermission().getName().equals(NEW_PROXY_IN_PKG + pkg)) {
throw e;
}
}
}
private void newInstanceFromConstructor(Class<?> proxyClass)
throws Exception
{
// expect newInstance to succeed if it's in the same runtime package
boolean isSamePackage = proxyClass.getName().lastIndexOf('.') == -1;
try {
Constructor cons = proxyClass.getConstructor(InvocationHandler.class);
cons.newInstance(newInvocationHandler());
if (!isSamePackage) {
throw new RuntimeException("ERROR: Constructor.newInstance should not succeed");
}
} catch (IllegalAccessException e) {
if (isSamePackage) {
throw e;
}
}
}
private static InvocationHandler newInvocationHandler() {
return new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Class<?>[] intfs = proxy.getClass().getInterfaces();
System.out.println("Proxy for " + Arrays.toString(intfs)
+ " " + method.getName() + " is being invoked");
return null;
}
};
}
static class NewInstancePolicy extends Policy {
final PermissionCollection permissions = new Permissions();
final boolean grant;
NewInstancePolicy(boolean grant) {
this.grant = grant;
permissions.add(new SecurityPermission("getPolicy"));
if (grant) {
permissions.add(new RuntimePermission("getClassLoader"));
permissions.add(new ReflectPermission(NEW_PROXY_IN_PKG + "p"));
permissions.add(new ReflectPermission(NEW_PROXY_IN_PKG + "java.util.zip"));
}
}
public PermissionCollection getPermissions(ProtectionDomain domain) {
return permissions;
}
public PermissionCollection getPermissions(CodeSource codesource) {
return permissions;
}
public boolean implies(ProtectionDomain domain, Permission perm) {
return permissions.implies(perm);
}
public String toString() {
StringBuilder sb = new StringBuilder("policy: ");
Enumeration<Permission> perms = permissions.elements();
while (perms.hasMoreElements()) {
sb.append("\n").append(perms.nextElement().toString());
}
return sb.toString();
}
}
}
/*
* Copyright (c) 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.
*
* 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.lang.reflect.*;
import java.security.*;
import java.util.Arrays;
/*
* @test
* @bug 8004260
* @summary Test making a proxy instance that implements a non-public
* interface with and without security manager installed
* @build p.Foo p.Bar
* @run main SimpleProxy
*/
public class SimpleProxy {
public static void main(String[] args) throws Exception {
ClassLoader loader = SimpleProxy.class.getClassLoader();
Class<?> fooClass = Class.forName("p.Foo");
Class<?> barClass = Class.forName("p.Bar");
makeProxy(loader, fooClass);
System.setSecurityManager(new SecurityManager());
try {
makeProxy(loader, barClass);
throw new RuntimeException("should fail to new proxy instance of a non-public interface");
} catch (AccessControlException e) {
if (e.getPermission().getClass() != ReflectPermission.class ||
!e.getPermission().getName().equals("newProxyInPackage.p")) {
throw e;
}
}
}
private static void makeProxy(ClassLoader loader, Class<?> cls) {
Class<?>[] intfs = new Class<?>[] { cls };
Proxy.newProxyInstance(loader, intfs, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Class<?>[] intfs = proxy.getClass().getInterfaces();
System.out.println("Proxy for " + Arrays.toString(intfs)
+ " " + method.getName() + " is being invoked");
return null;
}
});
}
}
/*
* Copyright (c) 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.
*
* 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 p;
interface Bar {
}
/*
* Copyright (c) 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.
*
* 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 p;
interface Foo {
}
......@@ -16,6 +16,9 @@ grant {
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
permission java.lang.reflect.ReflectPermission "newProxyInPackage.";
permission java.lang.reflect.ReflectPermission "newProxyInPackage.java.util.zip";
// used by TestLibrary to determine test environment
permission java.util.PropertyPermission "test.classes", "read";
permission java.util.PropertyPermission "test.src", "read";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册