当前位置: 首页 > 工具软件 > Apache Toree > 使用案例 >

项目依赖和构建管理工具Apache Ant & Ivy最全面讲解

阮星火
2023-12-01

Apache Ant

项目地址: http://ant.apache.org/

教程地址: https://www.w3cschool.cn/ant/

Apache Ant is a Java library and command-line tool whose mission is to drive processes described in build files as targets and extension points dependent upon each other. The main known usage of Ant is the build of Java applications. Ant supplies a number of built-in tasks allowing to compile, assemble, test and run Java applications. Ant can also be used effectively to build non Java applications, for instance C or C++ applications. More generally, Ant can be used to pilot any type of process which can be described in terms of targets and tasks.

Ant is written in Java. Users of Ant can develop their own "antlibs" containing Ant tasks and types, and are offered a large number of ready-made commercial or open-source "antlibs".

Ant is extremely flexible and does not impose coding conventions or directory layouts to the Java projects which adopt it as a build tool.

Apache Ivy

项目地址: http://ant.apache.org/ivy/

Apache Ivy™ is a popular dependency manager focusing on flexibility and simplicity.

Ivy主要包含2类xml文件,一个是配置文件ivysettings.xml,一个是编译依赖文件build.xml

ivysettings.xml经典实例和讲解

<ivysettings>
	<settings defaultResolver="main"/>
	
	<resolvers>
		<ibiblio name="public" m2compatible="true"/>
	</resolvers>

	<!-- share -->
	<property name="ivy.shared.default.root"             value="${ivy.default.ivy.user.dir}/shared" override="false"/>
	<property name="ivy.shared.default.ivy.pattern"      value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
	<property name="ivy.shared.default.artifact.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
	<resolvers>
		<filesystem name="shared" m2compatible="true">
			<ivy pattern="${ivy.shared.default.root}/${ivy.shared.default.ivy.pattern}" />
			<artifact pattern="${ivy.shared.default.root}/${ivy.shared.default.artifact.pattern}" />
		</filesystem>
	</resolvers>

	<!-- local -->
	<property name="ivy.local.default.root"             value="${user.home}/.m2/repository" override="false"/>
	<property name="ivy.local.default.ivy.pattern" value="[organisation]/[module]/[revision]/[module]-[revision](-[classifier]).pom" override="false"/>
	<property name="ivy.local.default.artifact.pattern" value="[organisation]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]" override="false"/>
	<resolvers>
		<filesystem name="local" m2compatible="true" local="true" changingMatcher="regexp" changingPattern=".*SNAPSHOT.*" checkmodified="true">
			<ivy pattern="${ivy.local.default.root}/${ivy.local.default.ivy.pattern}"/>
			<artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}" />
		</filesystem>
	</resolvers>

	<resolvers>
		<chain name="main" dual="true" changingMatcher="regexp" changingPattern=".*SNAPSHOT.*" checkmodified="true">
   			<resolver ref="local"/> 
			<resolver ref="public"/>
		</chain>
	</resolvers>

</ivysettings>

上面实际上可拆分成多个ivysettings-*.xml文件,将由此展开来讲。

1. Adjusting default settings

Ivy comes bundled with some default settings which makes it pretty simple to use in a typical environment. This tutorial, which is close to a reference document, explains what those default settings are and how they can be adjusted to your needs.

To fully understand the concept of settings and what you can do with them, we suggest reading other tutorials related to settings (like Multiple Resolvers and Dual Resolver) or the Settings Files reference documentation.

Concept

The default settings include 3 types of repositories:

  • local
    A repository which is private to the user.

  • shared
    A repository which is shared between all the members of a team

  • public
    A public repository in which most modules, and especially third party modules, can be found

Note that if you work alone, the distinction between a local and shared repository is not very important, but there are some things you should know to distinguish them.

Now let’s describe each of these repository concepts in more detail. We will describe how they are set up physically later.

Local

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 what is available in others.

For instance, if you have a module declaring a dependency on the module foo with a revision of 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 publishes 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 repository, 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.

