Challenges Maven Faces
The speed of the new and old in the software industry is often raspberry, not much time, you will find that once rounds technology has become yesterday's yellow, of course, MAVEN is no exception. While it is basically a fact standard for Java construction, we can also see emerging tools emerge, such as Goovy-based Gradle, and last year hibernate announced that the move from Maven to Gradle was attracting a lot of attention. Before that, I also heard a lot of complaints about MAVEN, including the cumbersome XML, inflexible, steep learning curve and so on. Can the gradle overcome these shortcomings on the basis of inheriting Maven's merits? With this in question, I started reading Gradle's documentation and trying to turn a MAVEN-based project into a Gradle build, which is probably one of those experiences. It is important to note that this article is gradle from a maven perspective, so the perspective will be quite different for ant users.
Gradle First Experience
GRADLE installation is very convenient, download the zip package, unzip to the local directory, set the GRADLE_HOME environment variable and add Gradle_home/bin to the PATH environment variable, the installation is complete. Users can run the GRADLE-V command to verify the installation, and these initial steps are no different from Maven. The current version of Gradle is 1.0-milestone-1, and according to roadmap on its wiki, there will be at least 3 milestone versions before the release of the 1.0 release, and 1.0 will not be released as soon as June. And it's a project that seems less mature, with documents that are embarrassing for many mature projects, including installation guides, basic tutorials, and a comprehensive user guide for nearly 300 pages. This is very friendly to the user, and it also shows that Gradle's developers are very confident about the project, and that writing and maintaining the document is not an easy task, especially for projects where Gradle is likely to change significantly in the future.
Like maven pom.xml
files, each Gradle project needs to have a corresponding build.gradle
file that defines tasks to complete the build, and of course, each task is configurable, the tasks can be relied upon, and the user can configure the default tasks, like this:
Defaulttasks ' taskb ' task Taska << { println "I ' m task A"}task taskb << { println "I ' m task B, and I de Pend on "+ Taska.name}taskb.dependson Taska
After running the command $ gradle-q (the parameter Q lets gradle not print a log other than the error), you can see the following expected output:
I ' m task Ai ' m task B, and I depend on Taska
Isn't this the same as ant? Indeed, the concept and usage of this "task" is similar to Ant and its use. The ant mission is the first citizen of the Gradle World, and Gradle is well integrated with Ant. In addition, because the Grovvy script used by Gradle is more flexible than XML, I still feel that ant users will like Gradle even though I am not an ant user myself.
Dependency management and integration of MAVEN repositories
We know that the concept of dependency management, warehouses, and conventions over configuration is the core of Maven, and the concept itself is not a problem, and has been widely studied and accepted. Did the Gradle realize these good ideas? The answer is yes.
Looking at dependency management first, I have a simple project that relies on some third-party libraries including Springframework, JUnit, Kaptcha, and so on. The original Maven pom configuration is probably like this (space relationship, omitting part of the parent POM configuration):
<properties> <kaptcha.version>2.3</kaptcha.version> </properties> <dependencie s> <dependency> <groupId>com.google.code.kaptcha</groupId> <artifacti D>kaptcha</artifactid> <version>${kaptcha.version}</version> <classifier> jdk15</classifier> </dependency> <dependency> <groupid>org.springframewor k</groupid> <artifactId>spring-core</artifactId> </dependency> <depend Ency> <groupId>org.springframework</groupId> <artifactid>spring-beans</artif actid> </dependency> <dependency> <GROUPID>ORG.SPRINGFRAMEWORK</GROUPID&G T <artifactId>spring-context</artifactId> </dependency> <dependency> <gr Oupid>junit</groupid> <artifactId>junit</artifactId> </dependency> </dependencies >
Then I converted it into a gradle script, and the result was 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 the original 28 lines to 7 lines! That's not the parent POM configuration I omitted. Reliance on GroupID, Artifactid, Version,scope and even classfier, a lot of them. Compared to Maven or ant's XML configuration script, the Grovvy script used by Gradle is too lethal, the heart of beauty, people have it, compared to the seven-year-old woman loose wrinkles, we must all like the girl's tight face, XML is that old woman's wrinkles.
On the dependency management of Gradle at first, I was a little worried about whether it had a mechanism of transitive dependency. After the document reading and the actual experiment, this doubts that Gradle can parse the existing Maven pom or Ivy XML configuration, so as to get transitive dependency information, and introduced into the current project, this is really a smart way. On top of this, it also supports the exclusion of transitive dependencies or the outright closure of transitive dependencies, 2nd of which Maven does not have.
The cornerstone of automated dependency management is the warehouse, and the MAVEN central repository has become an essential resource for Java developers, and since Gradle has a dependency on management, it must also be used in warehouses, which of course includes the MAVEN central repository, like this:
repositories { mavenlocal () mavencentral () mavenrepo URLs: "http://repository.sonatype.org/content/ groups/forge/"}
This code is rarely explained by the use of MAVEN local repositories, central warehouses, and custom address warehouses in Gradle. When I actually build the project, I can see the terminal printing download information, the downloaded file is stored in the USER_HOME/.gradle/cache/
directory for the project to use, this method of implementation and MAVEN is similar, can say gradle not only to maximize the inheritance of maven many ideas, warehouse resources are directly used.
The resources generated by the Gradle project using the MAVEN project are no longer a problem, and need to be considered in turn, will maven users be able to use the resources generated by Gradle? Or, more simply, can the artifacts generated by the Gradle project be published to the MAVEN repository for human use? This is important because if you do not do this, you may lose a large number of users. Fortunately, Gradle again gave a satisfying answer. With Gradle maven Plugin, users can easily upload project artifacts 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"}}
In the process of uploading, gradle can be based on build.gradle
the creation of the corresponding Maven pom file, the user can configure the POM information, such as GroupID and Artifactid here, and such as the dependency configuration of such content, Gradle will automatically help you to convert. Because the direct way to rely on interaction between MAVEN projects is the warehouse, and Gradle can use Maven repositories to publish their own content in a MAVEN format, so technically, even in a MAVEN-based environment, Local use of Gradle is also hardly a problem.
Conventions better than configuration
Like Ant, Gradle gives users enough freedom to define their own tasks, but Gradle also provides a MAVEN-like convention that is implemented through Gradle Java plugin, which is recommended in the documentation. Java plugin defines a project layout that is exactly the same as Maven:
Src/main/java
Src/main/resources
Src/test/java
Src/test/resources
The difference is that using groovy to customize the layout of the project is more convenient:
Sourcesets { Main { java { srcdir ' Src/java ' } Resources { srcdir ' src/resources ' } }}
Gradle Java Plugin also defines the build lifecycle, including the task of compiling the main code, processing resources, compiling test code, performing tests, uploading archives, and so on:
Figure 1. Gradle's Build life cycle
Gradle's build lifecycle is slightly more complex than Maven's fully linear life cycle, but it's also more flexible, such as a jar for packaging, unlike Maven, which relies on the test task of executing tests, similar to what you can see, A final build task is also not dependent on the uploadarchives task. This lifecycle does not limit the user to death, for example, I would like to release the snapshot version to the MAVEN repository each time, and I just want to use the simplest gradle clean build command, which only needs to add a single line of task dependency configuration:
Build.dependson ' Uploadarchives '
Since Gradle is completely based on a flexible task model, many things include overwriting existing tasks, and skipping tasks are very easy to implement. And these things, in Maven's world, are more troublesome to achieve, or maven doesn't want users to do it at all.
Summary
Experience, Gradle give me the biggest feeling is two points. One is simplicity, and the compact script based on groovy is really addictive, and there is nothing unclear about the intent of the presentation. The second is flexible, all kinds of things in Maven difficult to do, in Gradle is a piece of cake, such as modifying the existing build life cycle, a few lines of configuration is complete, the same thing, in Maven you have to write a plug-in, that for a newly-started users, Not a two-day mission is almost impossible.
But even so, Gradle's ability to replace Maven in the future seems to me an unknown. One of the big hurdles is grovvy, where almost all Java developers are familiar with XML, but how many people know about groovy? Learning costs This hurdle is difficult to cross, many people boycott maven because it is not easy to learn, you now let a building tool to learn a new language (even if the language and Java very close), it is almost inevitable that the cold reply. Another problem with Gradle is that it is too flexible, although it supports conventions over configuration, but from this article you also see how easy it is to break the convention. People like to be free, love to customize, feel their own needs are very special, but in fact, from the MAVEN's popularity, almost 95% of the situation you do not need to expand themselves, if you do so, it will only make the building difficult to understand. From this point of view, freedom is a double-edged sword, Gradle gives you enough freedom, the agreement is better than the configuration is only an option, it seems tempting at first, but it may also make it a repeat of the ant mistakes. MAVEN has introduced concepts such as dependency management, warehouses, and conventions over configuration on ant, which is a big step forward, but in my view, Gradle does not introduce new concepts and gives me the feeling that it is an excellent implementation that combines Ant and maven concepts.
If you know groovy and understand that MAVEN's convention is better than configuration, it's good to try Gradle, especially when it's almost seamlessly integrated with existing MAVEN systems, and you can enjoy the simplicity. In fact, when it comes to brevity, perhaps in the near future Maven users can also directly enjoy, Polyglot maven has done a lot of work in this area. This article introduces the rookie of Gradle's build tool entirely based on Maven's perspective, but is limited to the length of the gradle, for example, Gradle also supports multi-module building, which provides a GUI interface, support for Grovvy (as a matter of course) and Scala projects, and so on. Interested readers can take a closer look at their own.
The contract is better than the configuration:
The convention is better than configuration (conventionover config), also known as Convention programming, is a design specification for software designed to reduce the number of decisions that software developers need to make, and to gain simple benefits Without losing flexibility. The essence is that developers only need to specify the parts of the application that are not in conformity with the agreement. For example, if you have a class named sale in your model, the corresponding table in the database is named Sales by default. Only when you deviate from this convention, for example by naming the table "Products_sold", should you write a configuration about that name. If the conventions of the tools you use are consistent with what you expect, you can save the configuration and, conversely, you can configure them to achieve the way you expect them to.
Maven Gradle Differences