Post

今天发现一个JDK编译器的bug

平平淡淡的一天,正常写开发输出代码,但在打包编译时就懵了,编译出错,正常错误还好,根据提示修改即可,但这次报的却是java.lang.StackOverflowError

我懵了:这ide也没提示有语法错误什么的啊,上个版本也能正常打包的啊

后来发现这可能是一个JDK编译器的bug, 具体情况是编译项目中的一个java类时,报StackOverflowError错误。

测试过以下jdk版本:

  • oricaljdk-1.8.0_271
  • oricaljdk-17.0.8
  • openjdk-17.0.2
  • openjdk-21.0.1

以上版本编译统一都报错如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
D:\workspace>javac Criteria.java


系统资源不足。
有关详细信息, 请参阅以下堆栈跟踪。
java.lang.StackOverflowError
        at jdk.compiler/com.sun.tools.javac.code.Type.equalsIgnoreMetadata(Type.java:513)
        at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.contains(Type.java:1150)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4769)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1681)
        at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4980)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4739)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1011)
        at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4980)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4771)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1681)
        at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4980)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4739)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1011)
        at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4980)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4771)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1681)

目前已经将bug上报了,等待官方反馈。

测试代码如下, 感兴趣的同学可以自己拿去javac编译下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package test;
import java.io.Serializable;
import test.Criteria.Builder;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class Criteria<B extends Builder<? extends Criteria>> implements Serializable {
	private static final long serialVersionUID = 5066371601838698479L;

	protected Criteria() {}

	protected Criteria(B builder) {
	}

  // 此处导致,做如下修改则能正常编译
  // 修改为 public static <B extends Builder> B builder()
	public static <B extends Builder<E>, E extends Criteria<B>> B builder() {
		return (B) new Builder<>();
	}

	public static class Builder<C extends Criteria<? extends Builder<C>>> {
		protected Builder() {
		}
		public Builder<C> page() {
			return this;
		}
		public C build() {
			return (C) new Criteria<Builder<C>>(this);
		}
	}
}

等官方反馈后在续上

2024-01-09 今天收到Oracle邮件回复,确认为bug, 目前已经被收录到jdk bug库 JDK 8 到 JDK 22 都存在此问题。

bug编号: JDK-8324809

This post is licensed under CC BY 4.0 by the author.