美文网首页工作生活
apache ant编译资源不足

apache ant编译资源不足

作者: 梦想又照进现实 | 来源:发表于2019-06-30 12:50 被阅读0次

最近生产程序有个公共包内有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

ant教程
https://www.w3cschool.cn/ant/vynj1hwi.html

相关文章

网友评论

    本文标题:apache ant编译资源不足

    本文链接:https://www.haomeiwen.com/subject/mxxbcctx.html