知识库 知识库
首页
  • Hyperskill - Java

    • Java basic
    • Java OOP
    • 应知
    • 扩展
    • IO & Stream
    • Error & Exception
    • Algorithm & Data structure
    • Design pattern
    • Web
    • Spring boot
  • 练习题

    • 选择题 & 填空题
    • 代码题
  • Frank - Java与生活 (OOP)

    • 参考资料
    • Java基础
    • OOP上半部分
    • OOP下半部分
  • Frank - Java API进阶

    • Base API
    • Unit Test and main function
  • 学习笔记
  • 学习笔记

    • 数据库
  • Frank - MySQL删库跑路

    • 安装、连接、配置
    • 基本操作——数据库
    • 基本操作——表
    • 基本操作——数据
    • 数据类型
    • 列属性完整性
    • 数据库设计思维
    • 单表查询
    • 多表查询
  • 学习笔记

    • 其它
  • Frank - Linux现代方法

    • 必知
    • 命令
    • 技巧
  • 技术文档
  • Git
  • GitHub技巧
  • 前端
  • Khan Academy - 语法
  • Monthly
  • 阅读
  • Others
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 标签
  • 归档
GitHub (opens new window)

Jim FuckPPT

Java小学生
首页
  • Hyperskill - Java

    • Java basic
    • Java OOP
    • 应知
    • 扩展
    • IO & Stream
    • Error & Exception
    • Algorithm & Data structure
    • Design pattern
    • Web
    • Spring boot
  • 练习题

    • 选择题 & 填空题
    • 代码题
  • Frank - Java与生活 (OOP)

    • 参考资料
    • Java基础
    • OOP上半部分
    • OOP下半部分
  • Frank - Java API进阶

    • Base API
    • Unit Test and main function
  • 学习笔记
  • 学习笔记

    • 数据库
  • Frank - MySQL删库跑路

    • 安装、连接、配置
    • 基本操作——数据库
    • 基本操作——表
    • 基本操作——数据
    • 数据类型
    • 列属性完整性
    • 数据库设计思维
    • 单表查询
    • 多表查询
  • 学习笔记

    • 其它
  • Frank - Linux现代方法

    • 必知
    • 命令
    • 技巧
  • 技术文档
  • Git
  • GitHub技巧
  • 前端
  • Khan Academy - 语法
  • Monthly
  • 阅读
  • Others
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 标签
  • 归档
GitHub (opens new window)
  • Hyperskill - Java

    • Java basic

    • Java OOP

    • 应知

    • 扩展

      • Theory:Units of information
      • Theory:IDE
      • Theory:IDEA
      • Theory:Build tools
      • Theory:Operating systems
      • Theory:Gradle basics
      • Theory:Basic project with Gradle
      • Theory:Building apps using Gradle
      • Theory:Dependency management
        • How to add dependencies?
        • Repository definition
        • Dependencies definition
        • Colorful world
        • Conclusion
      • Theory:Formatted output
      • Theory:Libraries
      • Theory:Frameworks
      • Theory:Modules
      • Theory:Introduction to software architecture
      • Theory:Class Diagrams
      • Theory:Text blocks
      • Theory:YAML
      • Theory:XML
      • Theory:JSON
    • IO & Stream

    • Error & Exception

    • Algorithm & Data structure

    • Design pattern

    • Web

    • Spring boot

  • 练习题

  • Frank - Java与生活

  • Frank - Java API进阶

  • 学习笔记

  • Java
  • Hyperskill - Java
  • 扩展
Jim
2022-07-03
目录

Theory:Dependency management

Small programs that you write when learning a language may not use any external libraries at all. When you need some functionality, you will find it in the standard library or create it yourself. However, it is quite difficult to develop a real application that doesn't use any libraries because they save tons of your time and provide solutions tested by millions of people around the world.

In this topic, we will learn how to add external libraries to our applications using Gradle.

# How to add dependencies?

In Gradle terminology, all external libraries are called dependencies. As a rule, they are packaged in JAR files. Gradle can automatically download them and add them to the project. It saves a lot of time and solves possible conflicts between versions of libraries.

Where do we get these dependencies and how do we add them to a project? To use a class, you need to have it locally, and your JVM must know that you have it. If you want to do it manually, you need to find and download such jars on your own and add them to the classpath of your project. Sounds quite tedious, right?

Fortunately, dependency management is one of the key features of Gradle. You don’t even need a plugin for it. To add an external library to a project, you need to do exactly two steps:

  1. Define a repository where to search for dependencies.
  2. Define a dependency that you want to include in your project.

Now, let's consider these steps in more detail.

# Repository definition

Repositories are just places where libraries are stored. Any project can use zero or more repositories.

There are different possible formats of repositories:

  • a Maven compatible repository (e.g.: Maven Central (opens new window), JCenter (opens new window), Google (opens new window))
  • an Ivy compatible repository;
  • local (flat) directories.

It's possible to host repositories like Maven or JCenter locally in your organization, but that is out of the scope of this tutorial. We will only consider public online versions of them.

Gradle has four aliases that you can use when adding Maven compatible repositories to the project.

  • mavenCentral(): fetches dependencies from the Maven Central Repository (opens new window).
  • jcenter(): fetches dependencies from the Bintray’s JCenter Maven repository (opens new window).
  • mavenLocal(): fetches dependencies from the local Maven repository.
  • google(): fetches dependencies from Google Maven repository (opens new window).

Defining a repository in Gradle is a piece of cake. Just add this to your build.gradle file:

repositories {
    mavenCentral()
    jcenter()
}
1
2
3
4

Also, you can just download the jars you need and place them into some directory on your computer, commonly in the libs folder of your project. This comes in handy when the jars you need are not available in public repositories.

