问题
I've created a taskdef in my build.xml that depends on a class that resides in a jar imported by Ivy.
I'd like to understand if it's possible in any way, given the fact that my build breaks before starting because it can't find the class for the taskdef.
This seems a egg and chicken issue, as I can't get the class because I'd have to resolve my dependencies first (which needs the build to be working).
回答1:
Yes, it is possible. However, it means that you must resolve and retrieve the jars before that <taskdef>
task is executed. There are two ways to do this:
Put the
<ivy:resolve>
and a<ivy:retrieve>
task before the<typedef/>
task. All three can be outside of a<target>
. However, in that case, if you run a clean, these three tasks will be executed first before theclean
which means a simpleclean
will take longer, and you have to make sure you don'tclean
anything done during the<ivy:resolve>
and the<ivy:retrieve>
.Put all three in their own target, then make the target which is dependent upon that third party jar dependent upon the target that retrieves the Ivy jars and defines the task. This can be difficult with something like the Ant-Contrib tasks which may be used by almost all of the tasks, but should be easier with things like some sort of packaging task that's used at the very end of your build process.
回答2:
The following is an example that uses ivy to retrieve the groovy task dependencies. As stated by David the trick is to call taskdef after the ivy has resolved the dependencies and created a path reference:
- Harsh Jarring with ivy
The following is more normal example build
- integrating JaCoCo in sonar using Ant
I create configurations to match the build classpaths I require. Pay special attention to the mappings for the "build" configuration. This is how the jars associated with ANT tasks can be kept separate to the jars used for compilation.
Bootstrapping ivy
Reaction to your chicken and egg comment.
I use ivy to manage all build dependencies. The following target ensures that ivy is installed on my build machine.
<available classname="org.apache.ivy.Main" property="ivy.installed"/>
<target name="install-ivy" description="Install ivy" unless="ivy.installed">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.3.0/ivy-2.3.0.jar"/>
<fail message="Ivy has been installed. Run the build again"/>
</target>
回答3:
Just documenting my solution in case it might help anyone. Doing it cleanly as in David's answer is probably the right way to go, but just in case you need the quick solution...
1) Move your taskdef inside the macro you want to call, instead of defining it outside. This will avoid it being evaluated and the build breaking immediatelly.
2) Add your dependencies resolution as a dependency of the task containing the call to the macro.
来源:https://stackoverflow.com/questions/28178395/how-can-i-use-an-ant-taskdef-that-depends-on-lib-imported-by-ivy