Skip to content

Commit

Permalink
Merge pull request #20 from babsingh/jcl_npe_to_ncdfe
Browse files Browse the repository at this point in the history
Throw NoClassDefFoundError: MH.resolveInvokeDynamic(...)
  • Loading branch information
pshipton authored Sep 28, 2017
2 parents 7e75f6d + a45bf26 commit b5f3cc5
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 0 deletions.
38 changes: 38 additions & 0 deletions jcl/src/java.base/share/classes/java/lang/invoke/MethodHandle.java
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,21 @@ MethodHandle insertArguments(MethodHandle equivalent, MethodHandle unboxingHandl
* equivalent for MethodHandle.
*/
private static final native MethodHandle getCPMethodHandleAt(Class<?> clazz, int index);

/**
* Get the class name from a constant pool class element, which is located
* at the specified <i>index</i> in <i>clazz</i>'s constant pool.
*
* @param an instance of class - its constant pool is accessed
* @param the constant pool index
*
* @return instance of String which contains the class name or NULL in
* case of error
*
* @throws NullPointerException if <i>clazz</i> is null
* @throws IllegalArgumentException if <i>index</i> has wrong constant pool type
*/
private static final native String getCPClassNameAt(Class<?> clazz, int index);

private static final int BSM_ARGUMENT_SIZE = Short.SIZE / Byte.SIZE;
private static final int BSM_ARGUMENT_COUNT_OFFSET = BSM_ARGUMENT_SIZE;
Expand Down Expand Up @@ -861,6 +876,9 @@ private static final MethodHandle resolveInvokeDynamic(Class<?> clazz, String na
switch (cpType) {
case 1:
cpEntry = cp.getClassAt(index);
if (cpEntry == null) {
throw throwNoClassDefFoundError(clazz, index);
}
break;
case 2:
cpEntry = cp.getStringAt(index);
Expand Down Expand Up @@ -991,6 +1009,26 @@ private static Throwable throwNoClassDefFoundError(TypeNotPresentException e) {
}
throw e;
}

/**
* Retrieve the class name of the constant pool class element located at the specified
* index in clazz's constant pool. Then, throw a NoClassDefFoundError with the cause
* set as ClassNotFoundException. The message of NoClassDefFoundError and
* ClassNotFoundException contains the name of the class, which couldn't be found.
*
* @param an instance of Class - its constant pool is accessed
* @param integer value of the constant pool index
*
* @return Throwable to prevent any fall through case
*
* @throws NoClassDefFoundError with the cause set as ClassNotFoundException
*/
private static Throwable throwNoClassDefFoundError(Class<?> clazz, int index) {
String className = getCPClassNameAt(clazz, index);
NoClassDefFoundError noClassDefFoundError = new NoClassDefFoundError(className);
noClassDefFoundError.initCause(new ClassNotFoundException(className));
throw noClassDefFoundError;
}

@Override
public String toString() {
Expand Down
50 changes: 50 additions & 0 deletions runtime/jcl/common/sun_reflect_ConstantPool.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,56 @@ Java_sun_reflect_ConstantPool_getFieldAtIfLoaded0(JNIEnv *env, jobject unusedObj
return getFieldAt(env, constantPoolOop, cpIndex, J9_RESOLVE_FLAG_JIT_COMPILE_TIME | J9_RESOLVE_FLAG_NO_THROW_ON_FAIL);
}

/**
* Get the class name from a constant pool class element, which is located
* at the specified index in a class's constant pool.
*
* @param env[in] the JNI env
* @param unusedObject[in] unused
* @param constantPoolOop[in] the class - its constant pool is accessed
* @param cpIndex[in] the constant pool index
*
* @return instance of String which contains the class name or NULL in
* case of error
*
* @throws NullPointerException if constantPoolOop is null
* @throws IllegalArgumentException if cpIndex has wrong type
*/
jobject JNICALL
Java_java_lang_invoke_MethodHandle_getCPClassNameAt(JNIEnv *env, jobject unusedObject, jobject constantPoolOop, jint cpIndex)
{
jobject classNameObject = NULL;
J9VMThread *vmThread = (J9VMThread *) env;
J9InternalVMFunctions *vmFunctions = vmThread->javaVM->internalVMFunctions;
J9MemoryManagerFunctions *gcFunctions = vmThread->javaVM->memoryManagerFunctions;
SunReflectCPResult result = NULL_POINTER_EXCEPTION;

if (NULL != constantPoolOop) {
UDATA cpType = J9CPTYPE_UNUSED;
J9ROMConstantPoolItem *romCPItem = NULL;
vmFunctions->internalEnterVMFromJNI(vmThread);
result = getROMCPItemAndType(vmThread, constantPoolOop, cpIndex, &cpType, &romCPItem);
if (OK == result) {
switch (cpType) {
case J9CPTYPE_CLASS: {
J9UTF8 *className = J9ROMCLASSREF_NAME((J9ROMClassRef*)romCPItem);
j9object_t internalClassNameObject = gcFunctions->j9gc_createJavaLangString(vmThread, J9UTF8_DATA(className), (U_32) J9UTF8_LENGTH(className), 0);
classNameObject = vmFunctions->j9jni_createLocalRef(env, internalClassNameObject);
break;
}
default:
result = WRONG_CP_ENTRY_TYPE_EXCEPTION;
break;
}
}
vmFunctions->internalReleaseVMAccess(vmThread);
}

checkResult(env, result);

return classNameObject;
}

jobject JNICALL
Java_sun_reflect_ConstantPool_getMemberRefInfoAt0(JNIEnv *env, jobject unusedObject, jobject constantPoolOop, jint cpIndex)
{
Expand Down
1 change: 1 addition & 0 deletions runtime/jcl/uma/se7_exports.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<export name="Java_java_lang_invoke_MethodHandle_getCPTypeAt" />
<export name="Java_java_lang_invoke_MethodHandle_getCPMethodTypeAt" />
<export name="Java_java_lang_invoke_MethodHandle_getCPMethodHandleAt" />
<export name="Java_java_lang_invoke_MethodHandle_getCPClassNameAt" />
<export name="Java_java_lang_invoke_ThunkTuple_registerNatives" />
<export name="Java_java_lang_invoke_InterfaceHandle_registerNatives" />
<export name="Java_java_lang_invoke_MethodType_makeTenured" />
Expand Down
1 change: 1 addition & 0 deletions runtime/oti/jclprots.h
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,7 @@ jobject JNICALL Java_sun_reflect_ConstantPool_getUTF8At0(JNIEnv *env, jobject un
jint JNICALL Java_java_lang_invoke_MethodHandle_getCPTypeAt(JNIEnv *env, jclass unusedClass, jobject constantPoolOop, jint cpIndex);
jobject JNICALL Java_java_lang_invoke_MethodHandle_getCPMethodTypeAt(JNIEnv *env, jclass unusedClass, jobject constantPoolOop, jint cpIndex);
jobject JNICALL Java_java_lang_invoke_MethodHandle_getCPMethodHandleAt(JNIEnv *env, jclass unusedClass, jobject constantPoolOop, jint cpIndex);
jobject JNICALL Java_java_lang_invoke_MethodHandle_getCPClassNameAt(JNIEnv *env, jobject unusedObject, jobject constantPoolOop, jint cpIndex);
jint JNICALL Java_jdk_internal_reflect_ConstantPool_getClassRefIndexAt0(JNIEnv *env, jobject unusedObject, jobject constantPoolOop, jint cpIndex);
jint JNICALL Java_jdk_internal_reflect_ConstantPool_getNameAndTypeRefIndexAt0(JNIEnv *env, jobject unusedObject, jobject constantPoolOop, jint cpIndex);
jobject JNICALL Java_jdk_internal_reflect_ConstantPool_getNameAndTypeRefInfoAt0(JNIEnv *env, jobject unusedObject, jobject constantPoolOop, jint cpIndex);
Expand Down

0 comments on commit b5f3cc5

Please sign in to comment.