-
Bug
-
Resolution: Fixed
-
P4
-
19, 20
-
b15
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8305394 | 17.0.8-oracle | Weibing Xiao | P4 | Resolved | Fixed | b02 |
JDK-8306293 | 17.0.8 | Goetz Lindenmaier | P4 | Resolved | Fixed | b01 |
Run jshell with the enclosed sample files. You will get StackOverflowError
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
jshell --enable-preview JsonToken.java SerializeTest.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
jshell should run and load the Java files
ACTUAL -
Exception in thread "main" java.lang.InternalError: Exception during analyze - java.lang.StackOverflowError
at jdk.jshell/jdk.jshell.TaskFactory$AnalyzeTask.analyze(TaskFactory.java:415)
at jdk.jshell/jdk.jshell.TaskFactory$AnalyzeTask.<init>(TaskFactory.java:406)
at jdk.jshell/jdk.jshell.TaskFactory.lambda$analyze$1(TaskFactory.java:178)
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.analyze(TaskFactory.java:175)
at jdk.jshell/jdk.jshell.TaskFactory.analyze(TaskFactory.java:161)
at jdk.jshell/jdk.jshell.Eval.compileAndLoad(Eval.java:1060)
at jdk.jshell/jdk.jshell.Eval.declare(Eval.java:893)
at jdk.jshell/jdk.jshell.Eval.eval(Eval.java:140)
at jdk.jshell/jdk.jshell.JShell.eval(JShell.java:493)
at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:3624)
at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:1348)
at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processInput(JShellTool.java:1246)
at jdk.jshell/jdk.internal.jshell.tool.JShellTool.run(JShellTool.java:1217)
at jdk.jshell/jdk.internal.jshell.tool.JShellTool.runFile(JShellTool.java:3105)
at jdk.jshell/jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:962)
at jdk.jshell/jdk.internal.jshell.tool.JShellToolBuilder.start(JShellToolBuilder.java:261)
at jdk.jshell/jdk.internal.jshell.tool.JShellToolProvider.main(JShellToolProvider.java:120)
Caused by: java.lang.IllegalStateException: java.lang.StackOverflowError
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:383)
at jdk.jshell/jdk.jshell.TaskFactory$AnalyzeTask.analyze(TaskFactory.java:412)
... 19 more
Caused by: java.lang.StackOverflowError
at jdk.compiler/com.sun.tools.javac.code.Type.equalsIgnoreMetadata(Type.java:513)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1083)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1077)
at jdk.compiler/com.sun.tools.javac.code.Types.isSuperType(Types.java:1304)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1086)
---------- BEGIN SOURCE ----------
JsonToken.java
public sealed interface JsonToken
{
record BeginArrayToken()
implements JsonToken {}
record EndArrayToken()
implements JsonToken {}
record BeginObjectToken()
implements JsonToken {}
record EndObjectToken()
implements JsonToken {}
record ObjectNameToken(String name)
implements JsonToken {}
record ValueSeparatorToken()
implements JsonToken {}
record StringToken(String value)
implements JsonToken {}
record NumberToken(Number value)
implements JsonToken {}
record BooleanToken(boolean value)
implements JsonToken {}
record NullToken()
implements JsonToken {}
}
======================
SerializeTest.java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.RecordComponent;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
public interface JsonSerializer
{
static JsonSerializer instance()
{
return new JsonSerializer() {};
}
default Stream<JsonToken> serialize(Object o)
{
return switch (o) {
case null -> Stream.of(new JsonToken.NullToken());
case String str -> Stream.of(new JsonToken.StringToken(str));
case Number n -> Stream.of(new JsonToken.NumberToken(n));
case Boolean b -> Stream.of(new JsonToken.BooleanToken(b));
case Enum<?> e -> Stream.of(new JsonToken.StringToken(e.name()));
case Optional<?> optional -> serialize(optional.orElse(null));
case Collection<?> collection -> serializeCollection(collection);
case Object ignore when o.getClass().isRecord() -> serializeRecord(o);
default -> throw new IllegalArgumentException(); // we don't support this type
};
}
Stream<JsonToken> serializeCollection(Collection<?> collection)
{
Stream.Builder<Stream<JsonToken>> builder = Stream.builder();
builder.accept(Stream.of(JsonToken.BeginArrayToken.INSTANCE));
boolean first = true;
for (Object value : collection) {
if (first) {
first = false;
}
else {
builder.add(Stream.of(JsonToken.ValueSeparatorToken.INSTANCE));
}
builder.accept(serialize(value));
}
builder.accept(Stream.of(JsonToken.EndArrayToken.INSTANCE));
return builder.build().flatMap(Function.identity());
}
Stream<JsonToken> serializeRecord(Object record)
{
RecordComponent[] recordComponents = record.getRecordComponents();
Stream.Builder<Stream<JsonToken>> builder = Stream.builder();
builder.accept(Stream.of(JsonToken.BeginObjectToken.INSTANCE));
boolean first = true;
for (RecordComponent recordComponent : recordComponents) {
if (first) {
first = false;
}
else {
builder.accept(Stream.of(JsonToken.ValueSeparatorToken.INSTANCE));
}
builder.accept(Stream.of(new JsonToken.ObjectNameToken(recordComponent.getName())));
try {
Object o = recordComponent.getAccessor().invoke(record);
builder.accept(serialize(o));
}
catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
builder.accept(Stream.of(JsonToken.EndObjectToken.INSTANCE));
return builder.build().flatMap(Function.identity());
}
}
---------- END SOURCE ----------
FREQUENCY : always
- backported by
-
JDK-8305394 Non-default method in interface leads to a stack overflow in JShell
- Resolved
-
JDK-8306293 Non-default method in interface leads to a stack overflow in JShell
- Resolved
- duplicates
-
JDK-8302862 JShell crashes when trying to throw a non-exist exception in certain lambdas
- Closed
- relates to
-
JDK-8305714 Add an extra test for JDK-8292755
- Resolved
- links to
-
Commit openjdk/jdk17u-dev/b0e142e7
-
Commit openjdk/jdk/2a387918
-
Review openjdk/jdk17u-dev/1245
-
Review openjdk/jdk/10221