You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ivy-user@ant.apache.org by Edwin Castro <0p...@gmx.us> on 2013/08/29 00:50:17 UTC

Publishing modules with configurations

We have a project that produces jars in this form: env.module_name.jar.
These jars are currently copied to the target environment filtered by
environment name and finally renamed so that the final jar on the target
is just module_name.jar. For example, dev.module_name.jar gets deployed
on the dev environment as module_name.jar.

It seemed to me that I could create a configuration for each environment
and then resolve/retrieve by configuration instead of jumping through
the renaming hoops we currently do.

Here's the test configuration I'm trying to use:

<!-- ivysettings.xml -->
<ivysettings>
    <credentials realm="Artifactory Realm"
                 host="localhost"
                 username="admin"
                 passwd="password"/>
    <caches defaultCacheDir="${basedir}/build/ivy_cache"
           
ivyPattern="[organisation]/[module]/[revision]/[type]s/[conf].[artifact].[ext]"
           
artifactPattern="[organisation]/[module]/[revision]/[type]s/[conf].[artifact].[ext]"/>
    <resolvers>
        <url name="default" m2compatible="false">
            <ivy
pattern="http://localhost:8082/artifactory/libs-snapshot-local/[organisation]/[module]/[revision]/[type]s/[conf].[artifact].[ext]"/>
            <artifact
pattern="http://localhost:8082/artifactory/libs-snapshot-local/[organisation]/[module]/[revision]/[type]s/[conf].[artifact].[ext]"/>
        </url>
    </resolvers>
</ivysettings>

<!-- ivy.xml -->
<ivy-module version="2.0">
    <info organisation="org.example"
          module="module_example"/>
    <configurations>
        <conf name="dev"/>
        <conf name="tst"/>
        <conf name="prd"/>
    </configurations>
    <publications>
        <artifact conf="dev"/>
        <artifact conf="tst"/>
        <artifact conf="prd"/>
    </publications>
</ivy-module>

<!-- build.xml -->
<project name="module_example" basedir="."
         xmlns:ivy="antlib:org.apache.ivy.ant">
    <taskdef uri="antlib:org.apache.ivy.ant"
             resource="org/apache/ivy/ant/antlib.xml">
        <classpath>
            <pathelement location="ivy-2.3.0.jar"/>
        </classpath>
    </taskdef>

    <ivy:resolve/>
    <ivy:publish resolver="default"
                 overwrite="true"
                 update="true"
                 forcedeliver="true"
                 pubrevision="0">
        <artifacts pattern="build/lib/[conf].[artifact].[ext]"/>
    </ivy:publish>
</project>

When I run ant I get:

BUILD FAILED
/Users/egcastro/dev/conf_test/build.xml:16: impossible to publish
artifacts for org.example#module_example;working@poseidon:
java.io.IOException: missing artifact
org.example#module_example;0!module_example.jar
    at
org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:219)
    at
org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:166)
    at org.apache.ivy.Ivy.publish(Ivy.java:615)
    at org.apache.ivy.ant.IvyPublish.doExecute(IvyPublish.java:312)
    at org.apache.ivy.ant.IvyTask.execute(IvyTask.java:277)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at
org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at
org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:179)
    at
org.apache.tools.ant.ProjectHelper.configureProject(ProjectHelper.java:93)
    at org.apache.tools.ant.Main.runBuild(Main.java:826)
    at org.apache.tools.ant.Main.startAnt(Main.java:235)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

Clearly I've misconfigured something but I'm not sure what what to look
at next. What am I doing wrong?

--
Edwin G. Castro


Re: Publishing modules with configurations

Posted by Edwin Castro <0p...@gmx.us>.
After a fair amount of searching I found [1] which indicates that using
[conf] in resolver and publish patterns is not currently supported. The
issue does provide an alternative that, while unattractive, it does give
me a way to achieve my goal. The advice was to use extra attributes [2]
to add a platform attribute which would be redundant with some
configuration values (as there could be non-platform configurations).

I used the same technique to create an environment attribute which
allows me to publish environment specific artifacts. Later I can
retrieve the artifacts by configuration providing the environment as the
configuration.

Here is my test configuration:

<?xml version="1.0" encoding="utf-8"?>
<ivysettings>
    <settings defaultResolver="default"/>
    <credentials realm="Artifactory Realm"
                 host="localhost"
                 username="admin"
                 passwd="password"/>
    <caches defaultCacheDir="${basedir}/build/ivy_cache"
           
ivyPattern="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]"
           
artifactPattern="[organisation]/[module]/[revision]/[type]s/([environment].)[artifact].[ext]"/>
    <resolvers>
        <url name="default" m2compatible="false">
            <ivy
pattern="http://localhost:8082/artifactory/libs-snapshot-local/[organisation]/[module]/[revision]/[type]s/[artifact].[ext]"/>
            <artifact
pattern="http://localhost:8082/artifactory/libs-snapshot-local/[organisation]/[module]/[revision]/[type]s/([environment].)[artifact].[ext]"/>
        </url>
    </resolvers>
