From 9d5b10bb267122242d0b456dad73873d50988342 Mon Sep 17 00:00:00 2001 From: iignatyev Date: Thu, 25 Apr 2013 11:04:36 -0700 Subject: [PATCH] 8012337: Change Whitebox implementation to make absence of method in Whitebox.class not fatal Reviewed-by: kvn, vlivanov --- src/share/vm/prims/whitebox.cpp | 24 ++++++++++++-- test/sanity/WhiteBox.java | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 test/sanity/WhiteBox.java diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp index 412ad4326..c351907ce 100644 --- a/src/share/vm/prims/whitebox.cpp +++ b/src/share/vm/prims/whitebox.cpp @@ -436,9 +436,29 @@ JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass)) instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass()); Handle loader(ikh->class_loader()); if (loader.is_null()) { + ResourceMark rm; ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI - jint result = env->RegisterNatives(wbclass, methods, sizeof(methods)/sizeof(methods[0])); - if (result == 0) { + bool result = true; + // one by one registration natives for exception catching + jclass exceptionKlass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string()); + for (int i = 0, n = sizeof(methods) / sizeof(methods[0]); i < n; ++i) { + if (env->RegisterNatives(wbclass, methods + i, 1) != 0) { + result = false; + if (env->ExceptionCheck() && env->IsInstanceOf(env->ExceptionOccurred(), exceptionKlass)) { + // j.l.NoSuchMethodError is thrown when a method can't be found or a method is not native + // ignoring the exception + tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s", methods[i].name, methods[i].signature); + env->ExceptionClear(); + } else { + // register is failed w/o exception or w/ unexpected exception + tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered", methods[i].name, methods[i].signature); + env->UnregisterNatives(wbclass); + break; + } + } + } + + if (result) { WhiteBox::set_used(); } } diff --git a/test/sanity/WhiteBox.java b/test/sanity/WhiteBox.java new file mode 100644 index 000000000..a366e4dd1 --- /dev/null +++ b/test/sanity/WhiteBox.java @@ -0,0 +1,58 @@ +/* + * 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. + */ + +/* + * @test WhiteBox + * @bug 8011675 + * @summary verify that whitebox can be used even if not all functions are declared in java-part + * @author igor.ignatyev@oracle.com + * @library /testlibrary + * @compile WhiteBox.java + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI sun.hotspot.WhiteBox + * @clean sun.hotspot.WhiteBox + */ + +package sun.hotspot; + +public class WhiteBox { + private static native void registerNatives(); + static { registerNatives(); } + public native int notExistedMethod(); + public native int getHeapOopSize(); + public static void main(String[] args) { + WhiteBox wb = new WhiteBox(); + if (wb.getHeapOopSize() < 0) { + throw new Error("wb.getHeapOopSize() < 0"); + } + boolean catched = false; + try { + wb.notExistedMethod(); + } catch (UnsatisfiedLinkError e) { + catched = true; + } + if (!catched) { + throw new Error("wb.notExistedMethod() was invoked"); + } + } +} -- GitLab