Skip to content

Commit 2440911

Browse files
Improve ClassCastException message
1 parent 23e9ca9 commit 2440911

File tree

3 files changed

+18
-25
lines changed

3 files changed

+18
-25
lines changed

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/constantpool/RuntimeConstantPool.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -378,21 +378,7 @@ public ResolvedClassConstant resolveClassConstant(int classIndex, ObjectKlass ac
378378
"Access check of: " + checkedKlass.getType() + " from " + accessingKlass.getType() + " throws IllegalAccessError");
379379
StringBuilder errorMessage = new StringBuilder("failed to access class ");
380380
errorMessage.append(checkedKlass.getExternalName()).append(" from class ").append(accessingKlass.getExternalName());
381-
if (context.getJavaVersion().modulesEnabled()) {
382-
errorMessage.append(" (");
383-
if (accessingKlass.module() == checkedKlass.module()) {
384-
errorMessage.append(checkedKlass.getExternalName());
385-
errorMessage.append(" and ");
386-
ClassRegistry.classInModuleOfLoader(context.getClassLoadingEnv(), accessingKlass, true, errorMessage, meta);
387-
} else {
388-
// checkedKlass is not an array type (getElementalType) nor a
389-
// primitive type (it would have passed the access checks)
390-
ClassRegistry.classInModuleOfLoader(context.getClassLoadingEnv(), (ObjectKlass) checkedKlass, false, errorMessage, meta);
391-
errorMessage.append("; ");
392-
ClassRegistry.classInModuleOfLoader(context.getClassLoadingEnv(), accessingKlass, false, errorMessage, meta);
393-
}
394-
errorMessage.append(")");
395-
}
381+
ClassRegistry.appendModuleAndLoadersDetails(context.getClassLoadingEnv(), checkedKlass, accessingKlass, errorMessage, context);
396382
throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, errorMessage.toString());
397383
}
398384
return new ResolvedFoundClassConstant(klass);

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistry.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ private ObjectKlass createKlass(EspressoContext context, ParserKlass parserKlass
629629
}
630630
if (!Klass.checkAccess(superKlass, klass)) {
631631
StringBuilder sb = new StringBuilder().append("class ").append(klass.getExternalName()).append(" cannot access its superclass ").append(superKlass.getExternalName());
632-
superTypeAccessMessage(env, klass, superKlass, sb, context);
632+
appendModuleAndLoadersDetails(env, klass, superKlass, sb, context);
633633
throw EspressoClassLoadingException.illegalAccessError(sb.toString());
634634
}
635635
if (!superKlass.permittedSubclassCheck(klass)) {
@@ -641,7 +641,7 @@ private ObjectKlass createKlass(EspressoContext context, ParserKlass parserKlass
641641
if (interf != null) {
642642
if (!Klass.checkAccess(interf, klass)) {
643643
StringBuilder sb = new StringBuilder().append("class ").append(klass.getExternalName()).append(" cannot access its superinterface ").append(interf.getExternalName());
644-
superTypeAccessMessage(env, klass, interf, sb, context);
644+
appendModuleAndLoadersDetails(env, klass, interf, sb, context);
645645
throw EspressoClassLoadingException.illegalAccessError(sb.toString());
646646
}
647647
if (!interf.permittedSubclassCheck(klass)) {
@@ -653,24 +653,24 @@ private ObjectKlass createKlass(EspressoContext context, ParserKlass parserKlass
653653
return klass;
654654
}
655655

656-
private static void superTypeAccessMessage(ClassLoadingEnv env, ObjectKlass sub, ObjectKlass sup, StringBuilder sb, EspressoContext context) {
656+
public static void appendModuleAndLoadersDetails(ClassLoadingEnv env, Klass klass1, Klass klass2, StringBuilder sb, EspressoContext context) {
657657
if (context.getJavaVersion().modulesEnabled()) {
658658
sb.append(" (");
659659
Meta meta = context.getMeta();
660-
if (sup.module() == sub.module()) {
661-
sb.append(sub.getExternalName());
660+
if (klass2.module() == klass1.module()) {
661+
sb.append(klass1.getExternalName());
662662
sb.append(" and ");
663-
classInModuleOfLoader(env, sup, true, sb, meta);
663+
classInModuleOfLoader(env, klass2, true, sb, meta);
664664
} else {
665-
classInModuleOfLoader(env, sub, false, sb, meta);
665+
classInModuleOfLoader(env, klass1, false, sb, meta);
666666
sb.append("; ");
667-
classInModuleOfLoader(env, sup, false, sb, meta);
667+
classInModuleOfLoader(env, klass2, false, sb, meta);
668668
}
669669
sb.append(")");
670670
}
671671
}
672672

673-
public static void classInModuleOfLoader(ClassLoadingEnv env, ObjectKlass klass, boolean plural, StringBuilder sb, Meta meta) {
673+
public static void classInModuleOfLoader(ClassLoadingEnv env, Klass klass, boolean plural, StringBuilder sb, Meta meta) {
674674
assert meta.getJavaVersion().modulesEnabled() && meta.java_lang_ClassLoader_nameAndId != null;
675675
sb.append(klass.getExternalName());
676676
if (plural) {

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/CheckCastQuickNode.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
2626
import com.oracle.truffle.api.frame.VirtualFrame;
2727
import com.oracle.truffle.espresso.classfile.bytecode.Bytecodes;
28+
import com.oracle.truffle.espresso.impl.ClassRegistry;
2829
import com.oracle.truffle.espresso.impl.Klass;
2930
import com.oracle.truffle.espresso.meta.Meta;
3031
import com.oracle.truffle.espresso.nodes.BytecodeNode;
3132
import com.oracle.truffle.espresso.nodes.EspressoFrame;
3233
import com.oracle.truffle.espresso.nodes.bytecodes.InstanceOf;
34+
import com.oracle.truffle.espresso.runtime.EspressoContext;
3335
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
3436

3537
public final class CheckCastQuickNode extends QuickNode {
@@ -62,6 +64,11 @@ public int execute(VirtualFrame frame, boolean isContinuationResume) {
6264

6365
@TruffleBoundary
6466
private String getExceptionMessage(BytecodeNode root, StaticObject receiver) {
65-
return receiver.getKlass().getType() + " cannot be cast to: " + typeToCheck.getType() + " in context " + root.getMethod().toString();
67+
Klass receiverKlass = receiver.getKlass();
68+
StringBuilder sb = new StringBuilder();
69+
sb.append("class ").append(receiverKlass.getExternalName()).append(" cannot be cast to ").append(typeToCheck.getExternalName());
70+
EspressoContext context = root.getMethod().getContext();
71+
ClassRegistry.appendModuleAndLoadersDetails(context.getClassLoadingEnv(), receiverKlass, typeToCheck, sb, context);
72+
return sb.toString();
6673
}
6774
}

0 commit comments

Comments
 (0)