Table of Contents
- Table of Contents
- Introduction
- Why Do We Use Packages?
- How Do Java Packages Relate to Maven Projects?
- What Do Maven groupId and artifactId Typically Look Like?
- What Does a Typical Base Java Package Look Like?
- Maven Java Project Folder Structure With Base Packages
- Java Class Package References
- Summary
Introduction
Organize your desktop, lady.
Miles Morales, Spider-Man: Into the Spider-Verse (2018)
Similar to when Miles Morales saw Doc Ock’s cluttered desktop and had trouble finding the information he needed, when we create applications, we don’t want all of our classes in one giant mess of a folder. Otherwise, we won’t be able to easily find what we need.
Why Do We Use Packages?
We would want a package structure for many reasons:
- Separate our code from that of our dependencies,
- More easily tell ownership of code in errors / stack traces,
- Avoid naming collisions with our dependencies,
- Distinguish between different classes with similar names, but different use cases (such as an external, internal, or database representation of a given object in a REST API),
- Group similar code together (such as configuration files, presentation logic or backend API calls),
- Restrict access to certain logic outside of the related classes in that package,
How Do Java Packages Relate to Maven Projects?
As long as you are following Maven coding conventions, then the base package structure will be a combination of Maven groupId and artifactId values.
What Do Maven groupId and artifactId Typically Look Like?
GroupId
If you are using a Maven build for your project, then hopefully that project is following the convention of using the reverse domain name under your control for your Maven groupId. For example, if you controlled the domain:
doesNotExist.com
Then your Maven groupIds may look like:
- com.doesnotexist
- com.doesnotexist.foo
- com.doesnotexist.bar
Note that the characters are all lowercase and that the sections of the domain name are in reversed order. The nesting can continue deeper, just depending upon how your teams/organizations/projects/code bases are structured.
ArtifactId
The Maven artifactId is generally a description of the code / purpose of that Java project.
- shipping
- orders
If a Java project is part of a larger module, it may carry information about that module as a prefix. For example, if we want to break an application called myapp up into smaller Java projects/modules, some of the Java sub-modules might be named like:
- myapp-api (for the externally exposed interfaces / APIs)
- myapp-dal (for DB / data access layer)
Using this approach allows the development team flexibility as to whether they want to group the sub-modules together in the same repo, or split them apart into independent, but related, repos. Doing so avoids the repo-level naming collisions, just like a package will help us avoid class-level naming collisions.
What Does a Typical Base Java Package Look Like?
If following the naming conventions above, then the base Java package for your project is going to look like:
<groupId>.<artifactId>
For example, if your Java project uses:
<groupId>com.doesnotexist</groupId>
<artifactId>shipping</artifactId>
Then your base Java package inside of the shipping project may look like:
com.doesnotexist.shipping
Note that Java conventions expect the package to only use lowercase letters. Any words inside of a portion of the package name are pushed together with no punctuation, such as doesnotexist.
Maven Java Project Folder Structure With Base Packages
Since a Maven project separates runtime (main) and testing (test) code bases, this base package will appear twice in your Maven project. If our project were to use the com.doesnotexist.shipping package as the base package, then the project’s folder structure in the file system will look like:
- src
- main
- java
- com
- doesnotexist
- shipping
- doesnotexist
- com
- java
- test
- java
- com
- doesnotexist
- shipping
- doesnotexist
- com
- java
- main
There are often nested packages inside of this base package for the project, to further break Java files into even smaller groupings.
Java Class Package References
Within Java files, when we reference a package, we do so with the dot (.) notation.
Package Statement
Java files within a package are expected to carry a package statement at the top of the file. If we were to create a Java file within the com.doesnotexist.shipping package, it would carry a statement like:
package com.doesnotexist.shipping;
Class Import Statements
When using a Java class from another package, with only a few exceptions in the underlying Java framework, we need to import it. That will also need to carry the package information to uniquely identify which class we want to import.
import com.doesnotexist.shipping.MyClassName;
Summary
Java packages help uniquely identify which class is being referenced. It is represented with the dot (.) notation inside of Java files, but appears as a folder in the underlying file system for the project. When using a Maven build for a Java project, the base package is often the <groupId>.<artifactId> with lowercase letters, assuming that the groupId is already in a reversed domain name format. This package will appear in both the main and the test source folders for a Maven Java project, too.

Leave a comment