当前位置: 首页 > news >正文

Java 8 lambda的一个编译bug

最近利用github action向Maven中央仓库发布企业微信SDK时会失败,从日志中发现是系统资源耗尽了,日志如下:

[INFO] Changes detected - recompiling the module! :dependency
[INFO] Compiling 35 source files with javac [debug target 8] to target/classesThe system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowErrorat com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2435)…………

编译的环境是 Java 8

应该是递归引用导致OOM了,但是仔细REVIEW了代码并没有发现问题。困扰了一个多月。今天终于解决了,问题是由下面的代码引起的:

public final class WecomUserAgent {/*** 版本号*/public static final String VERSION = "1.2.4";/*** UserAgent*/public static final String WECOM_USER_AGENT= "Wecom/" + VERSION + Optional.ofNullable(System.getProperty("java.version")).map(javaVersion -> " Java/" + javaVersion).orElse("");private WecomUserAgent() {}
}

根本的原因在于上面的静态变量WECOM_USER_AGENT

Java 8 中,被标记final的静态属性初始化时如果在字符串拼接中使用了lambda流操作,可能导致javac递归,最终堆栈溢出。该问题在Java 9得到了修复
Bug报告:https://bugs.openjdk.org/browse/JDK-8077605

解决方法

升级JDK

升级JDK到9+ 就可以直接解决这个问题。

兼容写法

如果无法直接升级JDK,可以使用静态块来初始化:

public final class WecomUserAgent {/*** 版本号*/public static final String VERSION = "1.2.4";/*** UserAgent*/public static final String WECOM_USER_AGENT;static {WECOM_USER_AGENT = "Wecom/" + VERSION + Optional.ofNullable(System.getProperty("java.version")).map(javaVersion -> " Java/" + javaVersion).orElse("");}private WecomUserAgent() {}
}
http://www.lryc.cn/news/249175.html

相关文章:

  • 无人机覆盖路径规划综述
  • 【代码随想录】算法训练计划37
  • 网络基础_1
  • 机器学习:DBSCAN算法(效果比K-means好)
  • 在Spring Boot中隔离@Async异步任务的线程池
  • FFmpeg架构全面分析
  • OAuth(开放授权)介绍
  • Online ddl和replace ddl
  • WEB渗透—反序列化(九)
  • 蓝桥杯day02——第三大的数
  • linux shell中set -e命令的作用
  • linux shell 字符替换命令
  • Vue3生命周期函数(简述题)
  • 11月29日,每日信息差//雷军个人向武汉大学捐赠13亿元现金//看电视默认设置新规一览:开机广告不超 5 秒、不设置一键付费
  • 融资经理简历模板
  • iptables防火墙之SNAT与DNET
  • mysql使用--备份与恢复
  • 【vue实战项目】通用管理系统:信息列表,信息录入
  • 【驱动】SPI驱动分析(六)-RK SPI驱动分析
  • 【Linux】基础IO--文件基础知识/文件操作/文件描述符
  • Intellij IDEA 的安装和使用以及配置
  • Zynq-Linux移植学习笔记之67- 国产ZYNQ上通过GPIO模拟MDC/MDIO协议
  • Zookeeper(一)在WSL单机搭建Zookeeper伪集群
  • QT(18):QString
  • 宏工科技通过CMMI三级认证,软件研发能力获国际权威认可
  • 2次MD5加密——用于分布式对话
  • 用Java制作简易版的王者荣耀
  • android 保活的一种有效的方法
  • kibana安装
  • LV.12 D19 ADC实验 学习笔记