RFR: 8340840: jshell ClassFormatError when making inner class static
Jan Lahoda
jlahoda at openjdk.org
Fri Oct 17 16:19:11 UTC 2025
On Tue, 7 Oct 2025 15:37:46 GMT, Chen Liang <liach at openjdk.org> wrote:
>> Consider a JShell interaction like:
>>
>> jshell> class O { class I {} }
>> | created class O
>>
>> jshell> var i = new O().new I();
>> i ==> O$I at 77caeb3e
>>
>> jshell> class O { static class I {} }
>> Exception in thread "main" java.lang.ClassFormatError: class not in class file format
>> at jdk.jdi/com.sun.tools.jdi.VirtualMachineImpl.redefineClasses(VirtualMachineImpl.java:396)
>> at jdk.jshell/jdk.jshell.execution.JdiExecutionControl.redefine(JdiExecutionControl.java:90)
>> at jdk.jshell/jdk.jshell.Unit.doRedefines(Unit.java:312)
>> at jdk.jshell/jdk.jshell.Eval.lambda$compileAndLoad$27(Eval.java:1120)
>> at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
>> at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:722)
>> at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
>> at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
>> at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
>> at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
>> at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
>> at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
>> at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
>> at jdk.jshell/jdk.jshell.Eval.lambda$compileAndLoad$29(Eval.java:1121)
>> at jdk.jshell/jdk.jshell.TaskFactory.lambda$runTask$4(TaskFactory.java:213)
>> at jdk.compiler/com.sun.tools.javac.api.JavacTaskPool.getTask(JavacTaskPool.java:193)
>> at jdk.jshell/jdk.jshell.TaskFactory.runTask(TaskFactory.java:206)
>> at jdk.jshell/jdk.jshell.TaskFactory.compile(TaskFactory.java:186)
>> at jdk.jshell/jdk.jshell.Eval.compileAndLoad(Eval.java:1100)
>> at jdk.jshell/jdk.jshell.Eval.declare(Eval.java:901)
>> at jdk.jshell/jdk.jshell.Eval.eval(Eval.java:140)
>> at jdk.jshell/jdk.jshell.JShell.eval(JShell.java:513)
>> at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:3633)
>> at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:1353)
>> at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processInput(JShellTool.java:1251)
>> ...
>
> src/jdk.jshell/share/classes/jdk/jshell/execution/JdiExecutionControl.java line 93:
>
>> 91: } catch (EngineTerminationException ex) {
>> 92: throw ex;
>> 93: } catch (Exception | LinkageError ex) {
>
> How was ClassFormatError previously thrown here? Was it wrapped in some exception?
It was simply thrown out of the redefine method, as the stacktrace in the summary suggests. Note that the javadoc for `redefineClasses` is very clear it may throw `ClassFormatError`:
https://docs.oracle.com/en/java/javase/25/docs/api/jdk.jdi/com/sun/jdi/VirtualMachine.html#redefineClasses(java.util.Map)
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/27665#discussion_r2440518160
More information about the compiler-dev
mailing list