Maven practice (6)-gradle: The Future of building tools?

Source: Internet
Author: User
Tags maven central
Challenges faced by Maven

The speed of the New and Old alternation in the software industry is often confusing. You don't need to spend much time, and you will find that the technology that once turned red and purple has become yesterday's yellow flower. Of course, Maven is no exception. Although it is basically a fact standard built in Java, we can also see that emerging tools are emerging, such as gradle Based on goovy, last year, Hibernate announced the migration from Maven to gradle, which attracted a lot of attention. Before that, I also heard a lot of Maven complaints, including the tedious, inflexible, and steep learning curves of XML. Can gradle overcome these shortcomings Based on the advantages of Maven? With this question, I started to read the gradle document and tried to convert a Maven-based project to be built using gradle. This article will introduce this experience. It should be noted that this article is based entirely on the maven perspective, so for ant users, the perspective will certainly be quite different.

Gradle initial experience

It is very convenient to install gradle. Download the zip package, decompress it to the local directory, set the gradle_home environment variable, and add gradle_home/bin to the path environment variable. The installation is complete. You can runGradle-VCommand to verify the installation. these initial steps are no different from those of Maven. Gradle's current version is 1.0-Milestone-1. According to roadmap on its wiki, there will be at least three milestone versions before the official version 1.0 is released, and 1.0 of the release date will not be earlier than January. It is such a seemingly immature project that has a document that makes many mature projects feel ashamed, it includes the installation guide, basic tutorials, and a comprehensive user guide on nearly 300 pages. This is very friendly for users. It also shows that gradle developers are very confident in this project. It is not easy to write and maintain documents, this is especially true for projects that may change significantly in the future like gradle.

Similar to Maven'spom.xmlFile, each gradle project must have a correspondingbuild.gradleFile, which defines some tasks to complete the build. Of course, each task can be configured and dependencies between tasks can also be configured. You can also configure the default task, as shown in the following figure:

defaultTasks 'taskB'  task taskA << {     println "i'm task A" }  task taskB << {     println "i'm task B, and I depend on " + taskA.name }  taskB.dependsOn taskA 

Run commands$ Gradle-QAfter (the Q Parameter prevents gradle from printing logs other than errors), you can see the following expected output:

i'm task A i'm task B, and I depend on taskA 

Isn't that the same as Ant? Indeed, the concept and usage of this "task" are similar to ant. The ant task is the first citizen in the gradle world. gradle has integrated ant very well. In addition, because the grovvy script used by gradle is more flexible than XML, even if I am not an ant user, I still think ant users will like gradle.

Manage dependencies and integrate Maven Repositories

We know that dependency management, warehousing, and conventions over configuration are the core content of Maven. Regardless of whether the implementation is optimal, the concept itself is no problem and has been widely learned and accepted. Does gradle implement these excellent concepts? The answer is yes.

First, let's look at dependency management. I have a simple project dependent on some third-party libraries, including springframework, JUnit, and kaptcha. The original Maven pom configuration is like this (the length relationship, omitted part of the parent pom configuration ):

    <properties>         <kaptcha.version>2.3</kaptcha.version>     </properties>      <dependencies>         <dependency>             <groupId>com.google.code.kaptcha</groupId>             <artifactId>kaptcha</artifactId>             <version>${kaptcha.version}</version>             <classifier>jdk15</classifier>         </dependency>         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-core</artifactId>         </dependency>         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-beans</artifactId>         </dependency>         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-context</artifactId>         </dependency>         <dependency>             <groupId>junit</groupId>             <artifactId>junit</artifactId>         </dependency>     </dependencies>

Then I converted it into a gradle script, and the results were amazing:

dependencies {     compile('org.springframework:spring-core:2.5.6')     compile('org.springframework:spring-beans:2.5.6')     compile('org.springframework:spring-context:2.5.6')     compile('com.google.code.kaptcha:kaptcha:2.3:jdk15')     testCompile('junit:junit:4.7') }

Note that the configuration is reduced from 28 to 7! This is not a part of my parent pom configuration. There are many dependent groupid, artifactid, version, scope, and even classfier. Compared with Maven or ant's xml configuration script, gradle's grovvy script is too lethal and has a crush on all people. Compared with the loose wrinkles of old women in the past seven years, everyone must like a girl's tight face, XML is the wrinkles of the old lady.

I was a little worried about the dependency management of gradle at first, that is, whether it has a mechanism of transmission dependency? After reading the document and conducting practical experiments, this problem was dispelled. gradle can parse the xml configuration of the existing Maven pom or Ivy to obtain the information of the passed dependency and introduce it to the current project, this is really a smart approach. On this basis, it also supports excluding the pass-through dependency or simply disabling the pass-through dependency. The second point is a feature not available in Maven.

The cornerstone of automated dependency management is the repository. Maven's central repository has become an indispensable resource for Java developers. Since gradle has dependency management, it must also be used, this also includes the maven central repository, as shown in the following figure:

repositories {     mavenLocal()     mavenCentral()     mavenRepo urls: "http://repository.sonatype.org/content/groups/forge/" }