</ivysettings>

<?xml version="1.0" encoding="utf-8"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
    <info organisation="org.example"
          module="module_example"/>
    <configurations>
        <conf name="dev"/>
        <conf name="tst"/>
        <conf name="prd"/>
    </configurations>
    <publications>
        <artifact conf="dev" e:environment="dev"/>
        <artifact conf="tst" e:environment="tst"/>
        <artifact conf="prd" e:environment="prd"/>
    </publications>
</ivy-module>

<?xml version="1.0"?>
<project name="module_example" basedir="."
         xmlns:ivy="antlib:org.apache.ivy.ant">
    <taskdef uri="antlib:org.apache.ivy.ant"
             resource="org/apache/ivy/ant/antlib.xml">
        <classpath>
            <pathelement location="ivy-2.3.0.jar"/>
        </classpath>
    </taskdef>
    <target name="publish">
        <ivy:resolve/>
        <ivy:publish resolver="default"
                     overwrite="true"
                     update="true"
                     forcedeliver="true"
                     pubrevision="0">
            <artifacts
pattern="build/lib/([environment].)[artifact].[ext]"/>
        </ivy:publish>
    </target>
    <macrodef name="fetch">
        <attribute name="todir"/>
        <attribute name="org"/>
        <attribute name="module"/>
        <attribute name="conf"/>
        <attribute name="rev" default="latest.integration"/>
        <attribute name="transitive" default="true"/>
        <sequential>
            <local name="rev.resolved"/>
            <ivy:configure override="false"/>
            <ivy:findrevision property="rev.resolved"
                              organisation="@{org}"
                              module="@{module}"
                              revision="@{rev}"/>
            <ivy:resolve inline="true"
                         organisation="@{org}"
                         module="@{module}"
                         revision="${rev.resolved}"
                         conf="@{conf}"
                         transitive="@{transitive}"/>
            <ivy:retrieve inline="true"
                          organisation="@{org}"
                          module="@{module}"
                          revision="${rev.resolved}"
                          conf="@{conf}"
                          transitive="@{transitive}"
                          pattern="@{todir}/[artifact].[ext]"/>
        </sequential>
    </macrodef>
    <target name="deploy">
        <fetch org="org.example" module="module_example" conf="dev"
todir="build/dist/dev"/>
        <fetch org="org.example" module="module_example" conf="tst"
todir="build/dist/tst"/>
        <fetch org="org.example" module="module_example" conf="prd"
todir="build/dist/prd"/>
    </target>
</project>

The Ant build script allows me to publish and to deploy (using inline
mode). I was able to validate that the content fetched for each
configuration/environment was indeed the correct content.

Note that the artifact patterns used for the cache, resolver, and
publish use an optional [environment] attribute (it is enclosed in
parens) because I have some modules that are not environment specific
and I need to be able to publish them without any
configurations/environments at all. I validated with a separate example
that the optional [environment] attribute works as expected when used
with a non-environment-specific module.

[1] https://issues.apache.org/jira/browse/IVY-472
[2] http://ant.apache.org/ivy/history/trunk/concept.html#extra

On 8/28/13 3:50 PM, Edwin Castro wrote:
> We have a project that produces jars in this form: env.module_name.jar.
> These jars are currently copied to the target environment filtered by
> environment name and finally renamed so that the final jar on the target
> is just module_name.jar. For example, dev.module_name.jar gets deployed
> on the dev environment as module_name.jar.
>
> It seemed to me that I could create a configuration for each environment
> and then resolve/retrieve by configuration instead of jumping through
> the renaming hoops we currently do.
>
> Here's the test configuration I'm trying to use:
>
> <snipped>
>
> When I run ant I get:
>
> BUILD FAILED
> /Users/egcastro/dev/conf_test/build.xml:16: impossible to publish
> artifacts for org.example#module_example;working@poseidon:
> java.io.IOException: missing artifact
> org.example#module_example;0!module_example.jar
>     at
> org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:219)
>     at
> org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:166)
>     at org.apache.ivy.Ivy.publish(Ivy.java:615)
>     at org.apache.ivy.ant.IvyPublish.doExecute(IvyPublish.java:312)
>     at org.apache.ivy.ant.IvyTask.execute(IvyTask.java:277)
>     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>     at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>     at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>     at java.lang.reflect.Method.invoke(Method.java:597)
>     at
> org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
>     at org.apache.tools.ant.Task.perform(Task.java:348)
>     at org.apache.tools.ant.Target.execute(Target.java:435)
>     at
> org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:179)
>     at
> org.apache.tools.ant.ProjectHelper.configureProject(ProjectHelper.java:93)
>     at org.apache.tools.ant.Main.runBuild(Main.java:826)
>     at org.apache.tools.ant.Main.startAnt(Main.java:235)
>     at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
>     at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
>
> Clearly I've misconfigured something but I'm not sure what what to look
> at next. What am I doing wrong?