This is an old revision of the document!
Anybody who wanted to to start with Apache Maven probably at least skimmed through the official guide and I wasn't an exception. While reading, I started to think, what the hell… it was supposed to be simple. Instead of it, I had to enter this crazy command into shell just to create a basic empty project:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
Oh God, whyyyy!? So let's fiddle with it…
What really happens when you run aforementioned command is that it creates directory structure, pom.xml (Maven project file, so called Project Object Model) and a Hello world app (and its test):
fiisch@mothership:~> cd /tmp/ fiisch@mothership:/tmp> mkdir mvn-test fiisch@mothership:/tmp> cd mvn-test/ fiisch@mothership:/tmp/mvn-test> mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app \ > -DarchetypeArtifactId=maven-archetype-quickstart \ > -DinteractiveMode=false [INFO] Scanning for projects... ... [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.808 s [INFO] Finished at: 2016-08-12T11:21:32+02:00 [INFO] Final Memory: 14M/343M fiisch@mothership:/tmp/mvn-test> find . ./my-app ./my-app/src ./my-app/src/main ./my-app/src/main/java ./my-app/src/main/java/com ./my-app/src/main/java/com/mycompany ./my-app/src/main/java/com/mycompany/app ./my-app/src/main/java/com/mycompany/app/App.java ./my-app/src/test ./my-app/src/test/java ./my-app/src/test/java/com ./my-app/src/test/java/com/mycompany ./my-app/src/test/java/com/mycompany/app ./my-app/src/test/java/com/mycompany/app/AppTest.java ./my-app/pom.xml
Also there is a generated pom.xml file which you have to edit if you take it seriously. Now let me explain the project-generation command:
Now we will try to create empty project by hand. First, create directory for your project and then a structure the archetype originally created for you:
fiisch@mothership:/tmp> mkdir mvn-test-hand
fiisch@mothership:/tmp> cd mvn-test-hand/
fiisch@mothership:/tmp/mvn-test-hand>
# now we are starting to create project
# create equivalent of -DartifactId=my-app
fiisch@mothership:/tmp/mvn-test-hand> mkdir my-app
# create directory structure for -DgroupId=com.mycompany.app
fiisch@mothership:/tmp/mvn-test-hand> cd my-app/
fiisch@mothership:/tmp/mvn-test-hand/my-app> mkdir -pv src/{main,test}/java/com/mycompany/app
mkdir: created directory ‘src’
mkdir: created directory ‘src/main’
mkdir: created directory ‘src/main/java’
mkdir: created directory ‘src/main/java/com’
mkdir: created directory ‘src/main/java/com/mycompany’
mkdir: created directory ‘src/main/java/com/mycompany/app’
mkdir: created directory ‘src/test’
mkdir: created directory ‘src/test/java’
mkdir: created directory ‘src/test/java/com’
mkdir: created directory ‘src/test/java/com/mycompany’
mkdir: created directory ‘src/test/java/com/mycompany/app’
# create minimal pom.xml in the my-app folder
fiisch@mothership:/tmp/mvn-test-hand/my-app> 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/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>
</project>
# now try to compile empty project
fiisch@mothership:/tmp/mvn-test-hand/my-app> mvn compile
[INFO] Scanning for projects...
...
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.395 s
[INFO] Finished at: 2016-08-12T12:05:05+02:00
[INFO] Final Memory: 9M/481M
And that's it. We managed to setup empty project without using the archetype.
Last thing I want to explain in this post is generating empty (or any other) project using interactive mode and also reasons why probably nobody uses it. Let's start with simple generate without any arguments:
fiisch@mothership:/tmp> mkdir mvn-test-interactive fiisch@mothership:/tmp> cd mvn-test-interactive/ fiisch@mothership:/tmp/mvn-test-interactive> mvn archetype:generate [INFO] Scanning for projects... ... very long output here ... 1639: remote -> us.fatehi:schemacrawler-archetype-plugin-command (-) 1640: remote -> us.fatehi:schemacrawler-archetype-plugin-dbconnector (-) 1641: remote -> us.fatehi:schemacrawler-archetype-plugin-lint (-) Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 821:
So… we have neat 1641 choices of archetypeArtifactId. Not what we really want and it gets even worse. Suppose we want to create Spring based project, we get 141 choices, narrowing our search to “springframework” we end up with 28 choices. Yeah, ok. And which one to proceed with?
fiisch@mothership:/tmp/mvn-test-interactive> mvn archetype:generate < /dev/null | grep -ci "spring" 141 fiisch@mothership:/tmp/mvn-test-interactive> mvn archetype:generate < /dev/null | grep -ci "springframework" 28 fiisch@mothership:/tmp/mvn-test-interactive> mvn archetype:generate < /dev/null | grep -ci "jboss" 68 fiisch@mothership:/tmp/mvn-test-interactive> mvn archetype:generate < /dev/null | grep -ci "mule" 14 fiisch@mothership:/tmp/mvn-test-interactive> mvn archetype:generate < /dev/null | grep -ci "camel" 102
Maven is built around the idea that most projects have the same structure. In theory, this is very good thinking about standardization of project structure. Problem is that anyone can write such template and publish it for everyone else to see. In practice, we end up with almost 1700 templates to choose from. For a newbie, this is something really off putting.
Sad truth is, that there is no good way of choosing particular archetypeArtifactId unless someone explicitly tells you which one to use. When you are creating new project, it is better to do it by hand and write yourself a pom.xml from scratch.
But okay, let's give interactive mode a shot:
fiisch@mothership:/tmp> mkdir mvn-test-interactive fiisch@mothership:/tmp> cd mvn-test-interactive/ fiisch@mothership:/tmp/mvn-test-interactive> mvn archetype:generate [INFO] Scanning for projects... ... very long output here ... 1639: remote -> us.fatehi:schemacrawler-archetype-plugin-command (-) 1640: remote -> us.fatehi:schemacrawler-archetype-plugin-dbconnector (-) 1641: remote -> us.fatehi:schemacrawler-archetype-plugin-lint (-) Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 821: # 821 is the quickstart archetype we previously specified as argument, hit ENTER Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 1: 1.0-alpha-1 2: 1.0-alpha-2 3: 1.0-alpha-3 4: 1.0-alpha-4 5: 1.0 6: 1.1 Choose a number: 6: # What the hell am I choosing? yeah, version of archetype. # No idea about differences, hit ENTER and use latest version. Define value for property 'groupId': : my-app Define value for property 'artifactId': : com.mycompany.app Define value for property 'version': 1.0-SNAPSHOT: : Define value for property 'package': my-app: : com.mycompany.app.mypackage Confirm properties configuration: groupId: my-app artifactId: com.mycompany.app version: 1.0-SNAPSHOT package: com.mycompany.app.mypackage Y: : y ... [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 03:22 min [INFO] Finished at: 2016-08-12T16:03:06+02:00 [INFO] Final Memory: 17M/477M
Well, without much explanation, I had to fill in the properties I previously specified on the command line. Interesting is, that Maven asked me about the package property.