This code hardly needs to be explained, that is, to configure and use the maven local repository, central repository, and custom address repository in gradle. When I build a project, I can see the download information printed on the terminal. The downloaded file is stored inUSER_HOME/.gradle/cache/Directory is used by the project. This implementation method is similar to maven. It can be said that gradle not only inherits many Maven concepts to the maximum extent, but also uses repository resources directly.

It is no longer a problem for the gradle project to use resources generated by Maven projects. Next, we need to consider whether Maven users can use resources generated by gradle? Or, simply, can the components generated by the gradle project be published to the maven repository for use? This is very important, because if you cannot do this, you may lose a large number of users. Fortunately, gradle once again gave a satisfactory answer. With gradle's MAVEN plugin, you can easily upload project components to the maven Repository:

apply plugin: 'maven' ... uploadArchives {     repositories.mavenDeployer {         repository(url: "http://localhost:8088/nexus/content/repositories/snapshots/") {             authentication(userName: "admin", password: "admin123")             pom.groupId = "com.juvenxu"             pom.artifactId = "account-captcha"         }     } }

During the upload process, gradle canbuild.gradleGenerate the corresponding Maven pom file. You can configure the POM information on your own. For example, the groupid and artifactid here. gradle will automatically convert content such as dependency configuration. Because the direct way of dependency interaction between Maven projects is the repository, gradle can both use the maven repository and release its own content to the repository in Maven format. Therefore, technically speaking, even in a Maven-based environment, using gradle is almost no problem.

Convention is better than Configuration

Like Ant, gradle provides users with sufficient freedom to define their own tasks. However, gradle also provides Maven-like conventions. Due to the configuration method, it is implemented through gradle's Java Plugin, from the document, gradle recommends this method. Java Plugin defines a completely consistent project layout with Maven:

  • Src/main/Java

  • Src/main/Resources

  • Src/test/Java

  • Src/test/Resources

The difference is that it is more convenient to use groovy to customize the project layout:

sourceSets {     main {         java {             srcDir 'src/java'         }         resources {             srcDir 'src/resources'         }     } }

Gradle Java Plugin also defines the build lifecycle, including compiling master code, processing resources, compiling test code, executing tests, uploading archives, and other tasks:

Figure 1. gradle build Lifecycle

Compared with the completely linear life cycle of Maven, the lifecycle of gradle construction is slightly complicated, but it is more flexible. For example, the jar task is used for packaging, it does not depend on the test task for testing as Maven does. Similarly, we can see that a final build task does not depend on the uploadarchives task. This life cycle does not limit the number of users. For example, I want to release the snapshot version to the maven repository every build, and I just want to use the simplest$ Gradle clean buildCommand, you only need to add a line of task dependency Configuration:

build.dependsOn 'uploadArchives'

Because gradle is completely based on a flexible task model, many tasks, including overwriting existing tasks, are easy to skip. In the maven world, implementation of these things is quite troublesome, or Maven does not want users to do this.

Summary

After some experience, gradle gives me two things. The first is conciseness. Groovy-based compact scripts are incredibly appealing and there is no ambiguity in expressing intentions. The second is flexibility. There are a variety of things that are difficult to start with in maven. In gradle, it is a piece of cake, such as modifying the existing build lifecycle, and several lines of configuration are completed. The same thing is done, in Maven, you must compile a plug-in. For an entry-level user, it is almost impossible to complete tasks within a day or two.

Even so, it is still unknown to me whether gradle can replace Maven in the future. One of its major obstacles is grovvy. Almost all Java developers are familiar with XML, but how many others are familiar with groovy? The learning cost is difficult to overcome. Many people resist Maven because it is not easy to learn, now, you want a build tool to learn a new language (even if this language is very similar to Java), it is almost inevitable to get a cold response. Another problem with gradle is that it is too flexible. Although it supports better conventions than configurations, you can see from this article how easy it is to break the conventions. People like freedom, love customization, and feel that their needs are very special. In fact, from the popularity of Maven, you do not need to expand more than 95% of the situations, if you do this, it will only make the build hard to understand. From this point of view, freedom is a double-edged sword. gradle gives you enough freedom. It is only an option to set a rule that is better than configuration. This seems attractive at the beginning, but it may make it the same as ant. Maven has introduced dependency management, repositories, and conventions over configuration on the basis of ant, which is a great improvement. However, in my opinion, gradle has not introduced any new concepts, it seems to me that it is an excellent implementation that combines ant and Maven concepts.

If you know groovy and understand Maven's conventions better than configuration, it would be nice to try gradle, especially if it can be seamlessly integrated with the existing Maven system, and you can also enjoy the great pleasure of simplicity. Actually speaking of conciseness, Maven users may be able to directly enjoy it in the near future. polyglot Maven has done a lot of work in this regard. This article introduces the rookie gradle building tool from the maven perspective. However, due to space limitations, it cannot go deep into all aspects of gradle. For example, gradle also supports multi-module building, it provides a GUI to support grovvy and Scala projects. Interested readers can learn more on their own.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.