Shared

As its name suggest, the shared repository is aimed to be shared among the whole development team. It is a place where you can publish your team’s private modules, and it’s also a place where you can put modules not available in the public repository. You can also put modules here that are simply inaccurate in a public repository (bad or incomplete module descriptors, for instance).

Note that modules can be split across the shared repository and the public one: for example, you can have the module descriptor in the shared repository and the artifacts in the public one.

Public

The public repository is the place where most modules can be found, but which sometimes lack the information you need. It’s usually a repository available through an Internet connection only, even if this is not mandatory.

2. Setting up the repositories

Now that we have seen the objective of each of the three repositories, let’s see how they are set up and how to configure them to fit your needs.

First, several repositories use the same root in your filesystem. Referenced as ${ivy.default.ivy.user.dir}, this is by default the directory .ivy2 in your user home.

Note that several things can be done by setting Ivy variables. To set them without defining your own ivysettings.xml file, you can:

  • set an Ant property before any call to Ivy in your build file if you use Ivy from Ant

  • set an environment variable if you use Ivy from the command line

For example:

<target name="resolve">
  <property name="ivy.default.ivy.user.dir" value="/path/to/ivy/user/dir"/>
  <ivy:resolve/>
</target>

Next we will show you how to override default values for the different kinds of repositories. Note that you can find what the default values are below in the details of the default settings.

Local

By default, the local repository lies in ${ivy.default.ivy.user.dir}/local. This is usually a good place, but you may want to modify it. No problem, you just have to set the ivy.local.default.root Ivy variable to the directory you want to use:

For example:

ivy.local.default.root=/opt/ivy/repository/local

If you already have something you would like to use as your local repository, you may also want to modify the layout of this repository. Once again, two variables are available for that:

  • ivy.local.default.ivy.pattern which gives the pattern to find Ivy module descriptor files

  • ivy.local.default.artifact.pattern which gives the pattern to find the artifacts

For example:

ivy.local.default.root=/opt/ivy/repository/local
ivy.local.default.ivy.pattern=[module]/[revision]/ivy.xml
ivy.local.default.artifact.pattern=[module]/[revision]/[artifact].[ext]

Shared

By default, the shared repository lies in ${ivy.default.ivy.user.dir}/shared. This is fine if you work alone, but the shared repository is supposed to be, mmm, shared! So changing this directory is often required, and it is usually modified to point to a network shared directory. You can use the ivy.shared.default.root variable to specify a different directory. Moreover, you can also configure the layout with variables similar to the ones used for the local repository:

  • ivy.shared.default.ivy.pattern which gives the pattern to find Ivy module descriptor files

  • ivy.shared.default.artifact.pattern which gives the pattern to find the artifacts

For example:

ivy.shared.default.root=/opt/ivy/repository/shared
ivy.shared.default.ivy.pattern=[organisation]/[module]/[revision]/ivy.xml
ivy.shared.default.artifact.pattern=[organisation]/[module]/[revision]/[artifact].[ext]

Public

By default, the public repository is ibiblio in m2 compatible mode (in other words, the Maven 2 public repository).

This repository has the advantage of providing a lot of modules, with metadata for most of them. The quality of metadata is not always perfect, but it’s a very good start to use a tool like Ivy and benefit from the power of transitive dependency management.

Despite its ease of use, we suggest reading the Best practices to have a good understanding of the pros and cons of using a public unmanaged repository before depending on such a repository for your enterprise build system.

 In 1.4 version, Ivy was using ivyrep as the default resolver, if you want to restore this, set ivy.14.compatible=true as an Ant property

3. Going further

OK, so we have seen how to easily change the settings of the three main repositories. But what if my shared repository is on a web server? What if you don’t want to use Maven 2 repository as the public repository? What if …​

No problem, Ivy is very flexible and can be configured with specific settings to match your needs and environment. But before considering writing your own settings from scratch, we suggest reading the following where you will learn how to leverage a part of the default settings and adjust the rest.

But before explaining how, you will need to have a quick overview of how Ivy is configured by default.

