Following a build-by-convention approach, Gradle allows for declaratively modeling your problem domain using a powerful and expressive domain-specific language (DSL) implemented in Groovy instead of XML.
Gradle is a JVM native, it allows you to write custom logic
in the language you're most comfortable with, be it Java or Groovy.
In the Java world, a remarkably large number of libraries
and frameworks are used. Dependency management is employed to automatically
download these artifacts from a repository and make them available to your
application.
Having learned from the shortcomings of existing dependency
management solutions, Gradle provides its own implementation.
Not only is it highly configurable, it also strives to be as
compatible as possible with existing dependency management infrastructures
(such as Maven and Ivy).
Gradle's ability to manage dependencies isn't limited to
external libraries. As your project grows in size and complexity, you'll want to
organize the code into modules with clearly defined responsibilities.
Gradle provides powerful support for defining and organizing
multi-project builds, as well as modeling dependencies between projects.
Let's say you want to copy a file to a specific location
when you're building the release version of your project.
To identify the version, you check a string in the metadata
describing your project. If it matches a specific numbering scheme (for example, 1.0-RELEASE), you copy the file
from point A to point B.
If you have to rely on XML, the build language of many
traditional tools, expressing this simple logic becomes fairly difficult.
The build tool's response is to add scripting functionality
through nonstandard extension mechanisms. You end up mixing scripting code with
XML or invoking external scripts from your build logic.
It's easy to imagine
that you'll need to add more and more custom code over time. As a result, you
inevitably introduce accidental complexity, and maintainability goes out the
window.
One of the conventions Maven is very strict about is that
one project needs to produce one artifact, such as a JAR file.
But how do you create two different JAR files from one
source tree without having to change your project structure? Just for this
purpose, you'd have to create two separate projects.
Two tools have dominated building Java projects: Ant and
Maven .
they have one weak point: build logic has to be described in
XML.
XML is great for describing hierarchical data, but falls
short on expressing program flow and conditional logic.
As a build script grows in complexity, maintaining the build
code becomes a nightmare.
Gradle build scripts are declarative, readable, and clearly express their intention.
Writing code in Groovy instead of XML, sprinkled with
Gradle's build-by-convention philosophy,
significantly cuts down the size of a build script and is
far more readable.
Never change a running system, you say? Your team already spent a lot of time on establishing your project's build code infrastructure.
Gradle doesn't force you to fully migrate all of your
existing build logic.
Good integration with other tools like Ant and Maven is at the top of Gradle's priority list.
Build scripts apply the
Gradle DSL and have access to its deep API
Each element in a Gradle
script has a one-to-one representation with a Java class; however, some of the
elements have been sugar-coated with a sprinkle of Groovy syntax.
Having a
"Groovy-fied" version of a class in many cases makes the code more
compact than its Java counterpart and allows for using new language features
such as closures.
Gradle can't know all
the requirements specific to your enterprise build.
By exposing hooks into
lifecycle phases, Gradle allows for monitoring and configuring the build
script's execution behavior.
Let's look at some
examples.
Most common to builds is
the notation of a unit of work that you want to get executed.
Gradle describes this unit
of work as a task.
Part of Gradle standard
DSL is the ability to define tasks very specific to compiling and packaging
Java source code.
It's a language for
building Java projects with its own vocabulary that doesn't need to be relevant
to other contexts.
Another example is the
way you can express dependencies to external libraries, a very common problem
solved by build tools.
Out-of-the-box Gradle
provides you with two configuration blocks for your build script that allow you
to define the dependencies and repositories that you want to retrieve them
from.
If the standard DSL
elements don't fit your needs, you can even introduce your own vocabulary
through Gradle's extension mechanism.
Gradle's DSL can be
extended.
You may want to change the
behavior of an existing task or add your own idioms for describing your
business domain.
Gradle offers you plenty
of options to do so.
XML isn't very expressive.
It makes it hard to define complex custom logic.
Gradle takes a different
approach. Under the hood, Gradle's DSL is written with Groovy providing
syntactic sugar on top of Java.
The result is a readable
and expressive build language. All your scripts are written in Groovy as well.
Being able to use a
programming language to express your build needs is a major plus.
You don't need to be a Groovy expert to get
started. Because Groovy is written on top of Java, you can migrate gradually by
trying out its language features.
You could even write your
custom logic in plain Java — Gradle couldn't care less.
Groovy veterans will
assure you that using Groovy instead of Java will boost your productivity
significantly.
One of Gradle's big
ideas is to give you guidelines and sensible defaults for your projects. Every Java project in Gradle knows exactly where source and test class file are
supposed to live, and how to compile your code, run unit tests, generate
Javadoc reports, and create a distribution of your code.
All of these tasks are fully integrated into the build lifecycle.
In
Gradle, Java projects are build by convention with sensible defaults. Changing
the defaults is easy and achieved through convention properties.
You can compile your Java production source code, run tests, and
assemble a JAR file.
Every Java project starts with a standard directory layout. It
defines where to find production source code, resource files, and test code.
Convention properties are used to change the defaults.
The same concept applies to other project archetypes like Scala,
Groovy, web projects, and many more. Gradle calls this concept build by convention.
The build script developer doesn't need to know how this works
under the hood. Instead, you can concentrate on what needs to be configured.
Gradle provides an
infrastructure to manage the complexity of resolving, retrieving, and storing
dependencies.
Once they're downloaded
and put in your local cache, they're made available to your project. A key
requirement of enterprise builds is reproducibility.
Builds have to produce the
same result on different machines, independent of the contents of your local
cache.
Ivy and Maven in their
current implementation cannot fully guarantee reproducibility.
Why is that? Whenever a
dependency is downloaded and stored in the local cache, it doesn't take into
account the artifact's origin.
In situations where the
repository is changed for a project, the cached dependency is considered
resolved, even though the artifact's content may be slightly different.
At worst, this will cause
a failing build that's extremely hard to debug.
For some companies, a
large project with hundreds of modules is reality.
Building and testing minor
code changes can consume a lot of time. You may know from personal experience
that deleting old classes and resources by running a cleanup task is a natural
reflex.
All too often, you get
burned by your build tool not picking up the changes and their dependencies.
What you need is a tool
that's smart enough to only rebuild the parts of your software that actually
changed.
Gradle supports
incremental builds by specifying task inputs and outputs. It reliably figures
out for you which tasks need to be skipped, built, or partially rebuilt.
The same concept
translates to multimodule projects, called partial builds. Because your build
clearly defines the dependencies between submodules, Gradle takes care of
rebuilding only the necessary parts.
Automated unit,
integration, and functional tests are part of the build process.
It makes sense to separate
short-running types of tests from the ones that require setting up resources or
external dependencies to be run.
Gradle supports parallel
test execution. This feature is fully configurable and ensures that you're
actually taking advantage of your processor's cores.
Gradle is going to support
distributing test execution to multiple machines in a future version. The days
of reading your Twitter feed between long builds are gone.
Developers run builds many times
during development.
That means starting a new Gradle process each time, loading all
its internal dependencies, and running the build logic.
You'll notice that it usually takes a couple of seconds before
your script actually starts to execute.
To improve the startup performance, Gradle can be run in daemon
mode. In practice, the Gradle command forks a daemon process, which not only
executes your build, but also keeps running in the background.
Subsequent build invocations will piggyback on the existing daemon
process to avoid the startup costs. As a result, you'll notice a far snappier
initial build execution.
If you want to share
reusable code among builds and projects, plugins are your best friend.
Representing Gradle's most powerful extension mechanism, plugins give you full
access to Gradle's API and can be written, tested, and distributed like any
other piece of software.
Gradle plays well with
its predecessors Ant, Maven, and Ivy
Gradle
provides deep integration with other build tools and opens the door to
gradually migrate your existing Ant or Maven build.
If you're coming from
Ant, Gradle doesn't force you to migrate your full build infrastructure.
Instead, it allows you to import existing build logic and reuse standard Ant
tasks.
Existing Ant scripts can
be imported into a Gradle build seamlessly and used as you'd use any other
external Gradle script.
Ant targets directly map
to Gradle tasks at runtime. Gradle ships with the Ant libraries and exposes a
helper class to your scripts called AntBuilder, which fully blends into
Gradle's DSL. It still looks and feels like Ant's XML, but without the pointy
brackets.
Gradle builds are 100%
compatible with Maven and Ivy repositories. You can retrieve dependencies and
publish your own artifacts.
Gradle provides a
converter for existing Maven builds that can translate the build logic into a
Gradle build script. With a little configuration, Gradle can upload your
project's artifact for company-wide or public consumption.





0 comments :
Post a Comment