repositories {
    flatDir {
        dirs 'lib'
    }
}
1
2
3
4
5

The following picture demonstrates how to add dependencies from different repositories using Gradle.

img

Now let's find out how to download dependencies from these repositories.

# Dependencies definition

To add a new dependency to your project, first, you need to identify it by the following attributes: group, name and version. All these attributes are required when you use Maven compatible repositories. If you use other repositories, some attributes might be optional. For example, a flat repository only needs a name and a version.

There are several ways to find these attributes. Some library maintainers are nice enough to list them on their website or git repository. Also, you can just search for them in your preferred repository.

img

Maven Central search example

All the dependencies are grouped into a named set of dependencies called configurations. Each of them has different characteristics and determines the following points:

  • the availability of dependencies on building steps;
  • the need to include dependencies in the final build artifact;
  • the visibility of dependencies for programmers who use your project as a library.

The 'java' and 'kotlin' plugins add a number of these configurations to your project. There are four of them:

  • implementation configuration means that the dependency is available at compile-time and it can't be exposed to people who use your compiled code as an external library in their own projects. This configuration is considered the default one.
  • compileOnly configuration is used to define dependencies that should only be available at compile-time, but you do not need them at runtime.
  • runtimeOnly is used to define dependencies that you need only during runtime, and not at compile time.
  • api configuration is similar to implementation, but will be exposed to the programmers who use your compiled code as a library in their projects.

In an existing project, you may see compile and runtime configurations as well, but they are deprecated now. Consider using implementation and runtimeOnly instead.

There also exist the same configurations only with the test prefix (e.g. testImplementation). Since tests are compiled and run separately and are not included in the final JAR (as well as their dependencies), they have their own set of dependencies. It helps decrease the size of a JAR, which is especially useful in Android development.

Please, note, that at this moment, you do not need to understand everything about configurations. Usually, the type of dependency configuration is already specified when you copy dependency info from an online repository or a website. If you would like to read more about configurations, see the official Gradle docs (opens new window).

When we decided on what dependencies we want and settled on their configurations, we are ready to add them to our build.gradle, which is as simple as adding repositories.

dependencies {
    // This dependency is used by the application.
    implementation group: 'com.google.guava', name: 'guava', version: '28.0-jre'

    // Use JUnit test framework only for testing
    testImplementation 'junit:junit:4.12'

    // It is only needed to compile the application
    compileOnly 'org.projectlombok:lombok:1.18.4'
}
1
2
3
4
5
6
7
8
9
10

Here, we add these three dependencies as an example:

  • Guava library, provides useful collections and utils for a project;
  • JUnit, used for testing purposes;
  • Lombok, modifies bytecode at compile time and isn't necessary anymore after compilation.

As you may have noticed, there are two ways of declaring dependencies: the one where we explicitly declare group, name, and version, and the one where we just list them separated by the colon. Both are perfectly fine and are up to your preferences. Note that Groovy syntax is flexible and you can use either single or double quotes for the dependency string and optionally enclose it in parentheses. All the following declarations are equally valid:

// 1
implementation("com.google.guava:guava:28.0-jre")

// 2
implementation "com.google.guava:guava:28.0-jre"

// 3
implementation 'com.google.guava:guava:28.0-jre'

// 4
def guava_version = "28.0-jre"
implementation "com.google.guava:guava:$guava_version"
1
2
3
4
5
6
7
8
9
10
11
12

After adding dependencies in the build.gradle file, you can use the libraries in your source code, but do not forget to import them. Gradle will automatically download the libraries from repositories when building the project.

# Colorful world

As an example of using external libraries, we take a look at a program that prints colored text messages.

  1. In the dependencies section of the build.gradle file we need to include JCDP library:
implementation group: 'com.diogonunes', name: 'JCDP', version: '2.0.3.1'
1

\2. And then import and use it inside the source code. Here are Java and Kotlin examples.

Java:

package org.hyperskill.gradleapp;

import com.diogonunes.jcdp.color.ColoredPrinter;
import com.diogonunes.jcdp.color.api.Ansi;

public class App {
    public static void main(String[] args) {
        ColoredPrinter printer = new ColoredPrinter
                .Builder(1, false).build();

        printer.print("Hello, colorful world!",
                Ansi.Attribute.BOLD, Ansi.FColor.BLUE, Ansi.BColor.WHITE);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Kotlin:

package com.hyperskill.gradleapp

import com.diogonunes.jcdp.color.ColoredPrinter
import com.diogonunes.jcdp.color.api.Ansi

fun main(args: Array<String>) {
    val printer = ColoredPrinter.Builder(1, false).build()

    printer.print("Hello, colorful world!",
            Ansi.Attribute.BOLD, Ansi.FColor.BLUE, Ansi.BColor.WHITE)
}
1
2
3
4
5
6
7
8
9
10
11

Both programs print the same colored message: Hello, colorful world!

# Conclusion

You've learned only the basics of dependency management, but this is enough to write programs with external libraries. As you may have noticed, Gradle is a very flexible tool for managing dependencies. It allows you to choose repositories where to download them and also to configure when to use dependencies: during compile-time, during runtime, or when testing, and so on. As an example, we examined a program that prints colored messages using an external library.

编辑 (opens new window)
#Gradle#Build tools#Tool Guide
上次更新: 2022/09/26, 16:55:15
Theory:Building apps using Gradle
Theory:Formatted output

← Theory:Building apps using Gradle Theory:Formatted output→

最近更新
01
《挪威的森林》
04-14
02
青钢影
04-14
03
Processing strings
02-18
更多文章>
Theme by Vdoing | Copyright © 2022-2023 Jim Frank | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式