Ivy OutOfMemoryError during ivy:publish
Asked Answered
H

0

6

I am having an issue with Ivy uploading large(ish) artifacts to our in-house artifact server (Artifactory 3.9.2). When we upload a 400MB file, we run out of Java heap space and it fails (thus failing our CI build). We keep nudging the upper limit up, but we're anticipating some significantly larger artifacts (~1GB in size) that is going to break our steady bumping in size.

We are using Ant 1.10, Ivy 2.4, OpenJSK 1.8.0.141, on a CentOS7 environment.

The issue has been documented with Ivy as IVY-1197 but it has not been fixed in a trunk build, so I want to put the described workaround:

The workaround is to always use ivy with commons-httpclient, commons-codec and commons-logging when the use case will involve uploading large files to sites requiring authentication

I want to add the commons-httpclient, commons-codec, and commons-logging to the Ivy classpath so that Ivy uses these during upload of the artifacts. Unfortunately, I am struggling to make this work. To be completely honest, I am a newcomer to the Java world, with classpaths being a foreign concept; I'm a C++ developer who has volunteered to fix this legacy part of our system.

We invoke our Ivy tasks through Ant. We pull in an ivysettings.xml file, whose relevant structure looks something like:

<ivysettings>
    <classpath file="${build-utils.basedir}/ivy.lib/commons-httpclient-3.1.jar"/>
    <classpath file="${build-utils.basedir}/ivy.lib/commons-codec-1.10.jar"/>
    <classpath file="${build-utils.basedir}/ivy.lib/commons-logging-1.2.jar"/>
</ivysettings>

The ivysettings.xml is pulled in through a build-utils.xml file that is shared among our components:

<project name="build-utils" xmlns:ivy="antlib:org.apache.ivy.ant">
    <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant">
        <classpath>
            <fileset dir="${build-utils.basedir}/ant.lib">
                <include name="ivy*.jar"/>
            </fileset>
        </classpath>
    </taskdef>

    <ivy:settings file="${build-utils.basedir}/ivysettings.xml"/>

    <target name="convert-POM-to-Ivy" > <!-- description="Convert a POM file to an Ivy file"; additionally verifies that we've pulled in Ivy correctly -->
        <ivy:convertpom pomFile="pom.xml" ivyFile="ivyFileOut.xml" />
    </target>
</project>

We also have an ivy.xml for each of our components that is pretty straightforward:

<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
    <info organisation = "${groupId}" 
          module       = "${artifactId}"
          revision     = "${version}}"/>

    <configurations>
        <include file="ivy-configurations.xml"/>
    </configurations>

    <!-- Some giant artifact -->
    <artifact conf="${conf.el7}" type="tar.bz2" e:classifier="${conf.el7}"/>
    <artifact type="pom"/> 

    <dependencies />
</ivy-module>

If I run the ant echoproperties target and grep for 'class.path' I get the following:

[echoproperties] 
java.class.path=/usr/share/java/ant.jar\:/usr/share/java/ant-launcher.jar\:/usr/share/java/jaxp_parser_impl.jar\:/usr/share/java/xml-commons-apis.jar\:/usr/lib/jvm/java/lib/tools.jar\:/usr/share/ant/lib/ant-bootstrap.jar\:/usr/share/ant/lib/ant-launcher.jar\:/usr/share/ant/lib/ant.jar
[echoproperties] 
java.class.path.ivy.instance=/usr/share/java/ant.jar\:/usr/share/java/ant-launcher.jar\:/usr/share/java/jaxp_parser_impl.jar\:/usr/share/java/xml-commons-apis.jar\:/usr/lib/jvm/java/lib/tools.jar\:/usr/share/ant/lib/ant-bootstrap.jar\:/usr/share/ant/lib/ant-launcher.jar\:/usr/share/ant/lib/ant.jar

With this setup, I still have issues with the upload, and I'm not sure if I can verify that I'm using the commons-httpclient.

Could someone provide some tips on how to get a jar into the Ivy classpath? Am I doing this wrong and I need to have it in the Ant classpath? If so, can someone point me in the right direction?

Hydrofoil answered 21/8, 2017 at 14:47 Comment(8)
I am having the same problem. Have you solved it in the meantime?Benedetta
Not in any maintainable fashion. We bumped the JVM max memory up to 1.5GB and did some profilingHydrofoil
That posted too soon. We profiled and figured out a 450MB artifact size is good in that memory. Prior to publishing, we check our artifact size and use Curl to upload it instead of Ivy. We plan on trying to fix it in Ivy later this yearHydrofoil
Thanks for the answer. One issue I have solved with your config. The "classpath" tag does not seem to be working in ivysettings.xml but you can solve this by adding the JARs to the Ivy classpath when you define the Ivy task in your build.xml (the "taskdef" tag accepts a custom-built classpathref)Benedetta
I will do that on Monday when I return to the office. I have been playing with the 2.5 version from their CI system too, with no luck on this specific issue.Hydrofoil
Any updates on this, @Kevin K? We have same issue.Maya
@J.Doe - I finally got an opportunity to revisit this. I appear to have been able to pull the commons-httpclient into the classpath, but I am now blocked because of proxy issues.Hydrofoil
I have the same issue but with the ivy publish mechanism used within sbtShulins

© 2022 - 2024 — McMap. All rights reserved.