8287171: Refactor null caller tests to a single directory

Reviewed-by: ihse, mchung
This commit is contained in:
Tim Prinzing 2022-06-02 16:45:05 +00:00 committed by Mandy Chung
parent 3cfd38caf1
commit e51ca1dee3
18 changed files with 429 additions and 689 deletions

View File

@ -62,10 +62,7 @@ ifeq ($(call isTargetOs, windows), true)
WIN_LIB_JLI := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := $(WIN_LIB_JLI)
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := jvm.lib
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerClassLoaderTest := jvm.lib
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerLookupTest := jvm.lib
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerResourceBundle := jvm.lib
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerGetResource := jvm.lib
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerTest := jvm.lib
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib
BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libAsyncStackWalk := /EHsc
BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libAsyncInvokers := /EHsc
@ -93,10 +90,7 @@ else
endif
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := -ljli
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerClassLoaderTest := -ljvm
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerLookupTest := -ljvm
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerResourceBundle := -ljvm
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerGetResource := -ljvm
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerTest := -ljvm
endif
ifeq ($(call isTargetOs, macosx), true)

View File

@ -110,7 +110,8 @@ jdk_lang = \
jdk/internal/jimage \
jdk/internal/math \
jdk/internal/vm \
jdk/modules
jdk/modules \
jni/nullCaller
# All of the java.util package
jdk_util = \

View File

@ -1,71 +0,0 @@
/*
* Copyright (c) 2022, 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
* @bug 8281000
* @summary Test uses custom launcher that starts VM using JNI that verifies
* ClassLoader.registerAsParallelCapable with null caller class
* throws an IllegalCallerException.
* @library /test/lib
* @requires os.family != "aix"
* @run main/native NullCallerClassLoaderTest
*/
// Test disabled on AIX since we cannot invoke the JVM on the primordial thread.
import java.io.File;
import java.util.Map;
import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class NullCallerClassLoaderTest {
public static void main(String[] args) throws IOException {
Path launcher = Path.of(System.getProperty("test.nativepath"), "NullCallerClassLoaderTest");
ProcessBuilder pb = new ProcessBuilder(launcher.toString());
Map<String, String> env = pb.environment();
String libDir = Platform.libDir().toString();
String vmDir = Platform.jvmLibDir().toString();
// set up shared library path
String sharedLibraryPathEnvName = Platform.sharedLibraryPathVariableName();
env.compute(sharedLibraryPathEnvName,
(k, v) -> (v == null) ? libDir : v + File.pathSeparator + libDir);
env.compute(sharedLibraryPathEnvName,
(k, v) -> (v == null) ? vmDir : v + File.pathSeparator + vmDir);
System.out.println("Launching: " + launcher + " shared library path: " +
env.get(sharedLibraryPathEnvName));
new OutputAnalyzer(pb.start())
.outputTo(System.out)
.errorTo(System.err)
.shouldHaveExitValue(0);
}
}

View File

