-
Notifications
You must be signed in to change notification settings - Fork 729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Throw NoClassDefFoundError instead of TypeNotPresentException #610
Throw NoClassDefFoundError instead of TypeNotPresentException #610
Conversation
2ebd50e
to
c9379d7
Compare
@DanHeidinga Should I create two versions of
|
Duplicating code isn't a great answer. What about modifying the resolve MT path to convert the TNPE to a NCDFE? |
0be2182
to
f4aea60
Compare
Code has been updated - modified resolve MT path. |
* instead of TypeNotPresentException during the VM resolve stage. | ||
* | ||
* @param methodDescriptor - the method descriptor string | ||
* @param loader - the ClassLoader to be used or null for System ClassLoader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loader
passed in here is from VMAccess.getClassloader() --> clazz.getClassLoaderImpl()
which returns the actual bootstrap classloader, not null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated description.
* @throws NoClassDefFoundError - if a named type cannot be found | ||
*/ | ||
private static final MethodType vmResolveFromMethodDescriptorString(String methodDescriptor, ClassLoader loader) throws Throwable { | ||
MethodType type = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initializing a variable to null
here is not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
private static final MethodType vmResolveFromMethodDescriptorString(String methodDescriptor, ClassLoader loader) throws Throwable { | ||
MethodType type = null; | ||
try { | ||
type = MethodType.fromMethodDescriptorString(methodDescriptor, loader); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably just return MethodType.fromMethodDescriptorString(methodDescriptor, loader);
.
} | ||
Assert.fail("NoClassDefFoundError not thrown when non-existent class is used to create MethodType via LDC"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Assert.fail
can be moved after MethodType mtToString = com.ibm.j9.jsr292.indyn.GenIndyn.ldc_invalid_type();
, and return
within catch
block can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
|
||
boolean typeNotPresentExceptionThrown = false; | ||
|
||
public void test_indyn_ldc_non_existent_class_methodtype() { | ||
try { | ||
MethodType mtToString = com.ibm.j9.jsr292.indyn.GenIndyn.ldc_invalid_type(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mtToString
is not used, can it be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should keep it since it tells what is being returned.
f4aea60
to
76cd3ff
Compare
runtime/vm/callin.cpp
Outdated
@@ -883,6 +883,24 @@ sendFromMethodDescriptorString(J9VMThread *currentThread, J9UTF8 *descriptor, J9 | |||
currentThread->returnValue2 = (UDATA)J9VMJAVALANGINVOKEMETHODTYPE_FROMMETHODDESCRIPTORSTRINGAPPENDARG_METHOD(vm); | |||
} | |||
c_cInterpreter(currentThread); | |||
if (VM_VMHelpers::exceptionPending(currentThread)) { | |||
j9object_t currentException = currentThread->currentException; | |||
J9Class *exceptionClass = J9VMJAVALANGTYPENOTPRESENTEXCEPTION(vm); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using name exceptionClassTNPE
offers better clarity. In addition, to achieve putting a rvalue on the left when comparing for equality later, pls define it as J9Class * const exceptionClassTNPE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done - changed to exceptionClassTNPE
and added const
.
runtime/vm/callin.cpp
Outdated
*/ | ||
if (exceptionClass == J9OBJECT_CLAZZ(currentThread, currentException)) { | ||
j9object_t cause = J9VMJAVALANGTHROWABLE_CAUSE(currentThread, currentException); | ||
J9Class *causeClass = J9VMJAVALANGCLASSNOTFOUNDEXCEPTION(vm); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, using name causeClassThrowable
offers better clarity. In addition, pls define it as J9Class * const causeClassThrowable
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done - changed to causeClassCNFE
and added const
.
a730300
to
3f6b771
Compare
runtime/vm/callin.cpp
Outdated
@@ -883,6 +883,24 @@ sendFromMethodDescriptorString(J9VMThread *currentThread, J9UTF8 *descriptor, J9 | |||
currentThread->returnValue2 = (UDATA)J9VMJAVALANGINVOKEMETHODTYPE_FROMMETHODDESCRIPTORSTRINGAPPENDARG_METHOD(vm); | |||
} | |||
c_cInterpreter(currentThread); | |||
if (VM_VMHelpers::exceptionPending(currentThread)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than duplicating this code natively, wouldn't it be cleaner to call vmResolveFromMethodDescriptorString()
directly and let the java code convert the TNPE to a CNFE?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be better in terms of avoiding duplicate code. But, sendFromMethodDescriptorString
calls MT.fromMethodDescriptorString
and MT.fromMethodDescriptorStringAppendArg
. So, the definition of MH.vmResolveFromMethodDescriptorString
will change.
private static final MethodType vmResolveFromMethodDescriptorString(String methodDescriptor, ClassLoader loader, Class<?> appendArgumentType) throws Throwable {
try {
if (null == appendArgumentType) {
return MethodType.fromMethodDescriptorString(methodDescriptor, loader);
} else {
return MethodType.fromMethodDescriptorStringAppendArg(methodDescriptor, loader, appendArgumentType);
}
} catch (TypeNotPresentException e) {
throw throwNoClassDefFoundError(e);
}
}
Currently, MT.fromMethodDescriptorStringAppendArg
is a private method. It will change to a public method since it will be used in MethodHandle.java
.
MH resolve code paths will become slightly longer due to this change. @DanHeidinga do you approve the above changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It cannot become a public method as that changes the public api for a class in the java.lang.invoke.* namespace.
It can become package or default access which will allow it to be called anywhere in the package without becoming API.
For the MH resolve, this shouldn't be an issue as the resolve occurs once per item.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
completed.
3f6b771
to
8f427bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change to the exception being thrown the expected behaviour in both Java 8 & 9?
try { | ||
if (null == appendArgumentType) { | ||
return MethodType.fromMethodDescriptorString(methodDescriptor, loader); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: an if
that terminates with a return or a throw doesn't need an else block after it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
8f427bd
to
6516407
Compare
This is a JVM requirement for both Java 8 and Java 9 during resolution.
|
} | ||
} | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you fix the formatting for the javadoc on this and the above method? The formatting is inconsistent between the two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
When the VM is resolving a MethodType, NoClassDefFoundError should be thrown instead of TypeNotPresentException. Signed-off-by: Babneet Singh <[email protected]>
Renamed test_indyn_ldc_invalid_type to test_indyn_ldc_non_existent_class_methodtype. Updated test to check for NoClassDefFoundError instead of TypeNotPresentException. Signed-off-by: Babneet Singh <[email protected]>
6516407
to
08d5f60
Compare
Jenkins test sanity plinux |
Change 1:
When the VM is resolving a
MethodType
,NoClassDefFoundError
should be thrown instead ofTypeNotPresentException
.Change 2:
Renamed
test_indyn_ldc_invalid_type
totest_indyn_ldc_non_existent_class_methodtype
. Updated test to check forNoClassDefFoundError
instead ofTypeNotPresentException
.Signed-off-by: Babneet Singh [email protected]