Create Maven Project

I don't have opportunities to create a new maven project so often, however, as I had some troubles when creating a new maven project before, I want to write down how it worked for the record. But be sure that I don't know if the procedures and configuration are really appropriate and maybe some parts are not good in practice. Only thing I am sure is it works and my current project is based on that. 

## 1. Create a New Maven Project from a Template
First of all, create a project directory and move to the directory.

```
root@ubuntu:~# mkdir ./maven_test
root@ubuntu:~# cd ./maven_test/
```

Next, you can create a new maven project from a template. 
Here, `maven-archetype-quickstart ` is a template to build a simple maven project. Also, you can define  `DgroupId` and `DartifactId` by yourself.

```
root@ubuntu:~# mvn archetype:generate -DgroupId=com.test \
   -DartifactId=test_maven_example \
   -DarchetypeArtifactId=maven-archetype-quickstart \
   -DinteractiveMode=false 
   
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
*** omitted ***
[INFO] project created from Old (1.x) Archetype in dir: /root/maven_test/test_maven_example
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.246 s
[INFO] Finished at: 2017-09-01T17:01:49-07:00
[INFO] Final Memory: 17M/90M
[INFO] ------------------------------------------------------------------------   
```

Then, check the newly created project tree.

```
root@ubuntu:~/maven_test# tree
.
└── test_maven_example
    ├── pom.xml
    └── src
        ├── main
        │   └── java
        │       └── com
        │           └── test
        │               └── App.java
        └── test
            └── java
                └── com
                    └── test
                        └── AppTest.java
```

## 2. Configure pom.xml: Dependency
Now, your pom.xml file should be like below. In the following steps, you need to configure this pom.xml file to compile your project properly.

```xml
root@ubuntu:~/maven_test/test_maven_example# cat pom.xml 
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test</groupId>
  <artifactId>test_maven_example</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>test_maven_example</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
```

For the test, let's use RabbitMQ sample codes.
- RabbitMQ Sender: https://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/Send.java
- RabbitMQ Reciever: https://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/Recv.java

> **Memo**
> Don't forget add the line `package com.test;` on the top of each rabbitmq code for compiling both java main classes  properly in the project.

In order to use RabbitMQ library, you need to add dependency to your pom.xml file. So insert the lines below in `<dipendencies></dipendencies>` section.

```xml
    <dependency>
      <groupId>com.rabbitmq</groupId>
      <artifactId>amqp-client</artifactId>
      <version>4.2.0</version>
    </dependency>
```

In most case, you can find libraries at maven central repository: https://mvnrepository.com/artifact/com.rabbitmq/amqp-client/4.2.0

## 3. Configure pom.xml: Plugin
For me, this plugin section was the trickiest part and still don't understand the whole thing. Therefore, note that there may be a few wrong parts or bad practices in pom.xml definition.   

In the following steps, some plugins are added into pom.xml. Before that, you need to define the below section in your xml files, then, add plugin's info into the section.

```xml
  <build>
    <plugins>
          *** Here, add plugins ***
    </plugins>    
  </build>    
```

First, you need to add maven compiler plugin and jar plugin.

```xml
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.3.2</version>
      </plugin>
```

Next, add maven dependency plugin. I don't know if this plugin is really necessary but it helps you by automatically downloading dependency libraries into your local system.

```xml
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
              <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>
                ${project.build.directory}/lib
              </outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
```

The next plugin is tricky. In my last project (and this test case as well), there are multiple main classes defined. In this test case, `Send.main` and `Recv.main`. As a result, you need to use `onejar-maven-plugin`. I would like to explain this plugin in the next section.

## 4. Configure pom.xml: onejar-maven-plugin
In order to use onejar-maven-plugin, add the following lines in your pom.xml file.

```xml
  <pluginRepositories>
    <pluginRepository>
      <id>onejar-maven-plugin.googlecode.com</id>
      <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
  </pluginRepositories>
```

Then, add onejar-maven-plugin in `<plugins>` section. In the `<plugin>` section, define `<mainClass>the_name_of_main</mainClass>`. In this case `com.test.Send` and `com.test.Recv` are main classes.

```xml
      <plugin>
        <groupId>com.jolira</groupId>
        <artifactId>onejar-maven-plugin</artifactId>
        <version>1.4.4</version>
        <executions>
          <execution>
            <id>build-first</id>
            <configuration>
              <mainClass>com.test.Send</mainClass>
              <attachToBuild>true</attachToBuild>
              <classifier>onejar</classifier>
              <filename>rabbitmq_sender.jar</filename>
            </configuration>
            <goals>
              <goal>one-jar</goal>
            </goals>
          </execution>
          <execution>
            <id>build-second</id>
            <configuration>
              <mainClass>com.test.Recv</mainClass>
              <attachToBuild>true</attachToBuild>
              <classifier>onejar</classifier>
              <filename>rabbitmq_receiver.jar</filename>
            </configuration>
            <goals>
              <goal>one-jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
```


