Just Enough Maven Part 3
This is the third blog post in a series of how to learn just enough Maven so that you're comfortable working with the JVM.
Just Enough Maven Part 1 - Check this out if you need some extra convincing that investing time to learn maven is worth it.
Just Enough Maven Part 2 - Read this for a refresher on how to do basic tasks without maven.
In this post, I'll try describe just enough about maven so you understand what it is. So, let's dive in!
Code that runs Code
So, what is Maven, really? Maven is a really just a java program that knows how to do these three things:
- find packages of code
- download them
- run them
And that's it! That's basically all that the core of maven code knows how to do!
In Maven terminology, each of the packages of code that it knows how to find, download and run is called an "artifact".
An artifact usually consists of a jar file along with some meta data describing what it contains and who created it.
Maven has a nice way of identifying these artifacts so that they can be found easily.
Artifact Names
One of the essential features of maven is that it has to be able to uniquely identify these artifacts. If you write a web app and I write a web app, maven need to be able to disguish between the two.
In order to do so, Maven uses a notion of an artifact "coordinate". A "coordinate" is just a name (a unique identifier) that consists of the following 3 parts:
- a group id
- an artifact id
- a version number
Group ID
The group id usually refers to the person, company, or organization who created the artifact.
For example, I like to use a group id com.upgradingdave
for any artifacts I create.
Here are a few other examples:
The jetty server artifact uses a group id of org.eclipse.jetty
.
The famous junit
test library has a group id of junit
.
The code that maven uses to compile source code has a group id of org.apache.maven.plugin
(more about this later).
Artifact ID
The artifact id part of the artifact describes what the code actually is (or does).
So for example, I used the artifact id of jdbc
to identify some code that I like to reuse whenever I need to access a database. The group id is com.upgradingdave
and the artifact id is jdbc
. Maven loves xml, so we can describe this artifact like so:
<groupId>com.upgradingdave</groupId>
<artifactId>jdbc</artifactId>
<version>(we'll get to versions in a second)</version>
The jetty server artifact has artifact id of jetty-server
. (clever name, i know)
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>(we'll get to versions in a second)</version>
The junit
library uses an artifact id of junit
.
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>(we'll get to versions in a second)</version>
The compiler that maven uses has an artifact id of maven-compiler-plugin
. Here's the xml for that one:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>(we'll get to this in a second)</version>
<type>(ignore this for now)</type>
Version Numbers
In the world of maven, versions can be whatever you want. You can use 1.0
, or 0.11-2
, or 0.0.1
, or a.b.c.d.e
, or 10.2.0.3.0
, or whatever!
At the time of this writing, the latest version of jetty
is 9.3.7.v20160115
. So the full artifact coordinates looks like this:
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.3.7.v20160115</version>
The latest version of junit is 4.12
and so the artifact coordinates looks like this:
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
I chose to use a version number of 2.0-SNAPSHOT
for my database code, and so the coordinates look like this:
<groupId>com.upgradingdave</groupId>
<artifactId>jdbc</artifactId>
<packaging>jar</packaging>
<version>2.0-SNAPSHOT</version>
Notice the -SNAPSHOT
on my version number? That's a standard version naming convention that most people use with maven. Whenever you see a version with -SNAPSHOT
on the end, you should treat that artifact like something that is in active/heavy development. In other words, the code inside a SNAPSHOT
artifact could (and probably will) change.
SNAPSHOTS
are great when you're developing code. But not so good when you want to deploy things in production.
Plugins
One theme I've picked up on over the years of doing software development is that if you can implement something in terms of itself, it's usually a good sign. And Maven is an great example of this.
The core features of Maven are bundled as artifacts.
For example, the code that maven runs to compile your source code inside your projects is a artifact (which was created by maven). It has a group id of org.apache.maven.plugins
.
In other words, the core functionality that people normally think of when they think of maven (things like compiling code, running tests, and creating jars) is all bundled up as maven artifacts!
There's no real difference between these artifacts and the artifacts that you will use Maven to create from your own source code.
You could say that Maven uses itself to run itself. Maven truly eats it's own dog food.
Artifacts that maven knows how to run are called Plugins.
For example, the maven compiler plugin is itself a maven artifact.
Remember that, fundamentally, maven is really a program that can find, download and run things. The "things" that maven knows how to find, download, and run are called "plugins".
Putting it all together now: Plugins are maven artifacts that instruct Maven how to do things. For example the maven compiler plugin knows how to compile your source code. They are jar files with some metadata. And so each maven plugin can be uniquely identified with a artifact coordinate (a group id, a artifact id, and a version).
Core Maven Plugins
When people talk about maven, really, what they are normally referring to is a handful of "core" maven plugins that maven will automatically run.
Here's a list of core plugins that maven will automatically download and execute the first time you ever run the mvn
command:
- Maven Compiler Plugin: This one can compile your source code.
- Maven Resources Plugin: This knows how to copy properties files, images, css, javascript into your class path and can help with configuration and properties files.
- Maven Surefire Plugin: This is the plugin that knows how to run unit tests and show nice reports
- Maven jar Plugin: This plugin knows how to copy your compiled bytecode into a jar file.
- Maven install Plugin: This knows how to package your code up into an artifact (along with meta data so that it can be used with other maven artifacts).
You can find a more detailed list here.
Summary
The core maven code is conceptually very simple. It looks for some core plugin artifacts (jar files with metadata), downloads them and runs them. That's essentially all that maven is from 10,000 foot level.
How does it know where to find these artifacts? And how does it know which order to run them in?
Those are great questions, and it all has to do with the Project Object Model, which I'll describe in the next post.