@ -1,76 +0,0 @@
/*
* Copyright (c) 2022, 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jni.h"
#include "assert.h"
static jclass class_IllegalCallerException;
int checkAndClearIllegalCallerExceptionThrown(JNIEnv *env) {
jthrowable t = (*env)->ExceptionOccurred(env);
if ((*env)->IsInstanceOf(env, t, class_IllegalCallerException) == JNI_TRUE) {
(*env)->ExceptionClear(env);
return JNI_TRUE;
}
return JNI_FALSE;
}
int main(int argc, char** args) {
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
jint rc;
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 0;
vm_args.options = options;
if ((rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)) != JNI_OK) {
printf("ERROR: cannot create VM.\n");
exit(-1);
}
class_IllegalCallerException = (*env)->FindClass(env, "java/lang/IllegalCallerException");
assert (class_IllegalCallerException != NULL);
// call ClassLoader.registerAsParallelCapable()
jclass class_ClassLoader = (*env)->FindClass(env, "java/lang/ClassLoader");
assert(class_ClassLoader != NULL);
jmethodID mid_ClassLoader_registerAsParallelCapable = (*env)->GetStaticMethodID(env, class_ClassLoader, "registerAsParallelCapable", "()Z" );
assert(mid_ClassLoader_registerAsParallelCapable != NULL);
jboolean b = (*env)->CallStaticBooleanMethod(env, class_ClassLoader, mid_ClassLoader_registerAsParallelCapable );
if ((rc = checkAndClearIllegalCallerExceptionThrown(env)) != JNI_TRUE) {
printf("ERROR: Didn't get the expected IllegalCallerException.\n");
exit(-1);
}
printf("Expected IllegalCallerException was thrown\n");
(*jvm)->DestroyJavaVM(jvm);
return 0;
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2022, 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
* @bug 8281003
* @summary Test uses custom launcher that starts VM using JNI that verifies
* MethodHandles::lookup with null caller class throws an IllegalCallerException.
* @library /test/lib
* @requires os.family != "aix"
* @run main/native NullCallerLookupTest
*/
// Test disabled on AIX since we cannot invoke the JVM on the primordial thread.
import java.io.File;
import java.util.Map;
import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
import java.io.IOException;
import java.nio.file.Path;
public class NullCallerLookupTest {
public static void main(String[] args) throws IOException {
Path launcher = Path.of(System.getProperty("test.nativepath"), "NullCallerLookupTest");
ProcessBuilder pb = new ProcessBuilder(launcher.toString());
Map<String, String> env = pb.environment();
String libDir = Platform.libDir().toString();
String vmDir = Platform.jvmLibDir().toString();
// set up shared library path
String sharedLibraryPathEnvName = Platform.sharedLibraryPathVariableName();
env.compute(sharedLibraryPathEnvName,
(k, v) -> (v == null) ? libDir : v + File.pathSeparator + libDir);
env.compute(sharedLibraryPathEnvName,
(k, v) -> (v == null) ? vmDir : v + File.pathSeparator + vmDir);
System.out.println("Launching: " + launcher + " shared library path: " +
env.get(sharedLibraryPathEnvName));
new OutputAnalyzer(pb.start())
.outputTo(System.out)
.errorTo(System.err)
.shouldHaveExitValue(0);
}
}

View File