## 5. Compile Maven Project
Finally, it's time to build your project. To compile a project, execute `mvn package` at your project directory.

```
root@ubuntu:~/maven_test/test_maven_example# mvn package
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Building test_maven_example 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
*** omitted ***
[INFO] 
[INFO] --- onejar-maven-plugin:1.4.4:one-jar (build-first) @ test_maven_example ---
[INFO] Using One-Jar to create a single-file distribution
[INFO] Implementation Version: 1.0-SNAPSHOT
[INFO] Using One-Jar version: 0.97
[INFO] More info on One-Jar: http://one-jar.sourceforge.net/
[INFO] License for One-Jar:  http://one-jar.sourceforge.net/one-jar-license.txt
[INFO] One-Jar file: /root/maven_test/test_maven_example/target/rabbitmq_sender.jar
[INFO] 
[INFO] --- onejar-maven-plugin:1.4.4:one-jar (build-second) @ test_maven_example ---
[INFO] Using One-Jar to create a single-file distribution
[INFO] Implementation Version: 1.0-SNAPSHOT
[INFO] Using One-Jar version: 0.97
[INFO] More info on One-Jar: http://one-jar.sourceforge.net/
[INFO] License for One-Jar:  http://one-jar.sourceforge.net/one-jar-license.txt
[INFO] One-Jar file: /root/maven_test/test_maven_example/target/rabbitmq_receiver.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.616 s
[INFO] Finished at: 2017-09-01T17:57:11-07:00
[INFO] Final Memory: 23M/90M
[INFO] ------------------------------------------------------------------------
```

Now, test newly created RabbitMQ jars. You can find 2 jar files in `target` directory.

```
root@ubuntu:~/maven_test/test_maven_example/target# ls -ls
total 1108
532 -rw-r--r-- 1 root root 541996 Sep  1 18:06 rabbitmq_receiver.jar
532 -rw-r--r-- 1 root root 541995 Sep  1 18:06 rabbitmq_sender.jar
```

Open 2 terminal consoles and start a receiver first.

```
root@ubuntu:~/maven_test/test_maven_example# java -jar ./target/rabbitmq_receiver.jar 
 [*] Waiting for messages. To exit press CTRL+C
```

Run a sender on the other console.

```
root@ubuntu:~/maven_test/test_maven_example/target# java -jar rabbitmq_sender.jar 
 [x] Sent 'Hello World!'
```

Then, the receiver get the message from the sender.

```
root@ubuntu:~/maven_test/test_maven_example# java -jar ./target/rabbitmq_receiver.jar 
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received 'Hello World!'
```

That's all. I hope this post will help me someday.

## 6. Reference: pom.xml
The following is the pom.xml defined in the above procedures. If your pom.xml doesn't work as you expect, please refer this.

```xml
root@ubuntu:~/maven_test/test_maven_example# cat pom.xml 
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test</groupId>
  <artifactId>test_maven_example</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>test_maven_example</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>com.rabbitmq</groupId>
      <artifactId>amqp-client</artifactId>
      <version>4.2.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.3.2</version>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
              <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>
                ${project.build.directory}/lib
              </outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>com.jolira</groupId>
        <artifactId>onejar-maven-plugin</artifactId>
        <version>1.4.4</version>
        <executions>
          <execution>
            <id>build-first</id>
            <configuration>
              <mainClass>com.test.Send</mainClass>
              <attachToBuild>true</attachToBuild>
              <classifier>onejar</classifier>
              <filename>rabbitmq_sender.jar</filename>
            </configuration>
            <goals>
              <goal>one-jar</goal>
            </goals>
          </execution>
          <execution>
            <id>build-second</id>
            <configuration>
              <mainClass>com.test.Recv</mainClass>
              <attachToBuild>true</attachToBuild>
              <classifier>onejar</classifier>
              <filename>rabbitmq_receiver.jar</filename>
            </configuration>
            <goals>
              <goal>one-jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>


    </plugins>    
  </build>    

  <pluginRepositories>
    <pluginRepository>
      <id>onejar-maven-plugin.googlecode.com</id>
      <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
  </pluginRepositories>

</project>
```