Before starting with dependency configuration, let's discuss how to publish packaged software in Java. You package and publish either in .jar
or .war
or .ear
file formats to a repository. The goal is to share these assets within the teams in an organization or with open source developers. Consider a scenario where you are publishing a utility project (messageutil.jar
) to a repository. Although the publication process mostly depends on an organization's policy, the common practice is, all the assets that you plan to publish should be versioned and stored in a central repository, so that all other teams can share it. This versioning helps to track different versions of libraries. With versioned libraries, you can also revert to old versions in case of any functionality issues. Whenever you publish any asset to the repositories, always make sure it is versioned. To know more about versioning look at this link: http://semver.org/.
Other than internal or external JAR files, a project can also depend on:
We saw an example of the Gradle API and the Groovy version used in the previous chapters when we developed custom tasks and plugins. Project dependency will be discussed in Chapter 6, Working with Gradle. In this chapter, we will discuss other module dependencies on global and local repositories, and file dependencies on the local system.
We will start dependency management with a simple example. Consider you are building a project, SampleProject
, which depends on a third-party library log4j-1.2.16.jar
.
To build the project, you need this jar file at compile time. Gradle provides a very easy and systematic way to define dependencies of the project using the dependencies closure in the following way:
dependencies { <configuration name> <dependencies> }
Gradle groups dependencies to different configurations. If you apply Java Plugin to a project, it provides six different configurations, which are listed in the following table:
Names |
Details |
---|---|
|
The dependencies mentioned here are added to the classpath during compilation of the source code ( |
|
The dependencies mentioned here are required at runtime during execution of the source code ( |
|
The dependencies mentioned here are added to the classpath during compilation of the test code ( |
|
The dependencies mentioned here are required at runtime during execution of the test code ( |
|
This is used to tell the build file about the artifacts generated by the project |
|
This contains the artifacts and dependencies used at runtime |
To define the preceding dependencies, you need to pass the following details to Gradle's dependency manager:
The dependencies can be defined in one of the following ways:
compile group: 'log4j', name: 'log4j', version: '1.2.16'
compile 'log4j:log4j:1.2.16','junit:junit:4.10'
compile ('log4j:log4j:1.2.16') ) { // extra configurations }
compile (group:'log4j',name:'log4j',version:'1.2.16') { // extra configurations }
To configure project dependencies, you need to mention all the libraries in the dependencies
closure. So the build file will look like this:
apply plugin: 'java' repositories { mavenCentral() } dependencies { compile group: 'log4j', name: 'log4j', version: '1.2.16' }
Do not get confused with the repositories
closure we have added in the example. We will discuss about this in the next section.
The job is half done when we say dependencies are identified and defined. How Gradle will know where to get these dependencies from? Here comes the concept of repositories
. Gradle provides the repositories
closure to define repositories from where dependencies can be downloaded. You can configure any number of repositories and also any type of repositories in your project. For dependencies listed in the dependencies
closure, Gradle searches repositories in sequential order. If it finds a library or a dependency in one of the repositories (if multiple repositories are configured), it skips searching other repositories. In the next section, we will learn how to configure different repositories.
You can use the following methods to configure repositories. Gradle allows you to use more than one configuration in a build file.
mavenCentral()
to the repositories
closure as mentioned here:repositories { mavenCentral() }
jCenter
repository by using jcenter()
inside the repositories.repositories { jcenter() }
mavenLocal()
in the repositories
closure. By default, Maven's local cache path would be <USER_HOME>/.m2/repository
. If you want to change it to another location, you can configure the path in settings.xml
under <USER_HOME>/.m2
or <USER_HOME>/.m2/conf
. Having this configuration makes it easy to build a "SNAPSHOT" version of another project locally and include that version.repositories { mavenLocal() }
repositories { ivy { url "http://<ivyrepositorylocation>" layout "ivy" // valid values are maven, gradle, ivy } }
You can also define the custom layout for your Ivy repository. There is not an equivalent ivyLocal()
because Ivy does not allow local publishing of artifacts such as Maven.
Repositories
location in the following format:repositories { maven { url "http://private.repository/path" credentials { username 'guest' password '123123' } } ivy { // For Ivy repositories url "http://private.repository/path" } }
If your private repository needs authentication, you can provide the credentials as well. You can add the credentials to ~/.gradle/gradle.properties
as well and use it from there, because it is not a good practice to add credentials directly to the build file.
For Maven's format repositories, there is always metadata attached with the jar as pom.xml
. There might be a scenario in which POM file and JAR file are located at two different locations. In such cases, you can mention both locations as follows:
repositories { maven { url "http://private.repository/pompath" artifactUrls "http://private.repository/jardir" } }
mavenLocal()
location). This situation could arise when some other projects or teams are creating jars at a different location and publishing those jars to a central location. You want your project to refer to these local directories only for dependency. This can be achieved by using the following code:repositories { flatDir { dirs '/localfile/dir1', '/localfile/dir2' } }
This is not the recommended approach as this will result in inconsistencies. The recommended approach is to always use the private or global repository.
3.16.137.117