Time for the first lesson. This one is extremely simple and serves only to present the basic concepts. Without further ado, let's get to work.

What you are going to learn

  1. How lessons work.
  2. How to run Maven.
  3. How to write your first Java program.
  4. The programming process: test, code, test, code, until all tests pass.
  5. How to print things on the console using Java.

Step 1 - start the VM

Remember that you have to be in the JavaClasses directory when you bring the VM up.

Go to the "clean" state and then start the VM. If you use Linux as the host OS, going to the "clean" state already brings the VM up. So running vagrant up may be not necessary.

user@host:~$ cd JavaClasses
user@host:~/JavaClasses$ vagrant snapshot go clean
user@host:~/JavaClasses$ vagrant up

Step 2 - log in to the VM

user@host:~/JavaClasses$ vagrant ssh
vagrant@vagrant-ubuntu-trusty-32:~$

From now on we will work only in the VM.

Step 3 - Obtain lesson files

During the setup preparation we installed a script called 02j-get-lesson. Running this script with the lesson number you will automatically download the lesson to the virtual machine:

vagrant@vagrant-ubuntu-trusty-32:~$ 02j-get-lesson 1

Step 4 - Go to the lesson directory

Then go to the lesson directory using the cd command. You can also invoke the tree command to list the structure under lesson1:

vagrant@vagrant-ubuntu-trusty-32:~$ cd lesson-1
vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$ tree
.
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── org
    │           └── aamm
    │               └── z2java
    │                   └── lesson1
    │                       └── App.java
    └── test
        └── java
            └── org
                └── aamm
                    └── z2java
                        └── lesson1
                            ├── GuidanceTest.java
                            └── MockPrintStream.java

13 directories, 4 files

You don't need to fully understand what each part does. What you need to know is that:

  • pom.xml - The configuration file for Maven. It tells Maven what to do. We will run Maven in a couple of minutes, so you will see it in action.
  • src/main/java - Here is where the main source code should be placed. When we program, what we try to create are the main source code. Our job is to create files inside of such a directory. We will discuss the meaning of org/aamm/z2java/lesson1 later.
  • src/test/java - Here is where tests are placed. When we program it is a good practice to create tests that check if our program is working properly. On these lessons, tests are already provided. So all you need to do is to make them pass.

Step 5 - Run Maven for the first time

You simply need to run the mvn command and all the magic will happen before your eyes.

vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$ mvn
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building lesson1 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ lesson1 ---
[INFO] Deleting /home/vagrant/lesson-1/target
[INFO] 
[INFO] --- maven-resources-plugin:2.3:resources (default-resources) @ lesson1 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/vagrant/lesson-1/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.0:compile (default-compile) @ lesson1 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/vagrant/lesson-1/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.3:testResources (default-testResources) @ lesson1 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/vagrant/lesson-1/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.0:testCompile (default-testCompile) @ lesson1 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /home/vagrant/lesson-1/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ lesson1 ---
[INFO] Surefire report directory: /home/vagrant/lesson-1/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.aamm.z2java.lesson1.GuidanceTest
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.057 sec <<< FAILURE!

Results :

Failed tests:   test(org.aamm.z2java.lesson1.GuidanceTest): The main method should call the method System.out.println(String) to print "Hello World"

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.935s
[INFO] Finished at: Sun Nov 02 15:08:53 UTC 2014
[INFO] Final Memory: 9M/22M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.10:test (default-test) on project lesson1: There are test failures.
[ERROR] 
[ERROR] Please refer to /home/vagrant/lesson-1/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

As you can see, something is wrong. We wanted to see that! It means there is a test that did not pass. Let's take a look at the failure message:

The main method should call the method System.out.println(String) to print "Hello World"

This message is telling us what went wrong. We can write tests so that they print those messages to hint for failure causes.

There is something else to notice. Let's check the directory contents once again:

vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$ ls
pom.xml  src  target

Maven created a new directory called target. This is where Maven puts all compiled files. We did not have to manually compile anything, nor run any test. Maven did all the hard work for us.

Step 6 - Let's program!

Time to program for real. Open the file src/main/java/org/aamm/z2java/lesson1/App.java with any editor. If you don't know any Linux editor, simply use pico (but I recommend learning the editor called vim, which is quite powerful but a bit hard to learn):

vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$ pico src/main/java/org/aamm/z2java/lesson1/App.java

You will see the source code:

package org.aamm.z2java.lesson1;

/**
 * Your class should write the message "Hello World" in the console using System.out.println.
 */
public class App 
{
    public static void main( String[] args )
    {
        // TODO Write here a command that prints "Hello World".
    }
}

If you are using pico, you will be happy to know that the words on the bottom of the screen are available commands. The character ^ means the "Control" key. So Control+X is the command to exit the editor.

Go ahead and replace the line // TODO ... so that the file becomes:

package org.aamm.z2java.lesson1;

/**
 * Your class should write the message "Hello World" in the console using System.out.println.
 */
public class App 
{
    public static void main( String[] args )
    {
        System.out.println("bla bla bla");
    }
}

Then press Control+X to save the file. pico will ask you to confirm saving the file. Just press Y to confirm and then hit ENTER to confirm again.

Step 7 - Run Maven again

The process that all programmers follow is:

  1. write source code
  2. compile
  3. run the program
  4. search for errors
  5. if there is anything wrong, go back to Step 1. If you found no errors, you are done!

Programmers love to do A and D, but hate B and C because they are repetitive and boring. That is why Maven does B and C for us. So let's run Maven again:

vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$ mvn
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building lesson1 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ lesson1 ---
[INFO] Deleting /home/vagrant/lesson-1/target
[INFO] 
[INFO] --- maven-resources-plugin:2.3:resources (default-resources) @ lesson1 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/vagrant/lesson-1/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.0:compile (default-compile) @ lesson1 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/vagrant/lesson-1/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.3:testResources (default-testResources) @ lesson1 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/vagrant/lesson-1/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.0:testCompile (default-testCompile) @ lesson1 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /home/vagrant/lesson-1/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ lesson1 ---
[INFO] Surefire report directory: /home/vagrant/lesson-1/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.aamm.z2java.lesson1.GuidanceTest
bla bla bla
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.064 sec <<< FAILURE!

Results :

Failed tests:   test(org.aamm.z2java.lesson1.GuidanceTest): The message you printed was not "Hello World". Take care about the differences between print and println. expected:<[Hello World]

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.947s
[INFO] Finished at: Sun Nov 02 15:47:39 UTC 2014
[INFO] Final Memory: 9M/24M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.10:test (default-test) on project lesson1: There are test failures.
[ERROR] 
[ERROR] Please refer to /home/vagrant/lesson-1/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

Ouch! We failed again! Don't panic! Programmers fail all the time! In fact, programming is about making things work. If everything is working, you are not programming. Programming is the process of finding things to improve and to create new things.

Let's see what happened this time! The new error message is:

expected:<[Hello World]

How silly we were. Instead of printing "Hello World" like the TODO line asked us to do, we wrote "bla bla bla" instead. It looks like we can't easily trick Java.

Step 8 - Correct mistakes

Let's go back to pico and change the file again:

package org.aamm.z2java.lesson1;

/**
 * Your class should write the message "Hello World" in the console using System.out.println.
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println("Hello world");
    }
}

It looks perfect this time! Save your file (Control+X if you are running pico). Let's run Maven again!

Step 9 - Running Maven again

We have to keep running Maven a thousand times. Now we understand why it is only three letters "mvn", so we can type it fast and not waste time:

vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$ mvn
(...)
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.aamm.z2java.lesson1.GuidanceTest
Hello world
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.087 sec <<< FAILURE!

Results :

Failed tests: 
  test(org.aamm.z2java.lesson1.GuidanceTest): The message you printed was not "Hello World". Take care about the differences between print and println. expected:<Hello [W]orld
> but was:<Hello [w]orld
>

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.019s
[INFO] Finished at: Sat Oct 25 21:11:52 BRST 2014
[INFO] Final Memory: 9M/125M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.7.2:test (default-test) on project lesson1: There are test failures.
[ERROR] 
[ERROR] Please refer to /home/akira/.svnworkspace/Documents/pessoal/projects/zeroToJavaWorkspace/trash/lesson1/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

Not again! What can possibly be wrong this time? Now the message says:

expected:<Hello [W]orld
> but was:<Hello [w]orld

So Java is telling us that we printed lowercase w instead of capital W. Let's change that again!

Step 10 - Change it again

This will be the third time we run pico (or your favorite editor). So the text editor is extremely important to a programmer. It is like the guitar for a guitar player. To be a good programmer you need to know a good editor in depth. For Java, among the best ones are Eclipse, InteliJ Idea, and Netbeans.

But for beginners, pico, vim or emacs are very decent ones.

By the way, you can run the same command again on Linux by pressing the up arrow several times. Then type ENTER to run the command again.

Let's run pico again, and this time pay attention to all details:

package org.aamm.z2java.lesson1;

/**
 * Your class should write the message "Hello World" in the console using System.out.println.
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println("Hello World");
    }
}

Step 11 - We are the champions

Let's run Maven again and see how much we rock:

vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$ mvn
(...)
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.aamm.z2java.lesson1.GuidanceTest
Hello World
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.151 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.875s
[INFO] Finished at: Sat Oct 25 21:19:45 BRST 2014
[INFO] Final Memory: 9M/125M
[INFO] ------------------------------------------------------------------------

No failures! BUILD SUCCESS! Our job is done!

Going the extra mile!

So far we saw how to have our program tested. All it does is to print a single message: "Hello World". But I can see much more than that on the terminal. Maven is adding a lot of obscure messages, and I really want to see only my program running. If my program is printing "Hello Word", I wanna see just that. How can I do that?

Maven will help us again:

vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$ mvn compile exec:java --quiet -Dexec.mainClass=org.aamm.z2java.lesson1.App
Hello World
vagrant@vagrant-ubuntu-trusty-32:~/lesson-1$

So what just happened? We just called maven passing 4 arguments:

  • compile - Tells Maven to compile your class.
  • exec:java - Tells Maven to execute a Java program
  • --quiet - Tells Maven to be quiet. So Maven does not print those obscure messages.
  • -Dexec.mainClass=org.aamm.z2java.lesson1.App - Tells Maven to execute the class called org.aamm.z2java.lesson1.App . This is our program.

So what exactly is a class? For now, all you need to know is that App is the name of our class and org.aamm.z2java.lesson1 is the package where the class is located.

A typical Java system may have thousands of classes. So we need to tell Maven which class is our main class. In other words, which class is the entry point, or the one that runs first and will call all the others.

For now such concept may look abstract and contrived since we only have one class, but those ideas will become more clear as we advance.

Have fun

Now that you finished this lesson, you can change the App class the way you want. Sure, by now the only thing you know how to do is to print messages in the console, but you can add more lines to print other things. Even some ASCII art!

package org.aamm.z2java.lesson1;

/**
 * Your class should write the message "Hello World" in the console using System.out.println.
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println("+---------------+");
        System.out.println("| JAVA IS GREAT |");
        System.out.println("+---------------+");
   }
}

Back to top