Path: blob/master/runtime/jcl/common/clsldr.cpp
6000 views
/*******************************************************************************1* Copyright (c) 1998, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/21#include "ArrayCopyHelpers.hpp"22#include "VMHelpers.hpp"23#include "j9.h"24#include "jclglob.h"25#include "jclprots.h"26#include "jvminit.h"27#include "j9protos.h"28#include "vmhook_internal.h"29#include "j9jclnls.h"3031#if JAVA_SPEC_VERSION >= 1532/* Should match OJDK's j.l.i.MethodHandleNatives.Constants.NESTMATE_CLASS (0x1). */33#define CLASSOPTION_FLAG_NESTMATE 0x134/* Should match OJDK's j.l.i.MethodHandleNatives.Constants.HIDDEN_CLASS (0x2). */35#define CLASSOPTION_FLAG_HIDDEN 0x236/* Should match OJDK's j.l.i.MethodHandleNatives.Constants.STRONG_LOADER_LINK (0x4). */37#define CLASSOPTION_FLAG_STRONG 0x438#endif /* JAVA_SPEC_VERSION >= 15 */394041extern "C" {4243jboolean JNICALL Java_java_lang_ClassLoader_isVerboseImpl(JNIEnv *env, jclass clazz)44{45J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM;4647return ( (javaVM->verboseLevel & VERBOSE_CLASS) == VERBOSE_CLASS );48}4950jclass JNICALL51Java_java_lang_ClassLoader_defineClassImpl(JNIEnv *env, jobject receiver, jstring className, jbyteArray classRep, jint offset, jint length, jobject protectionDomain)52{53J9VMThread *currentThread = (J9VMThread *)env;54J9InternalVMFunctions *vmFuncs = currentThread->javaVM->internalVMFunctions;55UDATA options = 0;5657if (NULL == protectionDomain) {58/*59* Only trusted code has access to JavaLangAccess.defineClass();60* callers only provide a NULL protectionDomain when exemptions61* are required.62*/63options |= J9_FINDCLASS_FLAG_UNSAFE;64}6566jclass result = defineClassCommon(env, receiver, className, classRep, offset, length, protectionDomain, &options, NULL, NULL, TRUE);6768if (J9_ARE_ANY_BITS_SET(options, J9_FINDCLASS_FLAG_NAME_IS_INVALID) && (NULL == result) && (NULL == currentThread->currentException)) {69/*70* Now that we know the class is not exempt, throw NoClassDefFoundError as we71* would have liked to have done above before we called defineClassCommon().72*/73vmFuncs->internalEnterVMFromJNI(currentThread);74vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNOCLASSDEFFOUNDERROR, (UDATA *)*(j9object_t *)className);75vmFuncs->internalExitVMToJNI(currentThread);76}7778return result;79}8081#if JAVA_SPEC_VERSION >= 1582jclass JNICALL83Java_java_lang_ClassLoader_defineClassImpl1(JNIEnv *env, jobject receiver, jclass hostClass, jstring className, jbyteArray classRep, jobject protectionDomain, jboolean init, jint flags, jobject classData)84{85J9VMThread *currentThread = (J9VMThread *)env;86J9JavaVM *vm = currentThread->javaVM;87J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;88UDATA options = 0;89BOOLEAN validateName = FALSE;9091vmFuncs->internalEnterVMFromJNI(currentThread);92if (NULL == classRep) {93vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, NULL);94vmFuncs->internalExitVMToJNI(currentThread);95return NULL;96}97if (NULL == hostClass) {98vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, NULL);99vmFuncs->internalExitVMToJNI(currentThread);100return NULL;101}102103j9object_t hostClassObject = J9_JNI_UNWRAP_REFERENCE(hostClass);104J9Class *hostClazz = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, hostClassObject);105106vmFuncs->internalExitVMToJNI(currentThread);107if (J9_ARE_ALL_BITS_SET(flags, CLASSOPTION_FLAG_HIDDEN)) {108options |= (J9_FINDCLASS_FLAG_HIDDEN | J9_FINDCLASS_FLAG_UNSAFE);109} else {110/* Validate the name for a normal (non-hidden) class. */111validateName = TRUE;112}113if (J9_ARE_ALL_BITS_SET(flags, CLASSOPTION_FLAG_NESTMATE)) {114options |= J9_FINDCLASS_FLAG_CLASS_OPTION_NESTMATE;115}116if (J9_ARE_ALL_BITS_SET(flags, CLASSOPTION_FLAG_STRONG)) {117options |= J9_FINDCLASS_FLAG_CLASS_OPTION_STRONG;118} else {119options |= J9_FINDCLASS_FLAG_ANON;120}121122jsize length = env->GetArrayLength(classRep);123124jclass result = defineClassCommon(env, receiver, className, classRep, 0, length, protectionDomain, &options, hostClazz, NULL, validateName);125if (env->ExceptionCheck()) {126return NULL;127} else if (NULL == result) {128throwNewInternalError(env, NULL);129return NULL;130}131132vmFuncs->internalEnterVMFromJNI(currentThread);133if (NULL != classData) {134j9object_t classDataObject = J9_JNI_UNWRAP_REFERENCE(classData);135j9object_t resultClassObject = J9_JNI_UNWRAP_REFERENCE(result);136J9VMJAVALANGCLASS_SET_CLASSDATA(currentThread, resultClassObject, classDataObject);137}138139j9object_t classObject = J9_JNI_UNWRAP_REFERENCE(result);140J9Class *j9clazz = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, classObject);141if (init) {142if (VM_VMHelpers::classRequiresInitialization(currentThread, j9clazz)) {143vmFuncs->initializeClass(currentThread, j9clazz);144j9clazz = J9_CURRENT_CLASS(j9clazz);145}146} else {147/* Should link the class, see https://github.com/eclipse-openj9/openj9/issues/10297 */148vmFuncs->prepareClass(currentThread, j9clazz);149}150151vmFuncs->internalExitVMToJNI(currentThread);152return result;153}154#endif /* JAVA_SPEC_VERSION >= 15 */155156157jboolean JNICALL158Java_java_lang_ClassLoader_foundJavaAssertOption(JNIEnv *env, jclass ignored)159{160J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM;161162return J9_ARE_ALL_BITS_SET(javaVM->extendedRuntimeFlags, J9_EXTENDED_RUNTIME_FOUND_JAVA_ASSERT_OPTION);163}164165jint JNICALL166Java_com_ibm_oti_vm_BootstrapClassLoader_addJar(JNIEnv *env, jobject receiver, jbyteArray jarPath)167{168jint newCount = 0;169J9VMThread * currentThread = (J9VMThread *) env;170J9JavaVM * vm = currentThread->javaVM;171J9InternalVMFunctions * vmFuncs = vm->internalVMFunctions;172173PORT_ACCESS_FROM_JAVAVM(vm);174175UDATA jarPathSize = (UDATA)env->GetArrayLength(jarPath);176char *jarPathBuffer = (char *)j9mem_allocate_memory(jarPathSize + 1, J9MEM_CATEGORY_CLASSES);177178if (NULL != jarPathBuffer) {179/* Use exclusive access to modify the array */180vmFuncs->internalEnterVMFromJNI(currentThread);181vmFuncs->acquireExclusiveVMAccess(currentThread);182VM_ArrayCopyHelpers::memcpyFromArray(currentThread, J9_JNI_UNWRAP_REFERENCE(jarPath), (UDATA)0, (UDATA)0, jarPathSize, (void*)jarPathBuffer);183jarPathBuffer[jarPathSize] = 0; /* null character terminated */184newCount = (jint)addJarToSystemClassLoaderClassPathEntries(vm, jarPathBuffer);185j9mem_free_memory(jarPathBuffer);186vmFuncs->releaseExclusiveVMAccess(currentThread);187vmFuncs->internalExitVMToJNI(currentThread);188}189/* If any error occurred, throw OutOfMemoryError */190if (0 == newCount) {191vmFuncs->throwNativeOOMError(env, J9NLS_JCL_UNABLE_TO_CREATE_CLASS_PATH_ENTRY);192}193return newCount;194}195196} /* extern "C" */197198199