By default, Ivy is configured using an ivysettings.xml which is packaged in the Ivy jar. Here is this settings file:

<ivysettings>
  <settings defaultResolver="default"/>
  <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
</ivysettings>

OK, so not much info here, except a lot of inclusions. These inclusions have been done on purpose so that you can easily change only one part of the Ivy settings and easily benefit from the rest. For example, if you want to define your own public resolver, you will just have to configure Ivy with the settings like the following:

<ivysettings>
  <settings defaultResolver="default"/>
  <include url="http://myserver/ivy/myivysettings-public.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
</ivysettings>

Note that only the ivysettings-public.xml inclusion has changed to include a homemade public resolver. Note also that this can be used like that thanks to the fact that ${ivy.default.settings.dir} is a variable which is always set to the place where Ivy’s default settings files are (i.e. packaged in the jar).

To finish this example, you have to write your own Ivy settings file (that you will make available at http://myserver/ivy/myivysettings-public.xml in this example) for defining your own public resolver. For instance, the contents of such a file could be:

<ivysettings>
  <resolvers>
    <filesystem name="public">
      <ivy pattern="/path/to/my/public/rep/[organisation]/[module]/ivy-[revision].xml"/>
      <artifact pattern="/path/to/my/public/rep/[organisation]/[module]/[artifact]-[revision].[ext]"/>
    </filesystem>
  </resolvers>
</ivysettings>

Now the last thing you will need in order to properly take advantage of the default settings is the content of each included Ivy settings file:

ivysettings-public.xml

<ivysettings>
  <resolvers>
    <ibiblio name="public" m2compatible="true"/>
  </resolvers>
</ivysettings>

ivysettings-shared.xml

<ivysettings>
  <property name="ivy.shared.default.root"             value="${ivy.default.ivy.user.dir}/shared" override="false"/>
  <property name="ivy.shared.default.ivy.pattern"      value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
  <property name="ivy.shared.default.artifact.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
  <resolvers>
    <filesystem name="shared">
      <ivy pattern="${ivy.shared.default.root}/${ivy.shared.default.ivy.pattern}"/>
      <artifact pattern="${ivy.shared.default.root}/${ivy.shared.default.artifact.pattern}"/>
    </filesystem>
  </resolvers>
</ivysettings>

ivysettings-local.xml

<ivysettings>
  <property name="ivy.local.default.root"             value="${ivy.default.ivy.user.dir}/local" override="false"/>
  <property name="ivy.local.default.ivy.pattern"      value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
  <property name="ivy.local.default.artifact.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
  <resolvers>
    <filesystem name="local">
      <ivy pattern="${ivy.local.default.root}/${ivy.local.default.ivy.pattern}"/>
      <artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}"/>
    </filesystem>
  </resolvers>
</ivysettings>

ivysettings-main-chain.xml

<ivysettings>
  <resolvers>
    <chain name="main" dual="true">
      <resolver ref="shared"/>
      <resolver ref="public"/>
    </chain>
  </resolvers>
</ivysettings>

ivysettings-default-chain.xml

<ivysettings>
  <resolvers>
    <chain name="default" returnFirst="true">
      <resolver ref="local"/>
      <resolver ref="main"/>
    </chain>
  </resolvers>
</ivysettings>

There you go, you should have enough clues to configure Ivy the way you want. Check the settings documentation to see if what you want to do is possible, and go ahead!

build.xml经典实例和讲解

<ivy-module version="2.0">
    <info organisation="apache" module="hello-ivy"/>
    <dependencies>
        <dependency org="commons-lang" name="commons-lang" rev="2.0"/>
        <dependency org="commons-cli" name="commons-cli" rev="1.0"/>
    </dependencies>
</ivy-module>

dependencies 部分让你定义依赖。这里这个模块依赖两个类库:commons-lang 和 commons-cli。如你所看到的,我们使用 org 和 name 属性来定义我们需要的依赖的组织和模块名。rev 属性用于明确说明你依赖的模块的修订版本。

 类似资料: