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