I've got a main project where module A depends on a a .jar file created by the build for module B. While I'm in development, I'm modifying B regularly, then building B to create the library, then building A to use these changes.
Is there a way to point module A's ivy file to the jar file my module B build creates? Given I'm iterating multiple times, I don't want to check module B's jar into ivy over and over. It's also annoying to have to copy the jar into module A's build directory structure after every module B build.
Actually, for me it's worse, as I have about 4 modules in something of a dependency tree (A->B->CD). If it were just A and B I'd probably just live with it, but I'm getting sick of copying jar files around after the submodule builds and thought if there was a way to override the ivy file dependency line to look locally then that'd make life a lot simpler.
Pointing the Ivy dependency at your locally built module isn't the way to solve this. Instead when you build module B publish it to your local Ivy repository. When you resolve your dependencies for module A it will pull down module B from your local repository.
From the Ivy docs on the local repository:
The local repository is particularly
useful when you want to do something
without being disturbed by anything
else happening in the environment.
This means that whenever ivy is able
to locate a module in this repository
it will be used, no matter of what is
available in others.
For instance, if you have a module
declaring a dependency on the module
foo in revision latest.integration,
then if a revision of foo is found in
the local repository, it will be used,
even if a more recent revision is
available in other repositories.
This may be disturbing for some of
you, but imagine you have to implement
a new feature on a project, and in
order to achieve that you need to
modify two modules: you add a new
method in module foo and exploit this
new method in module bar. Then if you
publish the module foo to your local
repository, you will be sure to get it
in your bar module, even if someone
else publish a new revision of foo in
the shared repository (this revision
not having the new method you are
currently adding).
But be careful, when you have finished
your development and publish it on the
shared you will have to clean your
local repository to benefit from new
versions published in the shared
repository.
Note also that modules found in the
local repository must be complete,
i.e. they must provide both a module
descriptor and the published
artifacts.
The Using Ivy in multiple projects environment documentation has an example publish-local Ant task that you might find useful.
Related
I have three projects: A, B, C
and build.xml in ant that should compile them.
C depends on B that depends on A
So far I had all dependencies were in eclipse and I had a build.xml in ant with:
<eclipse.incrementalBuild project="A" kind="incremental"/>
<eclipse.incrementalBuild project="B" kind="incremental"/>
<eclipse.incrementalBuild project="C" kind="incremental"/>
Now, I have ivy.xml files - for example:
<ivy>
<ivy module="B"/>
<dependencies>
<dependency name="A">
</dependencies>
</ivy>
Now, all works great when I publish A, B, C in this order to a repository (I use sonatype nexus repository), since the repository is also used for resolving, so the process is:
1. resolve dependencies for A - no such
2. upload currently in workspace A as jar to repository
3. resolve dependencies for B - A is resolved as dependency
4. upload currently in workspace B as jar to repository
5. resolve dependenceies for C - B and A are resolved as dependencies
6. upload currently in workspace C as jar to repository
The way I see it publishing to nexus is for delivering the product
What I need is a simple build.xml to just compile my project - and so I don't want to publish all the time new version.
Instead I am looking for I way to use ivy to
1. compile A
2. and then compile B using already compiled A
2. and then compile C using already compiled B,A
I thought about using a local repository in the file system, in which stages 1-6 are made - producing local jars to be used - however, this is a bit cumbersome since:
1. my resolve will have to contain two resolvers - the file system preceding the nexus repo - which means that on a real publish, I will have to remember to delete the local jars
2. Sounds a bit too much work for something I believe may have a simpler solution.
In essence, I want to mimic eclipse's IVY plugin that can resolve dependencies in workspace and compile projects using other projects in the workspace - but I am looking for the best, most recommended way of doing this.
Thank you
You stated:
I have three projects: A, B, C and build.xml in ant that should
compile them.
That suggests that your project is in fact one large monolithic build.
Instead you need to emulate how Maven does its work. Each module needs to have its own build file and an ivy file that lists that module's dependencies. Each module publishes its own jar artifact into a repository (local or remote) making it accessible to other modules using ivy resolve operations.
The following examples give links to the ivy documentation on multi-module builds using ivy.
ivy simple shared repository
Ivy: Using dynamic revisions
It's not easy to break up a big project, I hope this helps.
My company runs an internal Ivy repository over a NAS. There we put all the dependencies for our projects. A few days ago, the repo has been rebuilt completely from scratch, using a combination of Java code and calls to Ant task ivy-install.
I personally designed and performed the rebuilding, but faced an important issue. While I used mvrepository.com as reference for importing common open source projects (e.g. Spring, Hibernate), often packages were available in not-widely-known Maven repositories I had to Google for.
Every time (e.g. with hibernate-spatial) I found a package belonging to an "unknown" Maven source I had to some manual work by registering the remote source into ivy-settings.xml and manually run again ivy-install.
This made me think: does it even exist a tool that graphically (e.g. web interface) helps Ivy administrator search and download to local repository artifacts from multiple remote sources (registered by user)? Like if I type the <dependency> tag, or the org, name and rev attributes and it lists available sources. When I need to download a package to local repo, simply click and it gets published.
I have a Maven 3 multi-module project (~50 modules) which is stored in Git. Multiple developers are working on this code and building it, and we also have automated build machines that run cold builds on every push.
Most individual changelogs alter code in a fairly small number of modules, so it's a waste of time to rebuild the entire source tree with every change. However, I still want the final result of running the parent project build to be the same as if it had built the entire codebase. And I don't want to start manually versioning modules, as this would become a nightmare of criss-crossing version updates.
What I would like to do is add a plugin which intercepts some step in build or install, and takes a hash of the module contents (ideally pulled from Git), then looks in a shared binary repository for an artifact stored under that hash. If one is found, it uses that artifact and doesn't even execute the full build. If it finds nothing in the cache it performs the build as normal, then stores its artifact in the cache. It would also be good to rebuild any modules which have dependencies (direct or transient) which themselves had a cache miss.
Is there anything out there which does anything like this already? If not, what would be the cleanest way to go about adding it to Maven? It seems like plugins might be able to accomplish it, but for a couple pieces I'm having trouble finding the right way to attach to Maven. Specifically:
How can you intercept the "install" goal to check the cache, and only invoke the module's 'native' install goal on a cache miss?
How should a plugin pass state from one module to another regarding which cache misses have occurred in order to force rebuilds of dependencies with changes?
I'm also open to completely different ways to achieve the same end result (fewer redundant builds) although the more drastic the solution the less value it has for me in the near term.
I have previously implemented a more complicated solution with artifact version manipulation and deployment to private Maven repository. However, I think this will fit your needs better and is somewhat more simple:
Split your build into multiple builds (e.g., with a single build per module using maven -pl argument).
Setup parent-child relationships between these builds. (Bamboo even has additional support for figuring out Maven dependencies, but I'm not sure how it works.)
Configure Maven settings.xml to use a different local repository location - specify a new directory inside your build working directory. See docs: https://maven.apache.org/guides/mini/guide-configuring-maven.html
Use mvn install goal to ensure newly built artifacts are added to local repository
Use Bamboo artifact sharing to expose built artifacts from local repository - you should probably filter this to include only the package(s) you're interested in
Set dependent builds to download all artifacts from parent builds and put them into proper subdirectory of local repository (which is customized to be in working directory)
This should even work for feature branch builds thanks to the way Bamboo handles parent-child relations for branch builds.
Note that this implies that Maven will redownload all other dependencies, so you should use a proxy private Maven repository on local network, such as Artifactory or Nexus.
If you want, I can also describe the more complicated scenario I've already implemented that involves modifying artifact versions and deploying to private Maven repository.
The Jenkins plugin allows you to manage/minimize dependent builds
whenever a SNAPSHOT dependency is built (determined by Maven)
after other projects are built (manually via Jenkins jobs)
And if you do a 'mvn deploy' to save the build into your corporate Maven repo then you don't have to worry about dependencies when builds run on slave Jenkins machines. The result is that no module is ever built unless it or one of its dependencies has changed.
Hopefully you can apply these principles to a solution with Bamboo.
I am working on a module (let's say A, version 1) that is available in my maven global repository. I have now modified the code inside this module and bumped the version up to version 2.
Now, the code for this module has not been committed and the global repository doesn't now about this new version. However, I have built the project and version 2 is available in my local .m2 folders.
I am now working on a new module (let's say B) that depends on module A, version 2. maven is not picking up this dependency on module A. And my code is not linking to classes in module A.
Any help would be much appreciated.
EDIT: I have performed a clean install of module A, and I can see the classes in the local repository.
Best,
Pulkit
Well, if you are using an IDE, which I presume you do (you are using maven), you could try to update the project configuration and update the dependencies. Also make sure you refer to the correct versions of your modules in your pom.xml file(s) . This is all presuming you have performed a clean install of your 'A version 2', of course. Good luck!
I am upgrading a project from Ant to Gradle. The project uses a aqapi13.jar(this is oracle aq jar. This is needed as the project reads from an oracle-queue and writes to an activemq queue.)
The ant project contains the jar aqapi13.jar in the libs folder. But iam trying to get this dependency from a repository instead of having it in the libs folder.
However, iam not able to find a repository which contains this jar. All the repositories that I have seen contain aqapi13-9i.jar, but not aqapi13.jar.
Anyone knows the difference between aqapi13.jar and aqapi13-9i.jar and how to get the needed aqapi13.jar from a repository.
Advance Thanks
Some dependencies are never found in public repositories because of the license they have.
One way to use this dependencies is to create your own repository (e.g. artifactory, nexus, archiva). Then you are free to put in every artifact you want (as long as you do not publish the repository). This repository can also serve as a mirror for maven.
Another way could be to mark this dependency as system scope.