Maven is based around the central concept of a build lifecycle and its made up of phases and these are executed sequentially,
If you execute command mvn verify
, it executes each default lifecycle phase in order (validate, compile, package, etc.), before executing verify.
Most commonly used command is mvn clean package
Each phase is made up of finer goals and these goals are grouped together in a Maven plugin. A plugin may have one or more goals wherein each goal represents a capability of that plugin. A goal not bound to any build phase could be executed outside of the build lifecycle by direct invocation. The order of execution depends on the order in which the goal(s) and the build phase(s) are invoked. For example, consider the command below. The clean and package arguments are build phases, while the dependency:copy-dependencies is a goal (of a plugin).
1mvn clean dependency:copy-dependencies package
If this were to be executed, the clean phase will be executed first, and then the dependency:copy-dependencies goal, before finally executing the package phase.
Eclipse ➔ File ➔ New ➔ Project ➔ Maven Project ➔ Next
Don't check Create a simple project(skip archetype selection) as in the next screen you will have to filter archetypes org.apache.maven
and select maven.archetype.quickstart
➔ Next
Fill GroupId, ArtifactId, Version and Package
Click Finish
It should look like this now
Dependency in terms of maven is a packaged piece of classes that your project depends on. It can be jar, war etc. For example, if you want to be able to write JUnit test, you'll have to use JUnit annotations and classes thus you have to declare that your project depends on JUnit.
Here we are going to add dependencies namely,
Adding those 3 dependencies in pom.xml under <dependencies></dependencies>
tag, you can get these from mvnrepository or by googling maven library-name
1<dependencies>2 <dependency>3 <groupId>junit</groupId>4 <artifactId>junit</artifactId>5 <version>4.11</version>6 <scope>test</scope>7 </dependency>8 9 <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->10 <dependency>11 <groupId>org.apache.logging.log4j</groupId>12 <artifactId>log4j-api</artifactId>13 <version>2.14.1</version>14 </dependency>15 16 <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->17 <dependency>18 <groupId>org.apache.logging.log4j</groupId>19 <artifactId>log4j-core</artifactId>20 <version>2.14.1</version>21 </dependency> 22 </dependencies>
When you do Ctrl+S, the dependencies get downloaded to a new folder(symbolic) Maven Dependencies but its actually downloaded to C:\users\Sushanth\.m2\repository\
Two things you got to do,
src/main
and src/test
- blue box in pic
1package com.bobbydreamer.sllim_maven;2
3import org.apache.logging.log4j.LogManager;4import org.apache.logging.log4j.Logger;5
6/**7 * Hello world!8 */9public class App {10 private static final Logger logger = LogManager.getLogger(App.class);11 public static void main( String[] args )12 {13 System.out.println( "Hello World!" );14 15 logger.trace("We've just greeted the user!");16 logger.debug("We've just greeted the user!");17 logger.info("We've just greeted the user!");18 logger.warn("We've just greeted the user!");19 logger.error("We've just greeted the user!");20 logger.fatal("We've just greeted the user!"); 21 }22}
Create the below log4j configuration file in src/main/resources
folder. Highlighted line mentions where log file will be created during execution.
1<?xml version="1.0" encoding="UTF-8"?>2<Configuration status="INFO">3 <Appenders>4 <Console name="ConsoleAppender" target="SYSTEM_OUT">5 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />6 </Console>7 <File name="FileAppender" fileName="logs/application-${date:yyyyMMdd}.log" immediateFlush="false" append="true">8 <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>9 </File>10 </Appenders>11 <Loggers>12 <Root level="debug">13 <AppenderRef ref="ConsoleAppender" />14 <AppenderRef ref="FileAppender"/>15 </Root>16 </Loggers>17</Configuration>
Plugins perform tasks for a Maven build. These are not packaged in the application. Any task executed by Maven is performed by plugins.
There are two categories of plugins,
According to specific goals specified, a specific lifecyle will be used and a specific set of plugins goals will be executed(eg:- mvn clean, mvn package)
All the plugins mentioned under <build>
, most of which are automatically added by eclipse during maven and build.
1<build>2 <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->3 <plugins>4 <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->5 <plugin>6 <artifactId>maven-clean-plugin</artifactId>7 <version>3.1.0</version>8 </plugin>9 <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->10 <plugin>11 <artifactId>maven-resources-plugin</artifactId>12 <version>3.0.2</version>13 </plugin>14 <plugin>15 <artifactId>maven-compiler-plugin</artifactId>16 <version>3.8.0</version>17 </plugin>18 <plugin>19 <artifactId>maven-surefire-plugin</artifactId>20 <version>2.22.1</version>21 </plugin>22 23 <plugin>24 <artifactId>maven-install-plugin</artifactId>25 <version>2.5.2</version>26 </plugin>27 <plugin>28 <artifactId>maven-deploy-plugin</artifactId>29 <version>2.8.2</version>30 </plugin>31 <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->32 <plugin>33 <artifactId>maven-site-plugin</artifactId>34 <version>3.7.1</version>35 </plugin>36 <plugin>37 <artifactId>maven-project-info-reports-plugin</artifactId>38 <version>3.0.0</version>39 </plugin>40 41 </plugins>42 </pluginManagement>43<!-- ... -->
Below are plugins mentioned outside of <pluginManagement>
as you want them to execute. Plugins we have here are,
Do note in maven-jar-plugin
we mention the mainClass, if we don't do that, we get error like below,
1no main manifest attribute, in slim_maven-0.0.1-SNAPSHOT.jar
My thoughts are maven-jar-plugin and maven-dependency-plugin should be used together and maven-resources-plugin is optional.
1<!-- ... -->2 <plugins>3 <plugin>4 <artifactId>maven-jar-plugin</artifactId>5 <version>3.0.2</version>6 <configuration>7 <archive>8 <manifest>9 <addClasspath>true</addClasspath>10 <mainClass>com.bobbydreamer.slim_maven.App</mainClass>11 <classpathPrefix>dependency-jars/</classpathPrefix> 12 </manifest>13 </archive>14 </configuration> 15 </plugin>16
17 <!-- Copy project dependency -->18 <plugin>19 <groupId>org.apache.maven.plugins</groupId>20 <artifactId>maven-dependency-plugin</artifactId>21 <version>2.5.1</version>22 <executions>23 <execution>24 <id>copy-dependencies</id>25 <phase>package</phase>26 <goals>27 <goal>copy-dependencies</goal>28 </goals>29 <configuration>30 <!-- exclude junit, we need runtime dependency only -->31 <includeScope>runtime</includeScope>32 <outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>33 </configuration>34 </execution>35 </executions>36 </plugin> 37
38 <plugin>39 <artifactId>maven-resources-plugin</artifactId>40 <version>3.0.2</version>41 <executions>42 <execution>43 <id>copy-resources</id>44 <phase>package</phase>45 <goals>46 <goal>copy-resources</goal>47 </goals>48 <configuration>49 <outputDirectory>${project.build.directory}/resources/</outputDirectory>50 <resources>51 <resource>52 <directory>${basedir}</directory> <!-- source directory -->53 <filtering>true</filtering>54 <excludes> <!--Those files will be excluded-->55 <exclude>.project</exclude>56 </excludes>57 58 <includes> <!--Only those files will be included-->59 <include>pom.xml</include>60 </includes> 61 </resource>62 63 <resource>64 <directory>${basedir}/src/main/resources</directory> <!-- source directory -->65 <filtering>true</filtering>66 </resource> 67 </resources>68 </configuration>69 </execution>70 </executions>71 </plugin>72
73 </plugins> 74 </build>
In the below image, i have highlighted few things to note,
dependency-jars
folder contains the log4j jar files logs
folder contains logs written by the applicationresources
folder contains log4j2.xml and pom.xmlslim_maven-0.0.1-SNAPSHOT.jar
is the jar file built by Maven
This is a thin jar solution where all project’s dependencies are copied to a pre-defined folder called dependency-jars
. If we extract slim_maven-0.0.1-SNAPSHOT.jar
using command tar xvf slim_maven-0.0.1-SNAPSHOT.jar
and see the META-INF/MANIFEST.MF
, the dependencies are added in the Class-Path.
1Manifest-Version: 1.02Created-By: Apache Maven 3.8.13Built-By: Sushanth4Build-Jdk: 16.0.15Class-Path: dependency-jars/log4j-api-2.14.1.jar dependency-jars/log4j-c6 ore-2.14.1.jar7Main-Class: com.bobbydreamer.slim_maven.App