@ -1,76 +0,0 @@
/*
* Copyright (c) 2022, 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jni.h"
#include "assert.h"
static jclass class_IllegalCallerException;
int checkAndClearIllegalCallerExceptionThrown(JNIEnv *env) {
jthrowable t = (*env)->ExceptionOccurred(env);
if ((*env)->IsInstanceOf(env, t, class_IllegalCallerException) == JNI_TRUE) {
(*env)->ExceptionClear(env);
return JNI_TRUE;
}
return JNI_FALSE;
}
int main(int argc, char** args) {
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
jint rc;
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 0;
vm_args.options = options;
if ((rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)) != JNI_OK) {
printf("ERROR: cannot create VM.\n");
exit(-1);
}
class_IllegalCallerException = (*env)->FindClass(env, "java/lang/IllegalCallerException");
assert (class_IllegalCallerException != NULL);
// call MethodHandles.lookup()
jclass methodHandlesClass = (*env)->FindClass(env, "java/lang/invoke/MethodHandles");
assert(methodHandlesClass != NULL);
jmethodID mid_MethodHandles_lookup = (*env)->GetStaticMethodID(env, methodHandlesClass, "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;" );
assert(mid_MethodHandles_lookup != NULL);
jobject l = (*env)->CallStaticObjectMethod(env, methodHandlesClass, mid_MethodHandles_lookup );
if ((rc = checkAndClearIllegalCallerExceptionThrown(env)) != JNI_TRUE) {
printf("ERROR: Didn't get the expected IllegalCallerException.\n");
exit(-1);
}
printf("Expected IllegalCallerException was thrown\n");
(*jvm)->DestroyJavaVM(jvm);
return 0;
}

View File

@ -1,184 +0,0 @@
/*
* Copyright (c) 2022, 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jni.h"
#undef NDEBUG
#include "assert.h"
#include "string.h"
static jclass class_InputStream = NULL;
static jmethodID mid_InputStream_close = NULL;
// in.close();
void closeInputStream(JNIEnv *env, jobject in) {
(*env)->CallObjectMethod(env, in, mid_InputStream_close);
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling InputStream::close.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
}
/*
* The java test running this native test creates a test module named 'n'
* which opens the package 'open'. It has a text file resource named
* 'test.txt' in the open package. It also has a class called
* open.OpenResources. One should be able to get the resource through
* either the Class or the Module with getResourceAsStream.
*
* Class c = open.OpenResources.fetchClass();
* InputStream in1 = c.getResourceAsStream("test.txt");
* Module n = c.getModule();
* InputStream in2 = n.getResourceAsStream("open/test.txt");
*
* The test also checks that closed resources are not available and
* don't throw any exceptions. The test module contains a class
* called closed.ClosedResources and a file 'test.txt' in the package
* 'closed'.
*
* Class closed = closed.ClosedResources.fetchClass();
* assert(closed.getResourceAsStream("test.txt") == null);
* assert(n.getResourceAsStream("closed/test.txt") == null);
*
*/
int main(int argc, char** args) {
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[4];
jint rc;
options[0].optionString = "--module-path=mods";
options[1].optionString = "--add-modules=n";
vm_args.version = JNI_VERSION_9;
vm_args.nOptions = 2;
vm_args.options = options;
if ((rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)) != JNI_OK) {
printf("ERROR: cannot create VM.\n");
exit(-1);
}
// initialize for stream close
class_InputStream = (*env)->FindClass(env, "java/io/InputStream");
assert(class_InputStream != NULL);
mid_InputStream_close = (*env)->GetMethodID(env, class_InputStream, "close", "()V" );
assert(mid_InputStream_close != NULL);
// the open and closed classes
jclass class_OpenResources = (*env)->FindClass(env, "open/OpenResources");
assert(class_OpenResources != NULL);
jclass class_ClosedResources = (*env)->FindClass(env, "closed/ClosedResources");
assert(class_ClosedResources != NULL);
// Fetch the Module from one of the classes in the module
jclass class_Class = (*env)->FindClass(env, "java/lang/Class");
assert(class_Class != NULL);
jmethodID mid_Class_getModule = (*env)->GetMethodID(env, class_Class, "getModule", "()Ljava/lang/Module;" );
assert(mid_Class_getModule != NULL);
jobject n =(*env)->CallObjectMethod(env, class_OpenResources, mid_Class_getModule);
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling Class::getModule.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
assert(n != NULL);
// Attempt to fetch an open resource from the module. It should return a valid stream.
// InputStream in = n.getResourceAsStream("open/test.txt");
jclass class_Module = (*env)->FindClass(env, "java/lang/Module");
assert(class_Module != NULL);
jmethodID mid_Module_getResourceAsStream =
(*env)->GetMethodID(env, class_Module, "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;" );
assert(mid_Module_getResourceAsStream != NULL);
jobject in = (*env)->CallObjectMethod(env, n, mid_Module_getResourceAsStream,
(*env)->NewStringUTF(env, "open/test.txt"));
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling Module::getResourceAsStream on 'open/test.txt'.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
if (in == NULL) {
printf("ERROR: Module::getResourceAsStream, expected valid stream for open resource\n");
exit(-1);
}
// in.close();
closeInputStream(env, in);
// Attempt to fetch closed resource from the module. It should return null.
// in = n.getResourceAsStream("closed/test.txt");
in = (*env)->CallObjectMethod(env, n, mid_Module_getResourceAsStream,
(*env)->NewStringUTF(env, "closed/test.txt"));
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling Module::getResourceAsStream on 'closed/test.txt'.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
if (in != NULL) {
printf("ERROR: Module::getResourceAsStream, expected null value for closed resource\n");
exit(-1);
}
// Attempt to fetch open resource from the class. It should return a valid stream.
// in = open.OpenReosurces.class.getResourceAsStream("test.txt");
jmethodID mid_Class_getResourceAsStream =
(*env)->GetMethodID(env, class_Class, "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;" );
assert(mid_Class_getResourceAsStream != NULL);
in = (*env)->CallObjectMethod(env, class_OpenResources, mid_Class_getResourceAsStream,
(*env)->NewStringUTF(env, "test.txt"));
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling Class::getResourceAsStream on 'test.txt'.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
if (in == NULL) {
printf("ERROR: Class::getResourceAsStream, expected valid stream for open resource\n");
exit(-1);
}
// in.close();
closeInputStream(env, in);
// Attempt to fetch closed resource from the class. It should return null.
// in = closed.ClosedResources.class.getResourceAsStream("test.txt");
in = (*env)->CallObjectMethod(env, class_ClosedResources, mid_Class_getResourceAsStream,
(*env)->NewStringUTF(env, "test.txt"));
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling Class::getResourceAsStream on closed 'test.txt'.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
if (in != NULL) {
printf("ERROR: Class::getResourceAsStream, expected null value for closed resource\n");
exit(-1);
}
(*jvm)->DestroyJavaVM(jvm);
return 0;
}

