mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-07 22:50:49 +00:00
8150782: findClass / accessClass throw unexpected exceptions
Reviewed-by: sundar
This commit is contained in:
parent
1c1cec5a6f
commit
bfb7e8cd07
@ -99,13 +99,16 @@ public class MethodHandles {
|
||||
* <p>
|
||||
* As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
|
||||
* of this lookup object will be {@link java.lang.Object}.
|
||||
* Consequently, the lookup context of this lookup object will be the bootstrap
|
||||
* class loader, which means it cannot find user classes.
|
||||
*
|
||||
* <p style="font-size:smaller;">
|
||||
* <em>Discussion:</em>
|
||||
* The lookup class can be changed to any other class {@code C} using an expression of the form
|
||||
* {@link Lookup#in publicLookup().in(C.class)}.
|
||||
* Since all classes have equal access to public names,
|
||||
* such a change would confer no new access rights.
|
||||
* such a change would confer no new access rights,
|
||||
* but may change the lookup context by virtue of changing the class loader.
|
||||
* A public lookup object is always subject to
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
|
||||
* Also, it cannot access
|
||||
@ -641,6 +644,11 @@ public class MethodHandles {
|
||||
* then no members, not even public members, will be accessible.
|
||||
* (In all other cases, public members will continue to be accessible.)
|
||||
* </ul>
|
||||
* <p>
|
||||
* The resulting lookup's capabilities for loading classes
|
||||
* (used during {@link #findClass} invocations)
|
||||
* are determined by the lookup class' loader,
|
||||
* which may change due to this operation.
|
||||
*
|
||||
* @param requestedLookupClass the desired lookup class for the new lookup object
|
||||
* @return a lookup object which reports the desired lookup class
|
||||
@ -939,13 +947,17 @@ assertEquals("[x, y, z]", pb.command().toString());
|
||||
/**
|
||||
* Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
|
||||
* initializer of the class is not run.
|
||||
* <p>
|
||||
* The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
|
||||
* loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
|
||||
* load the requested class, and then determines whether the class is accessible to this lookup object.
|
||||
*
|
||||
* @param targetName the fully qualified name of the class to be looked up.
|
||||
* @return the requested class.
|
||||
* @exception SecurityException if a security manager is present and it
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws LinkageError if the linkage fails
|
||||
* @throws ClassNotFoundException if the class does not exist.
|
||||
* @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
|
||||
* @throws IllegalAccessException if the class is not accessible, using the allowed access
|
||||
* modes.
|
||||
* @exception SecurityException if a security manager is present and it
|
||||
@ -960,6 +972,9 @@ assertEquals("[x, y, z]", pb.command().toString());
|
||||
/**
|
||||
* Determines if a class can be accessed from the lookup context defined by this {@code Lookup} object. The
|
||||
* static initializer of the class is not run.
|
||||
* <p>
|
||||
* The lookup context here is determined by the {@linkplain #lookupClass() lookup class} and the
|
||||
* {@linkplain #lookupModes() lookup modes}.
|
||||
*
|
||||
* @param targetClass the class to be access-checked
|
||||
*
|
||||
|
||||
80
jdk/test/java/lang/invoke/t8150782/TestAccessClass.java
Normal file
80
jdk/test/java/lang/invoke/t8150782/TestAccessClass.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @compile TestAccessClass.java TestCls.java
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestAccessClass
|
||||
*/
|
||||
package test.java.lang.invoke.t8150782;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
|
||||
import static org.testng.AssertJUnit.*;
|
||||
|
||||
import org.testng.annotations.*;
|
||||
|
||||
public class TestAccessClass {
|
||||
|
||||
private static boolean initializedClass1;
|
||||
|
||||
private static class Class1 {
|
||||
static {
|
||||
initializedClass1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializerNotRun() throws IllegalAccessException {
|
||||
lookup().accessClass(Class1.class);
|
||||
assertFalse(initializedClass1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsSameClass() throws IllegalAccessException, ClassNotFoundException {
|
||||
Class<?> aClass = lookup().accessClass(Class1.class);
|
||||
assertEquals(Class1.class, aClass);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
Object[][] illegalAccessAccess() {
|
||||
return new Object[][] {
|
||||
{publicLookup(), Class1.class},
|
||||
{publicLookup(), TestCls.getPrivateSIC()}
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "illegalAccessAccess", expectedExceptions = {IllegalAccessException.class})
|
||||
public void illegalAccessExceptionTest(Lookup lookup, Class<?> klass) throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup.accessClass(klass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void okAccess() throws IllegalAccessException {
|
||||
lookup().accessClass(TestCls.getPrivateSIC());
|
||||
}
|
||||
|
||||
}
|
||||
38
jdk/test/java/lang/invoke/t8150782/TestCls.java
Normal file
38
jdk/test/java/lang/invoke/t8150782/TestCls.java
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 test.java.lang.invoke.t8150782;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
|
||||
public class TestCls {
|
||||
|
||||
public static final Lookup LOOKUP = lookup();
|
||||
|
||||
private static class PrivateSIC {}
|
||||
public static Class getPrivateSIC() { return PrivateSIC.class; }
|
||||
public static Lookup getLookupForPrivateSIC() { return lookup(); }
|
||||
|
||||
}
|
||||
|
||||
90
jdk/test/java/lang/invoke/t8150782/TestFindClass.java
Normal file
90
jdk/test/java/lang/invoke/t8150782/TestFindClass.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @compile TestFindClass.java TestCls.java
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestFindClass
|
||||
*/
|
||||
package test.java.lang.invoke.t8150782;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
|
||||
import static org.testng.AssertJUnit.*;
|
||||
|
||||
import org.testng.annotations.*;
|
||||
|
||||
public class TestFindClass {
|
||||
|
||||
private static final String PACKAGE_PREFIX = "test.java.lang.invoke.t8150782.";
|
||||
|
||||
private static boolean initializedClass1;
|
||||
|
||||
private static class Class1 {
|
||||
static {
|
||||
initializedClass1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializerNotRun() throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup().findClass(PACKAGE_PREFIX + "TestFindClass$Class1");
|
||||
assertFalse(initializedClass1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsRequestedClass() throws IllegalAccessException, ClassNotFoundException {
|
||||
Class<?> aClass = lookup().findClass(PACKAGE_PREFIX + "TestFindClass$Class1");
|
||||
assertEquals(Class1.class, aClass);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = {ClassNotFoundException.class})
|
||||
public void classNotFoundExceptionTest() throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup().findClass(PACKAGE_PREFIX + "TestFindClass$NonExistent");
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
Object[][] illegalAccessFind() {
|
||||
return new Object[][] {
|
||||
{publicLookup(), PACKAGE_PREFIX + "TestFindClass$Class1"},
|
||||
{publicLookup(), PACKAGE_PREFIX + "TestCls$PrivateSIC"}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assertion: @throws IllegalAccessException if the class is not accessible, using the allowed access modes.
|
||||
*/
|
||||
@Test(dataProvider = "illegalAccessFind", expectedExceptions = {ClassNotFoundException.class})
|
||||
public void illegalAccessExceptionTest(Lookup lookup, String className) throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup.findClass(className);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void okAccess() throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup().findClass(PACKAGE_PREFIX + "TestCls$PrivateSIC");
|
||||
}
|
||||
|
||||
}
|
||||
67
jdk/test/java/lang/invoke/t8150782/TestLookup.java
Normal file
67
jdk/test/java/lang/invoke/t8150782/TestLookup.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestLookup
|
||||
*/
|
||||
package test.java.lang.invoke.t8150782;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
|
||||
import static org.testng.AssertJUnit.*;
|
||||
|
||||
public class TestLookup {
|
||||
|
||||
@Test
|
||||
public void testClassLoaderChange() {
|
||||
Lookup lookup = lookup();
|
||||
assertNotNull(lookup.lookupClass().getClassLoader());
|
||||
Lookup lookup2 = lookup.in(Object.class);
|
||||
assertNull(lookup2.lookupClass().getClassLoader());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = {ClassNotFoundException.class})
|
||||
public void testPublicCannotLoadUserClass() throws IllegalAccessException, ClassNotFoundException {
|
||||
Lookup lookup = publicLookup();
|
||||
lookup.findClass("test.java.lang.invoke.t8150782.TestCls");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicCanLoadSystemClass() throws IllegalAccessException, ClassNotFoundException {
|
||||
Lookup lookup = publicLookup();
|
||||
lookup.findClass("java.util.HashMap");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicInChangesClassLoader() {
|
||||
Lookup lookup = publicLookup();
|
||||
assertNull(lookup.lookupClass().getClassLoader());
|
||||
Lookup lookup2 = lookup.in(TestCls.class);
|
||||
assertNotNull(lookup2.lookupClass().getClassLoader());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user