最近生产程序有个公共包内有900多个文件,使用JDK1.6打包可以顺利打出jar,目前需要升级到1.8,然后就打包提示 java.lang.StackOverflowError,具体部分信息如下:
compile:
[echo] +---------------------------------------------------+
[echo] | C O M P I L I N G S O U R C E S |
[echo] +---------------------------------------------------+
[javac] E:\workspace\RE_PSS_XX\build.xml:61: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 395 source files to E:\workspace\RE_PSS_XX\classes
[javac] 系统资源不足。
[javac] 有关详细信息, 请参阅以下堆栈跟踪。
[javac] java.lang.StackOverflowError
[javac] at com.sun.tools.javac.comp.Attr.attribArgs(Attr.java:668)
[javac] at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1816)
[javac] at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465)
[javac] at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)
Build.xml文件出错的一步是
<!-- =================================================================== -->
<!-- Compiles all the source code to build path -->
<!-- =================================================================== -->
<target name="compile" description="Compile all the source code.">
<echo>+---------------------------------------------------+</echo>
<echo>| C O M P I L I N G S O U R C E S |</echo>
<echo>+---------------------------------------------------+</echo>
<javac srcdir="${src.dir}" classpathref="project.class.path" destdir="${build.classes}" fork="yes" debug="on" />
</target>
尝试一、修改编译命令
根据Javac命令格式,我们进行了添加内存大小、fork等的设置:
<!-- =================================================================== -->
<!-- Compiles all the source code to build path -->
<!-- =================================================================== -->
<target name="compile" description="Compile all the source code.">
<echo>+---------------------------------------------------+</echo>
<echo>| C O M P I L I N G S O U R C E S |</echo>
<echo>+---------------------------------------------------+</echo>
<javac fork="true" executable="D:\ProgramFiles\Java\jdk1.8.0_144\bin\javac"
srcdir="${src.dir}" memoryInitialSize="512m" memorymaximumsize="1024m"
destdir="${build.classes}" classpathref="project.class.path" debug="on"
deprecation="on"/>
</target>
然后问题依然没有解决;
尝试二、文件缩减拆包
排查策略:
1、采用减法策略,按各子模块包名进行删除,直到能顺利打包,定位问题的大致范围;
2、定位到某个模块,按实体对象进行,entity、dao、service的删除,并验证打包结果;
3、定位到某一个能影响打包结果的文件;
4、分析该文件,发现是个大表(栏位200个)的DaoImpl文件,比如自动化生成的 batchInsertPerApp(final List<PerApp> list)有1000行,注释掉改方法,打包顺利通过;
5、发现问题是出在大文件的巨型方法上,查找其他类似问题,逐个解决;
经过删减非必须的冗余文件,并修改超大方法以后,包顺利打出;
遗留问题:
JDK1.6和1.8在大文件打包上存在差异,具体原因待排查,有类似的同学可以留言交流;
附参考资料
# 相关Javac的网文资料摘要:
<target name="compile" depends="clean">
<mkdir dir="build/classes"/>
<javac destdir="build/classes" debug="on" fork="true" memoryInitialSize="512m" memorymaximumsize="500M source="1.5" target="1.5" deprecation="on" >
<!-- srcdir 源目录(在这里为源代码目录)destdir目标目录 即编译完成后存放class文件的目录 -->
<src path="src"/>
<src path="eventinfo"/>
</javac>
</target>
fork
是否执行外部的javac
如果没有制定fork属性默认为false javac和ant命令将在同一个进程中执行 容易出现内存溢出 同时javac被分配的内存只有64MB,如果指定fork属性为true,javac命令将和ant不在同一个进程中执行,分配内存的大小将为
memoryinitialsize(获得基本vm初始内存大小)、memorymaximumsize(最大内存大小)指定的大小。
source:指定版本号使编译出的(文件)类兼容该版本
一般jdk都向下兼容向上不兼容 source在这里指编译出向下兼容的版本的类
如果用Eclipse,你可以在项目属性中编译选项里有设置生成兼容JDK1.4的类。但是如果你在Eclipse里自己写Ant脚本用<javac> 命令去编译java类,则生成的仍为JDK1.5的类(执行Ant脚本时与Eclipse设置的编译选项无关)。如何解决了,其实很简单,只要在<javac> ant 命令里加source参数。
target:根据指定的vm版本生成class文件
<target name="main3">
<delete dir="${class.dir}"/>
<mkdir dir="${class.dir}"/>
<javac fork="true" executable="D:\Java\jdk1.5.0_10\bin\javac" srcdir="${src.dir}" destdir="${class.dir}">
<classpath refid="classpath" />
</javac>
</target>
为javac 任务指定fork和executable,是用指定编译器编译,这个方法更灵活,您甚至可以指定非sun公司的java编译器
<target name="-compile">
< javac srcdir="${srcdir}" destdir="${builddir}" fork="true" memorymaximumsize="500M" includes="**/*.java" classpathref="class_path">
<compilerarg value="-Xlint:unchecked"/>
</javac>
</target>
<javac
srcdir="@{srcdir}"
destdir="@{destdir}"
includeantruntime="@{includeantruntime}"
debug="@{debug}"
deprecation="@{deprecation}"
target="@{target}"
source="@{target}"
fork="@{fork}"
executable="@{executable}"
memoryInitialSize="@{memoryInitialSize}"
memoryMaximumSize="@{memoryMaximumSize}">
<compilerarg compiler="${build.compiler}" line="${build.compiler.args}"/>
<javac-elements/>
</javac>
Jard打包
<jar destfile="${webRoot}/${ash_jar}" level="9" compress="true" encoding="utf-8" basedir="${dest}">
<manifest>
<attribute name="Implementation-Version" value="Version: 2.2"/>
</manifest>
</jar>
ant编译项目出现 [javac] 系统资源不足
https://www.cnblogs.com/huige-you/p/3726770.html