View File

@ -1,83 +0,0 @@
/*
* Copyright (c) 2022, 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
* @bug 8280902
* @summary Test uses custom launcher that starts VM using JNI that verifies
* ResourceBundle::getBundle with null caller class functions properly
* using the system class loader unnamed module. The custom launcher
* creates a properties file and passes the VM option to the JNI
* functionality for the resource lookup.
* @library /test/lib
* @requires os.family != "aix"
* @run main/native NullCallerResourceBundle
*/
// Test disabled on AIX since we cannot invoke the JVM on the primordial thread.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
public class NullCallerResourceBundle {
public static void main(String[] args) throws IOException {
// build a properties file for the native test
var propPath = Path.of(System.getProperty("test.classes"), "NullCallerResource.properties");
try (var stream = Files.newOutputStream(propPath)) {
var props = new Properties();
props.put("message", "Hello!");
props.save(stream, "Test property list");
}
var launcher = Path.of(System.getProperty("test.nativepath"), "NullCallerResourceBundle");
var classpathAppend = "-Djava.class.path=" + System.getProperty("test.classes");
var pb = new ProcessBuilder(launcher.toString(), classpathAppend);
var env = pb.environment();
var libDir = Platform.libDir().toString();
var vmDir = Platform.jvmLibDir().toString();
// set up shared library path
var sharedLibraryPathEnvName = Platform.sharedLibraryPathVariableName();
env.compute(sharedLibraryPathEnvName,
(k, v) -> (v == null) ? libDir : v + File.pathSeparator + libDir);
env.compute(sharedLibraryPathEnvName,
(k, v) -> (v == null) ? vmDir : v + File.pathSeparator + vmDir);
System.out.println("Launching: " + launcher + " shared library path: " +
env.get(sharedLibraryPathEnvName));
new OutputAnalyzer(pb.start())
.outputTo(System.out)
.errorTo(System.err)
.shouldHaveExitValue(0);
}
}

View File

