Maven

Intro

As much as I enjoy Java, there are some aspects of plain out-of-the-box Java that I've always found confusing and frustrating. Creating a JAR, managing packages and dependencies, and remembering to set the class path quickly become unwieldy when dealing with anything more than a couple of source files. (And even then I almost never remember to implement those details appropriately enough to successfully compile and run on the first attempt.) Happily, we have Maven. Maven is a build tool developed and maintained by Apache, who describe it as a plugin execution framework. This means that while it's been designed to take care of all those pesky administrative details that can drive you up a wall, it's also highly extensible, so it's capable of much more than basic build tasks. Its integration with JUnit via the core surefire plugin (included by default) is especially welcome, allowing seamless incorporation of unit testing into the build process.

Installing Maven

Go here. If you're on windows, download the Binary zip archive, and if you're on Linux download the Binary tar.gz archive. Then follow the installation instructions, which amount to:

  1. Extract the archive to a directory of your choosing.
  2. Modify your PATH environment variable to include <your>/<path>/<to>/apache-maven-3.6.3/bin

Alternatively, if you're on Windows and use chocolatey you can make this even easier with choco install maven

Starting a New Project

Note: The first time you do this it might take a second; there's a whole bunch of stuff Maven needs to download (archetypes, dependencies, etc.) that weren't included in the initial download and installation process.

On The Command Line

Here's the command:

mvn archetype:generate -DgroupId='com.organization.your.app'
-DartifactId=learning-app
-DarchetypeArtifactId=maven-archetype-quickstart
-DarchetypeVersion='1.4'
-DinteractiveMode=false

Important: If you're doing this on Powershell, make sure to include the quotation marks around any value that contains a dot (.). The command will not complete without them.

In Visual Studio Code

Proceed through the following. VSC will prompt you the whole way. See below to understand the values it asks for.

  1. On the left hand menu bar, there's a submenu titled JAVA PROJECTS. Expand and click the button labeled "Create new Java project." At the top of the screen a selection of project types will be displayed. Select "Maven create from archetype," and then choose the archetype appropriate for your project. Maven will then prompt you in the command line for some information that it needs to create your unique project:
  2. Define value for property 'groupId':
  3. Define value for property 'artifactId':
  4. Define value for property 'version' 1.0-SNAPSHOT:
  5. Define value for property 'package' <groupId>:

What All That Means

Whichever option you choose, you should understand the options involved:

Maven has now created a directory structure for your project, as specified by the parameters you supplied to the above arguments. You'll see it's parent folder, which bears the name of your artifactId, if you ls in your current directory. If you're using VSC you can view this structure in the "Explorer" pane on the left. This is what it looks like:

There are a couple thing to notice here. First, the root directory of your new project contains a file named "pom.xml". pom stands for Project Object Model. It is the fundamental configuration file for Maven projects, and its existence is what makes a Maven project a Maven project. It contains the information that you entered above, and it contains information about any and all dependencies for your project. All Maven commands (mvn [options] <arguments>) must be run from your project's root directory

The second thing to notice is the src folder that Maven created. Or more specifically, notice the way it forks. Maven creates two branches, one for your projects source files, and one for unit testing. At the end of both of those trees are sample programs that can be altered and adjusted to meet the needs of your project. So there you have it. Modify the source code in src/main/java/com/organization/your/app/App.java, and modify the unit tests in src/test/java/com/organization/your/app/AppTest.java.

Installing a Local Third-Party JAR (Or Other Artifact) as a Dependency

Helpful Links:

Guide to installing 3rd party JARs

Installing an artifact to a specific local repository path

Stack Overflow - How to add local jar files to a Maven project?

For whatever reason, I had the darndest time figuring out how to include a local third-party JAR in my project, and I couldn't seem to find any clear, easy solutions that didn't leave something important out. Now it's very possible that I just missed something basic, and if the method provided below seems needlessly convoluted, or if it's clearly spelled out in the documentation somewhere, please do let me know! In the meantime, here's what eventually worked for me.

Step 1:

Here's the command:

mvn install:install-file -Dfile=<path-to-artifact-jar>
-DgroupId=<your.groupId>
-DartifactId=<artifactId>
-Dversion=<version number>
-Dpackaging=jar
-DlocalRepositoryPath=<path/to/.m2/repository>

The last argument, -DlocalRepositoryPath, is the path to the .m2 repository where Maven keeps copies of relevant jars for a project, and it's the option that I had the most trouble figuring out based on the documentation. Now following the command above should place a copy of the local jar, along with the appropriate directory structure, in your local repository. But it doesn't (at least for me) update the project's pom.xml file to reflect that dependency, which means that any attempt to compile will still fail.

Step 2:

Open your project's pom.xml file and enter the following lines:

<dependency>
<groupId>your.groupId.example</groupId>
<artifactId>name_of_jar</artifactId>
<version>version_number</version>
</dependency>

Now your local jar should be copied to the local repository and your Maven project should know where to look for it when executing a buildcycle.

A Note About Unit Testing With Maven

Inclusions and Exclusions of Tests

Can modify the testing file as necessary, but do NOT include a main method. It won't work. The testing file belongs in the 'test' directory. Surefire won't look for it in the 'main' directory. Note that there are naming conventions: **/Test*.java, **/*Test.java, **/*Tests.java, **/*TestCase.java

Resource folder:

Apache Maven Resources Plugin

Resources Plugin - FAQ

The resource folder resides in /src/main, and it's used for all non-source code files, such as xml, images, etc. f you look through the output of the 'mvn package' command, you will see that Maven looks for a project resources folder. This typically resides in /src/main/resources, but the process followed above with the quickstart archetype does not create it. Create manually and add resources as necessary.