0
votes

How could ivy support publishing artifacts of projects in multiple phases?

Suppose we had project A and B. A depends on B's models while B depends on A's models. (Usually the circular dependence isn't that direct, but the example serves. Our projects are relatively loosely coupled, sending messages to each other via the models) The models themselves don't depend on anything, so I can easy build those artifacts. However, while I can build moduleA-models.jar, I cannot build moduleA.jar until I get moduleB-models.jar. (And.. of course, visa-versa with module B.)

So I'm thinking a 2 phase publishing effort. I'm doing exactly that. I have an ant target that builds the models and then publishes the 'model' ivy conf. I run through all the projects building/publishing the models. I then go back and start building the rest of the project code. Note that 'going back and building the rest of the project code' implies a new publishing call... this time with all the artifacts, not just the model artifact.

However ivy is.. mildly unhappy with it. For example, it sometimes sees module A's 'published' ivy.xml with just the model jar, and then might find out later there's an updated ivy.xml for module A that has model and non-model jars in it. By and large I can get around that with 'changing="true"' dependency flag.

However, lately even that just fails for me and ivy is trying to build projects out of order and thus failing. Also I occasionally get into trouble about a missing version of a project (due again to the fact that it's seeing two different versions of a project's ivy.xml within the same build cycle).

So what's the recommended approach here? Separate ivy projects (in the same file structure) perhaps?

1
What do you mean by "models"? Are you asking about ivy support for multi-module builds? - Mark O'Connor
Well.. simple beans. In my case, protocol buffers. - ticktock
Your question is still confusing.... I suspect you want to publish more than one type of artifact? Ivy supports this using configurations. So the "default" configuration could be used to combine the "module11.jar" and "module1-model.jar" artifacts. A second "model" configuration would contain only the second artifact. Such a setup in the module's ivy files would enable clients to download either both artifacts or a just the model artifact as dependencies. Confusing? A solid example of the problem you're trying to solve would really help. - Mark O'Connor
You're right.. I did a poor job of framing the question. Editing the quest now. (not enough space in comments!) - ticktock

1 Answers

1
votes

Why don't you structure your project to have a common module that builds and publishes the jars containing the message model classes?

├── build.xml
├── common
│   ├── build.xml
│   ├── ivy.xml
│   └── src
|       ..
├── module1
│   ├── build.xml
│   ├── ivy.xml
│   └── src
|       ..
└── module2
    ├── build.xml
    ├── ivy.xml
    └── src
        ..

Each module can then have a dependency on these common dependencies:

<dependency org="myproj.common" name="module1-model" rev="1.0"/>

The root build file can use the buildlist task to determine the module build order based on the ivy file dependencies.

<target name="determine-build-order">
    <ivy:buildlist reference="build-path">
        <fileset dir="." includes="modules/**/build.xml"/>
    </ivy:buildlist>
</target>

<target name="build" depends="determine-build-order">
    <subant target="build" buildpathref="build-path" />
</target>