@ -1,102 +0,0 @@
/*
* Copyright (c) 2022, 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jni.h"
#undef NDEBUG
#include "assert.h"
#include "string.h"
/*
* The java test running this native test passes in an argument to provide as
* an option for the configuration of the JVM. The system classpath has the
* classpath of the java test appended so it can pick up the resource that
* was created by the java part of the test.
*/
int main(int argc, char** args) {
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
jint rc;
assert(argc == 2);
options[0].optionString = args[1];
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 1;
vm_args.options = options;
if ((rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)) != JNI_OK) {
printf("ERROR: cannot create VM.\n");
exit(-1);
}
// b = ResourceBundle.getBundle("NullCallerResource");
jclass class_ResourceBundle = (*env)->FindClass(env, "java/util/ResourceBundle");
assert(class_ResourceBundle != NULL);
jmethodID mid_ResourceBundle_getBundle = (*env)->GetStaticMethodID(env, class_ResourceBundle, "getBundle", "(Ljava/lang/String;)Ljava/util/ResourceBundle;" );
assert(mid_ResourceBundle_getBundle != NULL);
jobject resourceName = (*env)->NewStringUTF(env, "NullCallerResource");
assert(resourceName != NULL);
jobject b = (*env)->CallStaticObjectMethod(env, class_ResourceBundle, mid_ResourceBundle_getBundle, resourceName);
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling ResourceBundle::getBundle.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
// msg = b.getString("message");
jmethodID mid_ResourceBundle_getString = (*env)->GetMethodID(env, class_ResourceBundle, "getString", "(Ljava/lang/String;)Ljava/lang/String;" );
assert(mid_ResourceBundle_getString != NULL);
jobject key = (*env)->NewStringUTF(env, "message");
jobject msg =(*env)->CallObjectMethod(env, b, mid_ResourceBundle_getString, key);
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling ResourceBundle::getString.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
assert(msg != NULL);
// check the message
const char* cstr = (*env)->GetStringUTFChars(env, msg, NULL);
assert(cstr != NULL);
assert(strcmp(cstr,"Hello!") == 0);
// ResourceBundle.clearCache()
jmethodID mid_ResourceBundle_clearCache = (*env)->GetStaticMethodID(env, class_ResourceBundle, "clearCache", "()V" );
assert(mid_ResourceBundle_clearCache != NULL);
(*env)->CallStaticVoidMethod(env, class_ResourceBundle, mid_ResourceBundle_clearCache);
if ((*env)->ExceptionOccurred(env) != NULL) {
printf("ERROR: Exception was thrown calling ResourceBundle::clearCache.\n");
(*env)->ExceptionDescribe(env);
exit(-1);
}
(*jvm)->DestroyJavaVM(jvm);
return 0;
}

View File

