Enterprise Java Development@TOPIC@
In this chapter you will be introduced to a standard module file structure that contains a class we intend to use in production and a unit test to verify the functionality of the production class. You will be asked to form the directory structure of files and execute the commands required to build and run the unit test.
This chapter is optional!!! It contains many tedious steps that are somewhat shell-specific. The intent is to simply introduce the raw data structure and actions that need to take place and then to later automate all of this through Maven. If you wish to just skim the steps -- please do. Please do not waste time trying to port these bash shell commands to your native shell.
This part requires junit.jar. These should have been downloaded for you when you built the class examples and can be located in $M2_REPO/junit/junit/(version)/. Where M2_REPO is HOME/.m2/repository or the location you have specified in the localRepository element of $HOME/.m2/settings.xml.
Set a few shell variables to represent root directories. For the
purposes of the follow-on steps, PROJECT_BASEDIR
is the root directory
for this exercise. In the example below, the user has chosen a directory of
$HOME/proj/784/exercises
to be the root directory for all class
exercises and named the root directory for this project "ex1". An
alternative for CLASS_HOME
might be c:/jhu/784
. M2_REPO
is the path to your Maven repository.
export CLASS_HOME=$HOME/proj/784 export PROJECT_BASEDIR=$CLASS_HOME/exercises/ex1 mkdir -p $PROJECT_BASEDIR cd $PROJECT_BASEDIR export M2_REPO=$HOME/.m2/repository
Create project directory structure. In this example, the developer used $HOME/proj/784 for all work in this class.
$PROJECT_BASEDIR |-- src | |-- main | | `-- java | | `-- myorg | | `-- mypackage | | `-- ex1 | `-- test | |-- resources | `-- java | `-- myorg | `-- mypackage | `-- ex1 `-- target |-- classes |-- test-classes `-- test-reports
mkdir -p src/main/java/myorg/mypackage/ex1 mkdir -p src/test/java/myorg/mypackage/ex1 mkdir -p src/test/resources mkdir -p target/classes mkdir -p src/test/java/myorg/mypackage/ex1 mkdir -p target/test-classes mkdir -p target/test-reports
Add the following Java implementation class to $PROJECT_BASEDIR/src/main/java/myorg/mypackage/ex1/App.java
package myorg.mypackage.ex1;
public class App {
public int returnOne() {
System.out.println( "Here's One!" );
return 1;
}
public static void main( String[] args ) {
System.out.println( "Hello World!" );
}
}
Add the following Java test class to $PROJECT_BASEDIR/src/test/java/myorg/mypackage/ex1/AppTest.java
package myorg.mypackage.ex1;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* Unit test for simple App.
*/
public class AppTest {
@Test
public void testApp() {
System.out.println("testApp");
App app = new App();
assertTrue("app didn't return 1", app.returnOne() == 1);
}
}
Make sure you put AppTest.java in the src/test tree.
Compile the application and place it in target/ex1.jar. The compiled classes will go in target/classes.
javac src/main/java/myorg/mypackage/ex1/App.java -d target/classes jar cvf target/ex1.jar -C target/classes . jar tf target/ex1.jar
$ javac src/main/java/myorg/mypackage/ex1/App.java -d target/classes $ jar cvf target/ex1.jar -C target/classes . added manifest adding: myorg/(in = 0) (out= 0)(stored 0%) adding: myorg/mypackage/(in = 0) (out= 0)(stored 0%) adding: myorg/mypackage/ex1/(in = 0) (out= 0)(stored 0%) adding: myorg/mypackage/ex1/App.class(in = 519) (out= 350)(deflated 32%) $ jar tf target/ex1.jar META-INF/ META-INF/MANIFEST.MF myorg/ myorg/mypackage/ myorg/mypackage/ex1/ myorg/mypackage/ex1/App.class
Compile the JUnit test and place the compiled tests in target/test-classes.
export JUNIT_JARS="$M2_REPO/junit/junit/4.12/junit-4.12.jar:$M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" javac -classpath "target/ex1.jar:$JUNIT_JARS" src/test/java/myorg/mypackage/ex1/AppTest.java -d target/test-classes
Verify you have your "production" class from src/main compiled into target/classes directory, your unit test class from src/test compiled into target/test-classes directory, and the Java archive with the production class is in target directory.
target |-- classes | `-- myorg | `-- mypackage | `-- ex1 | `-- App.class |-- ex1.jar |-- test-classes | `-- myorg | `-- mypackage | `-- ex1 | `-- AppTest.class `-- test-reports
Run the JUnit test framework.
java -classpath "target/ex1.jar:$JUNIT_JARS:target/test-classes" org.junit.runner.JUnitCore myorg.mypackage.ex1.AppTest
JUnit version 4.12 .testApp Here's One! Time: 0.003 OK (1 test)
Change add/remove a test that will fail, re-compile the test class, and re-run.
//AppTest.java
@Test
public void testFail() {
System.out.println("testFail");
App app = new App();
assertTrue("app didn't return 0", app.returnOne() == 0);
}
javac -classpath "target/ex1.jar:$JUNIT_JARS" src/test/java/myorg/mypackage/ex1/AppTest.java -d target/test-classes java -classpath "target/ex1.jar:$JUNIT_JARS:target/test-classes" org.junit.runner.JUnitCore myorg.mypackage.ex1.AppTest
JUnit version 4.12 .testApp Here's One! .testFail Here's One! E Time: 0.007 There was 1 failure: 1) testFail(myorg.mypackage.ex1.AppTest) java.lang.AssertionError: app didn't return 0 at org.junit.Assert.fail(Assert.java:93) at org.junit.Assert.assertTrue(Assert.java:43) at myorg.mypackage.ex1.AppTest.testFail(AppTest.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ... at org.junit.runner.JUnitCore.main(JUnitCore.java:45) FAILURES!!! Tests run: 2, Failures: 1
In this chapter of the exercise you setup, built, and tested a sample project with only command-line commands. You did this to help show what higher level tools will need to do as well. Even though the command line provides clarity, it doesn't scale and shell scripts aren't generally portable and optimized (wrong tool for the job). Hopefully, after going through this, you have an understanding of the low level structure and usecases and are now interested adding a build environment.