Skip to content

Commit

Permalink
8199940: Print more information about class loaders in IllegalAccessE…
Browse files Browse the repository at this point in the history
…rrors

Reviewed-by: lfoltan, mchung
  • Loading branch information
GoeLin committed Jun 27, 2018
1 parent 1e4a26c commit cad47f4
Show file tree
Hide file tree
Showing 10 changed files with 762 additions and 38 deletions.
17 changes: 13 additions & 4 deletions src/hotspot/share/classfile/classFileParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4612,12 +4612,17 @@ static void check_super_class_access(const InstanceKlass* this_klass, TRAPS) {
InstanceKlass::cast(super),
vca_result);
if (msg == NULL) {
bool same_module = (this_klass->module() == super->module());
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(),
"class %s cannot access its superclass %s",
"class %s cannot access its %ssuperclass %s (%s%s%s)",
this_klass->external_name(),
super->external_name());
super->is_abstract() ? "abstract " : "",
super->external_name(),
(same_module) ? this_klass->joint_in_module_of_loader(super) : this_klass->class_in_module_of_loader(),
(same_module) ? "" : "; ",
(same_module) ? "" : super->class_in_module_of_loader());
} else {
// Add additional message content.
Exceptions::fthrow(
Expand Down Expand Up @@ -4646,12 +4651,16 @@ static void check_super_interface_access(const InstanceKlass* this_klass, TRAPS)
InstanceKlass::cast(k),
vca_result);
if (msg == NULL) {
bool same_module = (this_klass->module() == k->module());
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(),
"class %s cannot access its superinterface %s",
"class %s cannot access its superinterface %s (%s%s%s)",
this_klass->external_name(),
k->external_name());
k->external_name(),
(same_module) ? this_klass->joint_in_module_of_loader(k) : this_klass->class_in_module_of_loader(),
(same_module) ? "" : "; ",
(same_module) ? "" : k->class_in_module_of_loader());
} else {
// Add additional message content.
Exceptions::fthrow(
Expand Down
27 changes: 20 additions & 7 deletions src/hotspot/share/interpreter/linkResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ void CallInfo::verify() {
fatal("Unexpected call kind %d", call_kind());
}
}
#endif //ASSERT
#endif // ASSERT

#ifndef PRODUCT
void CallInfo::print() {
Expand Down Expand Up @@ -294,7 +294,7 @@ void LinkResolver::check_klass_accessability(Klass* ref_klass, Klass* sel_klass,
base_klass = ObjArrayKlass::cast(sel_klass)->bottom_klass();
}
// The element type could be a typeArray - we only need the access
// check if it is an reference to another class.
// check if it is a reference to another class.
if (!base_klass->is_instance_klass()) {
return; // no relevant check to do
}
Expand All @@ -306,13 +306,17 @@ void LinkResolver::check_klass_accessability(Klass* ref_klass, Klass* sel_klass,
char* msg = Reflection::verify_class_access_msg(ref_klass,
InstanceKlass::cast(base_klass),
vca_result);
bool same_module = (base_klass->module() == ref_klass->module());
if (msg == NULL) {
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(),
"failed to access class %s from class %s",
"failed to access class %s from class %s (%s%s%s)",
base_klass->external_name(),
ref_klass->external_name());
ref_klass->external_name(),
(same_module) ? base_klass->joint_in_module_of_loader(ref_klass) : base_klass->class_in_module_of_loader(),
(same_module) ? "" : "; ",
(same_module) ? "" : ref_klass->class_in_module_of_loader());
} else {
// Use module specific message returned by verify_class_access_msg().
Exceptions::fthrow(
Expand Down Expand Up @@ -596,8 +600,11 @@ void LinkResolver::check_method_accessability(Klass* ref_klass,
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(),
"class %s tried to access method %s.%s%s (%s%s%s)",
"class %s tried to access %s%s%smethod %s.%s%s (%s%s%s)",
ref_klass->external_name(),
sel_method->is_abstract() ? "abstract " : "",
sel_method->is_protected() ? "protected " : "",
sel_method->is_private() ? "private " : "",
sel_klass->external_name(),
sel_method->name()->as_C_string(),
sel_method->signature()->as_C_string(),
Expand Down Expand Up @@ -927,14 +934,20 @@ void LinkResolver::check_field_accessability(Klass* ref_klass,
// Any existing exceptions that may have been thrown, for example LinkageErrors
// from nest-host resolution, have been allowed to propagate.
if (!can_access) {
bool same_module = (sel_klass->module() == ref_klass->module());
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(),
"tried to access field %s.%s from class %s",
"class %s tried to access %s%sfield %s.%s (%s%s%s)",
ref_klass->external_name(),
fd.is_protected() ? "protected " : "",
fd.is_private() ? "private " : "",
sel_klass->external_name(),
fd.name()->as_C_string(),
ref_klass->external_name()
(same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
(same_module) ? "" : "; ",
(same_module) ? "" : sel_klass->class_in_module_of_loader()
);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ static void test_GoodInvoke(){
static void test_NoHostInvoke() throws Throwable {
System.out.println("Testing for missing nest-host attribute");
String msg = "class TestNestmateMembership$Caller tried to access " +
"method TestNestmateMembership$TargetNoHost.m()V";
"private method TestNestmateMembership$TargetNoHost.m()V";
try {
Caller.invokeTargetNoHost();
throw new Error("Missing IllegalAccessError: " + msg);
Expand All @@ -698,16 +698,16 @@ static void test_NoHostInvoke() throws Throwable {
}

msg = "class TestNestmateMembership$CallerNoHost tried to access " +
"method TestNestmateMembership$Target.m()V";
"private method TestNestmateMembership$Target.m()V";
try {
CallerNoHost.invokeTarget();
throw new Error("Missing IllegalAccessError: " + msg);
}
catch (IllegalAccessError expected) {
check_expected(expected, msg);
}
msg = "class TestNestmateMembership$CallerNoHost tried to access method " +
"TestNestmateMembership$TargetNoHost.m()V";
msg = "class TestNestmateMembership$CallerNoHost tried to access private " +
"method TestNestmateMembership$TargetNoHost.m()V";
try {
CallerNoHost.invokeTargetNoHost();
throw new Error("Missing IllegalAccessError: " + msg);
Expand Down Expand Up @@ -949,8 +949,8 @@ static void test_GoodConstruct(){

static void test_NoHostConstruct() throws Throwable {
System.out.println("Testing for missing nest-host attribute");
String msg = "class TestNestmateMembership$Caller tried to access method " +
"TestNestmateMembership$TargetNoHost.<init>()V";
String msg = "class TestNestmateMembership$Caller tried to access private " +
"method TestNestmateMembership$TargetNoHost.<init>()V";
try {
Caller.newTargetNoHost();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
Expand All @@ -976,17 +976,17 @@ static void test_NoHostConstruct() throws Throwable {
check_expected(expected, msg);
}

msg = "class TestNestmateMembership$CallerNoHost tried to access method " +
"TestNestmateMembership$Target.<init>()V";
msg = "class TestNestmateMembership$CallerNoHost tried to access private " +
"method TestNestmateMembership$Target.<init>()V";
try {
CallerNoHost.newTarget();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
}
catch (IncompatibleClassChangeError expected) {
check_expected(expected, msg);
}
msg = "class TestNestmateMembership$CallerNoHost tried to access method " +
"TestNestmateMembership$TargetNoHost.<init>()V";
msg = "class TestNestmateMembership$CallerNoHost tried to access private " +
"method TestNestmateMembership$TargetNoHost.<init>()V";
try {
CallerNoHost.newTargetNoHost();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
Expand Down Expand Up @@ -1220,8 +1220,8 @@ static void test_GoodGetField(){

static void test_NoHostGetField() throws Throwable {
System.out.println("Testing for missing nest-host attribute");
String msg = "tried to access field TestNestmateMembership$TargetNoHost.f" +
" from class TestNestmateMembership$Caller";
String msg = "class TestNestmateMembership$Caller tried to access private " +
"field TestNestmateMembership$TargetNoHost.f";
try {
Caller.getFieldTargetNoHost();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
Expand All @@ -1247,17 +1247,17 @@ static void test_NoHostGetField() throws Throwable {
check_expected(expected, msg);
}

msg = "tried to access field TestNestmateMembership$Target.f" +
" from class TestNestmateMembership$CallerNoHost";
msg = "class TestNestmateMembership$CallerNoHost tried to access private " +
"field TestNestmateMembership$Target.f";
try {
CallerNoHost.getFieldTarget();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
}
catch (IncompatibleClassChangeError expected) {
check_expected(expected, msg);
}
msg = "tried to access field TestNestmateMembership$TargetNoHost.f" +
" from class TestNestmateMembership$CallerNoHost";
msg = "class TestNestmateMembership$CallerNoHost tried to access private " +
"field TestNestmateMembership$TargetNoHost.f";
try {
CallerNoHost.getFieldTargetNoHost();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
Expand Down Expand Up @@ -1485,8 +1485,8 @@ static void test_GoodPutField(){

static void test_NoHostPutField() throws Throwable {
System.out.println("Testing for missing nest-host attribute");
String msg = "tried to access field TestNestmateMembership$TargetNoHost.f" +
" from class TestNestmateMembership$Caller";
String msg = "class TestNestmateMembership$Caller tried to access private " +
"field TestNestmateMembership$TargetNoHost.f";
try {
Caller.putFieldTargetNoHost();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
Expand All @@ -1512,17 +1512,17 @@ static void test_NoHostPutField() throws Throwable {
check_expected(expected, msg);
}

msg = "tried to access field TestNestmateMembership$Target.f" +
" from class TestNestmateMembership$CallerNoHost";
msg = "class TestNestmateMembership$CallerNoHost tried to access private " +
"field TestNestmateMembership$Target.f";
try {
CallerNoHost.putFieldTarget();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
}
catch (IncompatibleClassChangeError expected) {
check_expected(expected, msg);
}
msg = "tried to access field TestNestmateMembership$TargetNoHost.f" +
" from class TestNestmateMembership$CallerNoHost";
msg = "class TestNestmateMembership$CallerNoHost tried to access private " +
"field TestNestmateMembership$TargetNoHost.f";
try {
CallerNoHost.putFieldTargetNoHost();
throw new Error("Missing IncompatibleClassChangeError: " + msg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public static void main(String[] args) throws Throwable {
throw new Error("Unexpected construction of ExternalSuper");
}
catch (IllegalAccessError iae) {
if (iae.getMessage().contains("class TestConstructorHierarchy tried to access method ExternalSuper.<init>()V")) {
if (iae.getMessage().contains("class TestConstructorHierarchy tried to access private method ExternalSuper.<init>()V")) {
System.out.println("Got expected exception constructing ExternalSuper: " + iae);
}
else throw new Error("Unexpected IllegalAccessError: " + iae);
Expand All @@ -61,7 +61,7 @@ public static void main(String[] args) throws Throwable {
throw new Error("Unexpected construction of NestedA and supers");
}
catch (IllegalAccessError iae) {
if (iae.getMessage().contains("class TestConstructorHierarchy$NestedA tried to access method ExternalSuper.<init>()V")) {
if (iae.getMessage().contains("class TestConstructorHierarchy$NestedA tried to access private method ExternalSuper.<init>()V")) {
System.out.println("Got expected exception constructing NestedA: " + iae);
}
else throw new Error("Unexpected IllegalAccessError: " + iae);
Expand All @@ -71,7 +71,7 @@ public static void main(String[] args) throws Throwable {
throw new Error("Unexpected construction of ExternalSub");
}
catch (IllegalAccessError iae) {
if (iae.getMessage().contains("class ExternalSub tried to access method TestConstructorHierarchy$NestedA.<init>()V")) {
if (iae.getMessage().contains("class ExternalSub tried to access private method TestConstructorHierarchy$NestedA.<init>()V")) {
System.out.println("Got expected exception constructing ExternalSub: " + iae);
}
else throw new Error("Unexpected IllegalAccessError: " + iae);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 by SAP AG, Walldorf, Germany.
* 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 test;

public class IAE78_A {

static Object f = new Object();

IAE78_A() {
// Nothing to do.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 SAP SE. 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 test;

public class IAE78_B {

public static void create() {
new IAE78_A();
}

public static void access() {
IAE78_A.f.hashCode();
}
}
Loading

0 comments on commit cad47f4

Please sign in to comment.