@ -0,0 +1,210 @@
/*
* Copyright (c) 2022, 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.
*/
#ifndef __CallHelper_hpp__
#define __CallHelper_hpp__
#include <stdlib.h>
#include <stdio.h>
#include <jni.h>
#undef NDEBUG
#include <assert.h>
#include <string>
#include <algorithm>
/*
* basis of classes to provide a bunch of checking in native calls to java
*/
class CallHelper {
public:
CallHelper(JNIEnv* e, const std::string& cname, const std::string& mname, const std::string& sig) :
classname(cname), method(mname), signature(sig), m(NULL), env(e) {
c = env->FindClass(classname.c_str());
assert (c != NULL);
}
protected:
// emit a message with the call made appended to the message
void emitErrorMessage(const std::string& msg) {
std::string nm = classname;
std::replace(nm.begin(), nm.end(), '/', '.');
::printf("ERROR: %s::%s, %s\n", nm.c_str(), method.c_str(), msg.c_str());
}
// check the given object which is expected to be null
void checkReturnNull(jobject obj) {
if (obj != NULL) {
emitErrorMessage("Null return expected");
::exit(-1);
}
}
// check the given object which is expected to NOT be null
void checkReturnNotNull(jobject obj) {
if (obj == NULL) {
emitErrorMessage("Non-Null return expected");
::exit(-1);
}
}
// check if any unexpected exceptions were thrown
void checkException() {
if (env->ExceptionOccurred() != NULL) {
emitErrorMessage("Exception was thrown");
env->ExceptionDescribe();
::exit(-1);
}
}
// check if an expected exception was thrown
void checkExpectedExceptionThrown(const std::string& exception) {
jclass expected = env->FindClass(exception.c_str());
assert(expected != NULL);
jthrowable t = env->ExceptionOccurred();
if (env->IsInstanceOf(t, expected) == JNI_FALSE) {
emitErrorMessage("Didn't get the expected " + exception);
::exit(-1);
}
env->ExceptionClear();
}
protected:
std::string classname;
std::string method;
std::string signature;
jclass c;
jmethodID m;
JNIEnv* env;
};
/*
* support for making checked calls on instances of an object
*/
class InstanceCall : public CallHelper {
public:
InstanceCall(JNIEnv* e, const std::string& cname, const std::string& mname, const std::string& sig)
: CallHelper(e, cname, mname, sig) {
m = env->GetMethodID(c, method.c_str(), signature.c_str());
assert(m != NULL);
}
// call on the given object, checking for exceptions and that the return is not null
jobject callReturnNotNull(jobject obj) {
jobject robj = call(obj);
checkReturnNotNull(robj);
return robj;
}
// call on the given object with an argument,
// checking for exceptions and that the return is not null
jobject callReturnNotNull(jobject obj, jobject arg) {
jobject robj = call(obj, arg);
checkReturnNotNull(robj);
return robj;
}
// call on the given object, checking for exceptions and that the return is null
jobject callReturnIsNull(jobject obj) {
jobject robj = call(obj);
checkReturnNull(robj);
return robj;
}
// call on the given object with an argument,
// checking for exceptions and that the return is null
jobject callReturnIsNull(jobject obj, jobject arg) {
jobject robj = call(obj, arg);
checkReturnNull(robj);
return robj;
}
// call a void method checking if exceptions were thrown
void callVoidMethod(jobject obj) {
env->CallVoidMethod(obj, m);
checkException();
}
jobject call(jobject obj) {
jobject robj = env->CallObjectMethod(obj, m);
checkException();
return robj;
}
jobject call(jobject obj, jobject arg) {
jobject robj = env->CallObjectMethod(obj, m, arg);
checkException();
return robj;
}
};
/*
* support for making checked static calls
*/
class StaticCall : public CallHelper {
public:
StaticCall(JNIEnv* e, const std::string& cname, const std::string& mname, const std::string& sig)
: CallHelper(e, cname, mname, sig) {
m = env->GetStaticMethodID(c, method.c_str(), signature.c_str());
assert(m != NULL);
}
// call a method returning an object checking for exceptions and
// the the return value is not null.
jobject callReturnNotNull(jobject arg) {
jobject robj = env->CallStaticObjectMethod(c, m, arg);
checkException();
checkReturnNotNull(robj);
return robj;
}
// call a void method checking if any exceptions thrown
void callVoidMethod() {
env->CallStaticVoidMethod(c, m);
checkException();
}
// call method returning boolean that is expected to throw the
// given exception
void callBooleanMethodWithException(const std::string& exception) {
env->CallStaticBooleanMethod(c, m);
checkExpectedExceptionThrown(exception);
}
// call method returning an object that is expected to throw the
// given exception
void callObjectMethodWithException(const std::string& exception) {
env->CallStaticObjectMethod(c, m);
checkExpectedExceptionThrown(exception);
}
};
void emitErrorMessageAndExit(const std::string& msg) {
::printf("ERROR: %s\n", msg.c_str());
::exit(-1);
}
#endif // __CallHelper_hpp__

View File

