Skip to content

Latest commit

 

History

History
140 lines (96 loc) · 7 KB

README.md

File metadata and controls

140 lines (96 loc) · 7 KB

Lab 2

Remember the complaints we had at the end of exercise 1d:

  • If we have more than one dependency, how annoying will it be to find download links for all of them?
  • How do we know what versions are available for dependencies?
  • What if our dependency has dependencies? How do we download those?

Build tools such as Maven, Gradle, and Bazel attempt to make it easier to build Java code while helping to handle these problems.

They work slightly differently and have different capabilities and syntax, but the core functionality of getting dependencies and building are mostly the same. For this exercise, we're going to focus on Maven.

Maven Summary

Maven is complicated, so this isn't going to be very short. However, I've attempted to pick only the most useful things to note in this document.

Maven is a software application that builds Java code, but it is also a framework that defines the de-facto standard for how to organize and distribute Java jars for other developers to use.

Project/Modules

Maven breaks up a build into units of work called "Projects". This can be slightly misleading because it is a smaller unit than what most people think of when talking about a "Software Project". A single project can have many sub-projects, in what is known as a multi-project or multi-module project.

When most developers to refer to them, as well as in much of resources available online, plus in the official Maven documentation, the sub-projects are referred to as modules. However, most of the actual output of the Maven commands as well as the Maven command-line arguments refer to them as projects. For the purposes of this training, we may refer to sub-projects as modules, to be consistent with other documentation and common usage. However, if we refer to Maven projects in general, then we mean both projects and sub-projects/modules.

For example, the widely used Log4j logging framework is considered one software project by most people. It exports several modules, such as:

  • log4j-api - The module that declares what the generic API and interfaces looks like.
  • log4j-core - The default logging code that logs to file
  • log4j-jul - An optional module that provides an adapter for the java.util.logging API.
  • log4j-mongodb - An optional module that logs to MongoDB
  • log4j-jmx-gui - An optional dependency that provides a GUI for remotely editing configuration
  • And much much more.

Artifacts

Maven introduces the concept of an Artifact. An artifact is a file generated by a Maven project, along with some metadata. A jar that can be depended on by another project, for example, is probably the most common type of artifact. A Maven project can generate one or more artifacts.

The metadata associated with a Maven artifact include three elements used to identify the artifact. These elements are known as Maven Coordinates.

Maven Coordinates

The maven coordinates are the groupId, artifactId, version.

groupId

The groupId is the identifier of the group that owns the project. This key makes it easier to find all of the artifacts that are published by a group. The groupId follows the same naming rules as Java packages - they're the reverse of a URL that points to a group.

For example, Guava is released under groupId com.google.guava.

Most of IMC's artifacts are com.imc.xxxxx.

artifactId

The artifactId is the identifer of the module within the group. The best practice is to use the actual project name as a prefix, which makes it easier to find the artifacts. This is why the slf4j modules all begin with slf4j-.

version

The version defines the specific version of the project that built this artifact.

Note that Maven defines a set of version specifications, as well as the concept of releases and snapshots, that we'll go into later.

The version can be an arbitrary string, but Maven has rules for determining whether a version is a "newer" version when compared to another version.

Example

An artifact is often described in the format: groupId:artifactId:version. For example, a recent Guava artifact is com.google.guava:guava:31.1-jre

Repository

Maven also introduced (or at least popularized) the concept of an artifact repository in the Java ecosystem. Rather than every project hosting its own JARs somewhere on its website, Maven hosts a centralized repository called "Maven Central" that everyone uploads their artifacts to. Then all you need is to know the group and artifact IDs in order to find and download an Artifact.

At IMC, we host an internal repository for our JARs, as well a mirror of Maven Central.

Maven then handles downloading dependencies from the repositories, as well as deploying your artifacts to the repository.

Directory structure

As you noticed from Lab 1, if you're just building Java files with javac and jar, you can tell them to generate your class files and jars basically wherever, and you just need to correctly specify where everything is when building.

However, as we mentioned, this can be very annoying to work with, if generated class files and jars are just floating about, mixed in with your source code. Additionally, without a standard directory layout, it can be very difficult to navigate code in a new project and understand how everything works.

Maven specifies a Standard Directory Layout that it is highly recommended to follow, for the above reasons.

By a miraculous coincidence, this is almost exactly the same directory structure we used in exercises 1b-1d. Though Maven uses /src/{main,test}/java for source code, in case you have files that are not Java code.

The relevant parts of the directory structure are as follows:

Path Description
src/main/java Application/Library sources
src/main/resources Application/Library resources
src/test/java Test sources
src/test/resources Test resources
target Generated artifacts
target/generated-sources Generated source code
target/generated-test-sources Generated source code used in tests
target/classes Compiled .class files
target/test-classes Compiled test .class files

POM

The Project Object Model, or POM is an XML file (pom.xml) that contains information about the project, the coordinates for the project, configuration and properties, details about how to build the project, the project's dependencies, the plugins and goals that can be executed, build profiles, and so on.

Exercises

  • 2a - Simple Maven Example
  • 2b - Dependencies
  • 2c - Tests and Build Phases