Skip to content
Shop

Maven

Maven is a build tool that automates the building process, including compiling, testing, packaging, and deploying applications. Maven also helps manage project dependencies and provides a structured way to organize projects, making them easier to understand and maintain. An alternative is gradle.

Let's make a small project using maven.

Getting Started

You will need:

  • PostgreSQL - A Relational database
  • JDBI - Lets you connect to a database
  • Docker - Used to run postgres in a container
  • Wildfly - Server alternative to tomcat that comes with JTA out of the box.
  • Flyway DB - Used for data migrations. Liquibase or Bytebase are alternatives.

Folder Structure

This is how a Maven project is structured:

└───maven-project
    ├───pom.xml
    ├───README.txt
    ├───NOTICE.txt
    ├───LICENSE.txt
    └───src
        ├───main
        │   ├───java
        │   ├───resources
        │   ├───filters
        │   └───webapp
        ├───test
        │   ├───java
        │   ├───resources
        │   └───filters
        ├───it
        ├───site
        └───assembly

pom.xml : this file contains dependencies and information about the application. Similar to Ruby on Rails' Gemfile and Node's package.json files.

src/main/java : contains package and source code.

src/test/java : contains test code

Configuration

bash
mvn archetype:generate \
-DgroupId=com.mycompany.app \
-DartifactId=my-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.5 \
-DinteractiveMode=false
yml
version : "3.8"

services:
    db:
        image: postgres:14-alpine
        container_name: user_db
        ports:
            - "5433:5432"
        environment:
            - "POSTGRES_USER=postgres"
            - "POSTGRES_PASSWORD=pgadmin"
            - "POSTGRES_DB=user_db"
java
package com.mycompany.app;

import org.jdbi.v3.core.Handle;
import org.jdbi.v3.core.Jdbi;

public class App{
    public static void main(String[] args) {
        Jdbi jdbi = Jdbi.create("jdbc:postgresql://localhost:5433/user_db","postgres","pgadmin");
        try(Handle handle = jdbi.open()) {
            System.out.println("Running JDBI stuff");
            createUserTables(handle);
            createTaskTables(handle);
        }
        System.out.println("DB Stuff is done!");
    }

    private static void createUserTables(Handle handle){
        handle.execute("CREATE TABLE roles (id SERIAL PRIMARY KEY,name VARCHAR(45))");
        handle.execute(
            "CREATE TABLE user_info" + "(id SERIAL PRIMARY KEY, phone VARCHAR(50), first_name VARCHAR(100), last_name VARCHAR(50), employer VARCHAR(50), university VARCHAR(50), employed_since TIMESTAMP, ip_address VARCHAR(50), bio TEXT, status BOOLEAN, settings json, createdAt TIMESTAMP, updatedAt TIMESTAMP)"
        );
        handle.execute(
            "CREATE TABLE users" + "(id SERIAL PRIMARY KEY, username VARCHAR(50), email VARCHAR(100), password VARCHAR(50), createdAt TIMESTAMP, updatedAt TIMESTAMP, user_info_id INTEGER REFERENCES user_info(id))"
        );
        handle.execute("CREATE TABLE users_roles (
          user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
          role_id INTEGER REFERENCES roles(id),
          CONSTRAINT users_roles_pk PRIMARY KEY(user_id, role_id))"
        );
    }

    private static void createTaskTables(Handle handle){
      handle.execute("CREATE TABLE task_types(id SERIAL PRIMARY KEY, name VARCHAR(50))");
      handle.execute("CREATE TABLE tasks(id SERIAL PRIMARY KEY, user_id integer references users(id), name VARCHAR(50), description text, type_id integer references task_types(id)");
    }
}
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>my-app</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>5.11.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
    </dependency>
    <!-- Optionally: parameterized tests support -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-params</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.7.6</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.jdbi/jdbi3-core -->
    <dependency>
        <groupId>org.jdbi</groupId>
        <artifactId>jdbi3-core</artifactId>
        <version>3.49.4</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.wildfly.core/wildfly-server -->
    <dependency>
        <groupId>org.wildfly.core</groupId>
        <artifactId>wildfly-server</artifactId>
        <version>28.0.1.Final</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.flywaydb/flyway-core -->
    <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
        <version>11.9.1</version>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.4.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.3.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.13.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>3.3.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.4.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>3.1.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>3.1.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.12.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.6.1</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

You may use other versions of these dependencies. I'm using the latest dependencies available at the time of this writing.

bash
docker-compose up

In the Intelij IDE you will need to click on the database icon to add a new postgres database. You can adjust the port,user, password, and database name to get the URL you will use for your database (these are also set in the docker-compose.yml file). The default port for postgres is 5432 but I mapped it to 5433 to avoid any issues that may come up with using the default.

Resources