@ -24,30 +24,33 @@
/**
* @test
* @bug 8281006
* @bug 8280902 8281000 8281003 8281006
* @summary Test uses custom launcher that starts VM using JNI that verifies
* Module::getResourceAsStream and Class::getResourceAsStream with
* a null caller class functions properly.
* various API called with a null caller class function properly.
* @library /test/lib
* @modules java.base/jdk.internal.module
* jdk.compiler
* @build NullCallerGetResource
* @build NullCallerTest
* jdk.test.lib.compiler.CompilerUtils
* @requires os.family != "aix"
* @run main/native NullCallerGetResource
* @run main/native NullCallerTest
*/
// Test disabled on AIX since we cannot invoke the JVM on the primordial thread.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Properties;
import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.compiler.CompilerUtils;
public class NullCallerGetResource {
public class NullCallerTest {
private static final String TEST_SRC = System.getProperty("test.src");
@ -57,6 +60,7 @@ public class NullCallerGetResource {
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
private static final Path MODS_DIR = Paths.get("mods");
private static final Path TEST_MOD_DIR = MODS_DIR.resolve(TEST_MODULE);
private static final Path TEST_MOD_SRC_DIR = SRC_DIR.resolve(TEST_MODULE);
/*
* Build the test module called 'n' which opens the package 'open'
@ -65,19 +69,18 @@ public class NullCallerGetResource {
*/
static void compileTestModule() throws Exception {
// javac -d mods/$TESTMODULE src/$TESTMODULE/**
boolean compiled
= CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE), TEST_MOD_DIR);
boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE), TEST_MOD_DIR);
assert (compiled);
var open = TEST_MOD_DIR.resolve("open/test.txt");
try (var out = Files.newBufferedWriter(open)) {
out.write("open");
out.flush();
}
var closed = TEST_MOD_DIR.resolve("closed/test.txt");
try (var out = Files.newBufferedWriter(closed)) {
out.write("closed");
out.flush();
}
// copy resources
var resources = List.of("open/test.txt", "closed/test.txt", "open/NullCallerResource.properties");
resources.stream().forEach(r -> {
try {
Files.copy(TEST_MOD_SRC_DIR.resolve(r), TEST_MOD_DIR.resolve(r));
} catch (IOException e) {
throw new RuntimeException("Failed to copy resource: " + r, e);
}
});
}
public static void main(String[] args) throws Exception {
@ -85,7 +88,7 @@ public class NullCallerGetResource {
// build the module used for the test
compileTestModule();
var launcher = Path.of(System.getProperty("test.nativepath"), "NullCallerGetResource");
var launcher = Path.of(System.getProperty("test.nativepath"), "NullCallerTest");
var pb = new ProcessBuilder(launcher.toString());
var env = pb.environment();

View File

@ -0,0 +1,188 @@
/*
* Copyright (c) 2022, 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.
*/
#include "CallHelper.hpp"
/*
* Test for JDK-8280902
*
* A call to ResourceBundle::getBundle() should not throw NPE when
* called with a null caller. This test fetches a simple bundle in
* the test module and makes sure it can read the expected value of
* 'Hello!' using the key 'message'.
*
* This also tests that ResourceBundle::clearCache() doesn't throw an
* NPE when called with a null caller.
*/
void getBundle(JNIEnv* env) {
StaticCall m_ResourceBundle_getBundle { env,
"java/util/ResourceBundle", "getBundle",
"(Ljava/lang/String;)Ljava/util/ResourceBundle;" };
InstanceCall m_ResourceBundle_getString { env,
"java/util/ResourceBundle", "getString",
"(Ljava/lang/String;)Ljava/lang/String;" };
StaticCall m_ResourceBundle_clearCache { env,
"java/util/ResourceBundle", "clearCache", "()V"
};
// b = ResourceBundle.getBundle("open/NullCallerResource");
jobject b = m_ResourceBundle_getBundle.callReturnNotNull(
env->NewStringUTF("open/NullCallerResource"));
// msg = b.getString("message");
jstring msg = (jstring) m_ResourceBundle_getString.callReturnNotNull(b, env->NewStringUTF("message"));
if (std::string("Hello!") != env->GetStringUTFChars(msg, NULL)) {
emitErrorMessageAndExit("Bundle didn't contain expected content");
}
// ResourceBundle.clearCache()
m_ResourceBundle_clearCache.callVoidMethod();
}
/*
* Test for JDK-8281000
*
* This test checks to make sure that calling ClassLoader::registerAsParallelCapable()
* with a null caller results in an ICE being thrown.
*/
void registerAsParallelCapable(JNIEnv* env) {
StaticCall m_ClassLoader_registerAsParallelCapable { env,
"java/lang/ClassLoader", "registerAsParallelCapable", "()Z" };
// ClassLoader.registerAsParallelCapable();
m_ClassLoader_registerAsParallelCapable.
callBooleanMethodWithException("java/lang/IllegalCallerException");
}
/*
* Test for JDK-8281001
*
* Try and load a class using Class::forName in the module n which should be
* found with the system classloader (to match FindClass() used above).
* Class exp = Class.forName("open.OpenResources");
*/
void forName(JNIEnv* env) {
/* coming soon
StaticCall m_Class_forName { env,
"java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;" };
m_Class_forName.callReturnNotNull(env->NewStringUTF("open.OpenResources"));
*/
}
/*
* Test for JDK-8281003
*
* The call to MethodHandles::lookup should throw ICE when called with
* a null caller.
*/
void lookup(JNIEnv* env) {
StaticCall m_MethodHandles_lookup { env,
"java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;" };
m_MethodHandles_lookup.
callObjectMethodWithException("java/lang/IllegalCallerException");
}
/*
* This function tests changes made for JDK-8281006
* Module::getResourceAsStream should check if the resource is open
* unconditionally when caller is null
*
* The java test running this native test creates a test module named 'n'
* which opens the package 'open'. It has a text file resource named
* 'test.txt' in the open package. It also has a class called
* open.OpenResources. One should be able to get the resource through
* either the Class or the Module with getResourceAsStream.
*/
void getResourceAsStream(JNIEnv *env) {
InstanceCall m_InputStream_close { env,
"java/io/InputStream", "close", "()V" };
InstanceCall m_Class_getModule {env,
"java/lang/Class", "getModule", "()Ljava/lang/Module;" };
InstanceCall m_Module_getResourceAsStream { env,
"java/lang/Module", "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;" };
InstanceCall m_Class_getResourceAsStream { env,
"java/lang/Class", "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;" };
// fetch the open and closed classes
jclass class_OpenResources = env->FindClass("open/OpenResources");
assert(class_OpenResources != NULL);
jclass class_ClosedResources = env->FindClass("closed/ClosedResources");
assert(class_ClosedResources != NULL);
// Fetch the Module from one of the classes in the module
jobject n = m_Class_getModule.callReturnNotNull(class_OpenResources);
// Attempt to fetch an open resource from the module. It should return a valid stream.
// InputStream in1 = n.getResourceAsStream("open/test.txt");
// in1.close();
jobject in1 = m_Module_getResourceAsStream.callReturnNotNull(n, env->NewStringUTF("open/test.txt"));
m_InputStream_close.callVoidMethod(in1);
// Attempt to fetch closed resource from the module. It should return null.
// InputStream in2 = n.getResourceAsStream("closed/test.txt");
m_Module_getResourceAsStream.callReturnIsNull(n, env->NewStringUTF("closed/test.txt"));
// Attempt to fetch open resource from the class. It should return a valid stream.
// InputStream in3 = open.OpenReosurces.class.getResourceAsStream("test.txt");
// in3.close();
jobject in3 = m_Class_getResourceAsStream.callReturnNotNull(
class_OpenResources, env->NewStringUTF("test.txt"));
m_InputStream_close.callVoidMethod(in3);
// Attempt to fetch closed resource from the class. It should return null.
// InputStream in4 = closed.ClosedResources.class.getResourceAsStream("test.txt");
m_Class_getResourceAsStream.callReturnIsNull(
class_ClosedResources, env->NewStringUTF("test.txt"));
}
int main(int argc, char** args) {
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[4];
jint rc;
options[0].optionString = (char*) "--module-path=mods";
options[1].optionString = (char*) "--add-modules=n";
vm_args.version = JNI_VERSION_9;
vm_args.nOptions = 2;
vm_args.options = options;
if ((rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)) != JNI_OK) {
emitErrorMessageAndExit("Cannot create VM.");
}
getBundle(env);
registerAsParallelCapable(env);
forName(env);
lookup(env);
getResourceAsStream(env);
jvm->DestroyJavaVM();
return 0;
}

View File

@ -0,0 +1 @@
closed

View File

@ -0,0 +1,3 @@
#Test property list
#Fri May 27 15:30:57 CDT 2022
message=Hello\!

View File

@ -0,0 +1 @@
open