Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/jcl/common/clsldr.cpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 1998, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* 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-exception
21
*******************************************************************************/
22
#include "ArrayCopyHelpers.hpp"
23
#include "VMHelpers.hpp"
24
#include "j9.h"
25
#include "jclglob.h"
26
#include "jclprots.h"
27
#include "jvminit.h"
28
#include "j9protos.h"
29
#include "vmhook_internal.h"
30
#include "j9jclnls.h"
31
32
#if JAVA_SPEC_VERSION >= 15
33
/* Should match OJDK's j.l.i.MethodHandleNatives.Constants.NESTMATE_CLASS (0x1). */
34
#define CLASSOPTION_FLAG_NESTMATE 0x1
35
/* Should match OJDK's j.l.i.MethodHandleNatives.Constants.HIDDEN_CLASS (0x2). */
36
#define CLASSOPTION_FLAG_HIDDEN 0x2
37
/* Should match OJDK's j.l.i.MethodHandleNatives.Constants.STRONG_LOADER_LINK (0x4). */
38
#define CLASSOPTION_FLAG_STRONG 0x4
39
#endif /* JAVA_SPEC_VERSION >= 15 */
40
41
42
extern "C" {
43
44
jboolean JNICALL Java_java_lang_ClassLoader_isVerboseImpl(JNIEnv *env, jclass clazz)
45
{
46
J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM;
47
48
return ( (javaVM->verboseLevel & VERBOSE_CLASS) == VERBOSE_CLASS );
49
}
50
51
jclass JNICALL
52
Java_java_lang_ClassLoader_defineClassImpl(JNIEnv *env, jobject receiver, jstring className, jbyteArray classRep, jint offset, jint length, jobject protectionDomain)
53
{
54
J9VMThread *currentThread = (J9VMThread *)env;
55
J9InternalVMFunctions *vmFuncs = currentThread->javaVM->internalVMFunctions;
56
UDATA options = 0;
57
58
if (NULL == protectionDomain) {
59
/*
60
* Only trusted code has access to JavaLangAccess.defineClass();
61
* callers only provide a NULL protectionDomain when exemptions
62
* are required.
63
*/
64
options |= J9_FINDCLASS_FLAG_UNSAFE;
65
}
66
67
jclass result = defineClassCommon(env, receiver, className, classRep, offset, length, protectionDomain, &options, NULL, NULL, TRUE);
68
69
if (J9_ARE_ANY_BITS_SET(options, J9_FINDCLASS_FLAG_NAME_IS_INVALID) && (NULL == result) && (NULL == currentThread->currentException)) {
70
/*
71
* Now that we know the class is not exempt, throw NoClassDefFoundError as we
72
* would have liked to have done above before we called defineClassCommon().
73
*/
74
vmFuncs->internalEnterVMFromJNI(currentThread);
75
vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNOCLASSDEFFOUNDERROR, (UDATA *)*(j9object_t *)className);
76
vmFuncs->internalExitVMToJNI(currentThread);
77
}
78
79
return result;
80
}
81
82
#if JAVA_SPEC_VERSION >= 15
83
jclass JNICALL
84
Java_java_lang_ClassLoader_defineClassImpl1(JNIEnv *env, jobject receiver, jclass hostClass, jstring className, jbyteArray classRep, jobject protectionDomain, jboolean init, jint flags, jobject classData)
85
{
86
J9VMThread *currentThread = (J9VMThread *)env;
87
J9JavaVM *vm = currentThread->javaVM;
88
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
89
UDATA options = 0;
90
BOOLEAN validateName = FALSE;
91
92
vmFuncs->internalEnterVMFromJNI(currentThread);
93
if (NULL == classRep) {
94
vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, NULL);
95
vmFuncs->internalExitVMToJNI(currentThread);
96
return NULL;
97
}
98
if (NULL == hostClass) {
99
vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALARGUMENTEXCEPTION, NULL);
100
vmFuncs->internalExitVMToJNI(currentThread);
101
return NULL;
102
}
103
104
j9object_t hostClassObject = J9_JNI_UNWRAP_REFERENCE(hostClass);
105
J9Class *hostClazz = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, hostClassObject);
106
107
vmFuncs->internalExitVMToJNI(currentThread);
108
if (J9_ARE_ALL_BITS_SET(flags, CLASSOPTION_FLAG_HIDDEN)) {
109
options |= (J9_FINDCLASS_FLAG_HIDDEN | J9_FINDCLASS_FLAG_UNSAFE);
110
} else {
111
/* Validate the name for a normal (non-hidden) class. */
112
validateName = TRUE;
113
}
114
if (J9_ARE_ALL_BITS_SET(flags, CLASSOPTION_FLAG_NESTMATE)) {
115
options |= J9_FINDCLASS_FLAG_CLASS_OPTION_NESTMATE;
116
}
117
if (J9_ARE_ALL_BITS_SET(flags, CLASSOPTION_FLAG_STRONG)) {
118
options |= J9_FINDCLASS_FLAG_CLASS_OPTION_STRONG;
119
} else {
120
options |= J9_FINDCLASS_FLAG_ANON;
121
}
122
123
jsize length = env->GetArrayLength(classRep);
124
125
jclass result = defineClassCommon(env, receiver, className, classRep, 0, length, protectionDomain, &options, hostClazz, NULL, validateName);
126
if (env->ExceptionCheck()) {
127
return NULL;
128
} else if (NULL == result) {
129
throwNewInternalError(env, NULL);
130
return NULL;
131
}
132
133
vmFuncs->internalEnterVMFromJNI(currentThread);
134
if (NULL != classData) {
135
j9object_t classDataObject = J9_JNI_UNWRAP_REFERENCE(classData);
136
j9object_t resultClassObject = J9_JNI_UNWRAP_REFERENCE(result);
137
J9VMJAVALANGCLASS_SET_CLASSDATA(currentThread, resultClassObject, classDataObject);
138
}
139
140
j9object_t classObject = J9_JNI_UNWRAP_REFERENCE(result);
141
J9Class *j9clazz = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, classObject);
142
if (init) {
143
if (VM_VMHelpers::classRequiresInitialization(currentThread, j9clazz)) {
144
vmFuncs->initializeClass(currentThread, j9clazz);
145
j9clazz = J9_CURRENT_CLASS(j9clazz);
146
}
147
} else {
148
/* Should link the class, see https://github.com/eclipse-openj9/openj9/issues/10297 */
149
vmFuncs->prepareClass(currentThread, j9clazz);
150
}
151
152
vmFuncs->internalExitVMToJNI(currentThread);
153
return result;
154
}
155
#endif /* JAVA_SPEC_VERSION >= 15 */
156
157
158
jboolean JNICALL
159
Java_java_lang_ClassLoader_foundJavaAssertOption(JNIEnv *env, jclass ignored)
160
{
161
J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM;
162
163
return J9_ARE_ALL_BITS_SET(javaVM->extendedRuntimeFlags, J9_EXTENDED_RUNTIME_FOUND_JAVA_ASSERT_OPTION);
164
}
165
166
jint JNICALL
167
Java_com_ibm_oti_vm_BootstrapClassLoader_addJar(JNIEnv *env, jobject receiver, jbyteArray jarPath)
168
{
169
jint newCount = 0;
170
J9VMThread * currentThread = (J9VMThread *) env;
171
J9JavaVM * vm = currentThread->javaVM;
172
J9InternalVMFunctions * vmFuncs = vm->internalVMFunctions;
173
174
PORT_ACCESS_FROM_JAVAVM(vm);
175
176
UDATA jarPathSize = (UDATA)env->GetArrayLength(jarPath);
177
char *jarPathBuffer = (char *)j9mem_allocate_memory(jarPathSize + 1, J9MEM_CATEGORY_CLASSES);
178
179
if (NULL != jarPathBuffer) {
180
/* Use exclusive access to modify the array */
181
vmFuncs->internalEnterVMFromJNI(currentThread);
182
vmFuncs->acquireExclusiveVMAccess(currentThread);
183
VM_ArrayCopyHelpers::memcpyFromArray(currentThread, J9_JNI_UNWRAP_REFERENCE(jarPath), (UDATA)0, (UDATA)0, jarPathSize, (void*)jarPathBuffer);
184
jarPathBuffer[jarPathSize] = 0; /* null character terminated */
185
newCount = (jint)addJarToSystemClassLoaderClassPathEntries(vm, jarPathBuffer);
186
j9mem_free_memory(jarPathBuffer);
187
vmFuncs->releaseExclusiveVMAccess(currentThread);
188
vmFuncs->internalExitVMToJNI(currentThread);
189
}
190
/* If any error occurred, throw OutOfMemoryError */
191
if (0 == newCount) {
192
vmFuncs->throwNativeOOMError(env, J9NLS_JCL_UNABLE_TO_CREATE_CLASS_PATH_ENTRY);
193
}
194
return newCount;
195
}
196
197
} /* extern "C" */
198
199