Appendix A: Packaging Java Applications

If your program is made up of multiple classes (it should be), you can package all needed classes in a jar archive. If your Java program makes calls to a native library (such as OpenCV) the command that runs your program should pass the path to those libraries as options to the Java virtual machine

There are build tools like ant and maven that help you automate many of the tasks involved in building software as well as documenting the dependency between those tasks. These tools generally offer a packaging task. For example, after changing your code (*.java files) you need to compile them (generate *.class files) before packaging them or running them. So the package step depends on the compile step. The Integrated Development Environments (IDEs) such as Eclipse and NetBeans also facilitate packing your application.

This article explains the steps to packaging an application without using those tools, but instead invoking all the commands from a command prompt in Windows so that each step can be illustrated and explained. The example application is a very simple Java program that uses the OpenCV library. OpenCV was picked because it is a very useful library in robotics and it makes calls to native code so we get to see how to tell the Java Virtual Machine about the location of native libraries when running the program.

1. Create project structure

Using a Command Prompt navigate to the directory where you keep your source code or create a directory for this purpose if you don't have one yet. On my machine I keep the source code in a folder named dev on my C: drive (so C:\dev ). We want to end up with a directory structure that looks like this

javapkg
    |
    +--> src
    |      |
    |      +--> org
    |             |
    |             +--> team1635
    |                    |
    |                    +--> javapkgtut
    |
    +--> target
           |
           +--> classes

Here are the commands that will create this directory structure

mkdir javapkg
cd javapkg
mkdir src
cd src
mkdir org
cd org
mkdir team1635
cd team1635
mkdir javapkgtut
cd javapkgtut
cd ..\..\..\..
mkdir target
cd target
mkdir classes

[TODO] Explain why we create this directory structure

2. Download the OpenCV library

Download the OpenCV library. A compiled version is available for the Windows platform and here we are using version 2.4.13. Run the downloaded executable file, and specify the directory where the library should be extracted. I keep my libraries in a folder named c:\dev\lib so I can use them in multiple projects. Another alternative is to store the library in a folder named lib inside your project. Remember the place you put the library because you'll have to use that location in a couple of steps below.

3. Code the program

Navigate to the package that holds our source file.

cd ..\src\org\team1635\javapkgtut

Open a file named JavaPkgMain.java in the text editor

notepad JavaPkgMain.java

There will be a prompt asking if you want to create a new file. Click yes and then copy the following java code in the text editor window. This code is from the OpenCV 3.0 Computer Vision with Java

package org.team1635.javapkgtut;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;

/**
* Sample OpenCV project
*/
public class JavaPkgMain {
  static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }

  public static void main( String[] args ) {
    System.out.println("Welcome to OpenCV " + Core.VERSION);
    Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
    System.out.println("OpenCV Mat: " + m);

    Mat mr1 = m.row(1);
    mr1.setTo(new Scalar(1));

    Mat mc5 = m.col(5);
    mc5.setTo(new Scalar(5));

    System.out.println("OpenCV mat data:\n" + m.dump());
  }
}

Save the file and exit the text editor then navigate back to the root of our project

cd ..\..\..\..

4. Compile

Compile the code using the following command

"C:\Program Files\Java\jdk1.8.0_66\bin\javac" -d target/classes -classpath ..\lib\opencv\build\java\opencv-2413.jar src/org/team1635/javapkgtut/JavaPkgMain.java

Let's go over the different part of this command:
"C:\Program Files\Java\jdk1.8.0_66\bin\javac" - when you install the Java Development Kit [TODO: link] the java tools are not put in your path. So we have to invoke the compiler by specifying the whole path. Your path might be different, and most likely the different part is the version of the jdk (shown in italics).
-d target/classes - normally the byte-code (*.class) files are written to the same directory where the source (*.java) files are located. But, in this case we tell the compiler to write the byte-code files to the target/classes directory
-classpath ..\lib\opencv\build\java\opencv-2413.jar - tell the complier where to find the opencv library. Replace the part in italics with the path where you expanded the OpenCV library in step 2.
src/org/team1635/javapkgtut/JavaPkgMain.java - we need to pass into the compiler the path to our source file.

5. Run program

java -Djava.library.path=..\lib\opencv\build\java\x64 -classpath ..\lib\opencv\build\java\opencv-2413.jar;target\classes org.team1635.javapkgtut.JavaPkgMain
Welcome to OpenCV 2.4.13.0
OpenCV Mat: Mat [ 5*10*CV_8UC1, isCont=true, isSubmat=false, nativeObj=0x193c2150, dataAddr=0x280e010 ]
OpenCV mat data:
[0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
1, 1, 1, 1, 1, 5, 1, 1, 1, 1;
0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
0, 0, 0, 0, 0, 5, 0, 0, 0, 0]

Let's go over the different part of this command:
java - when you install the Java Development Kit it puts the virtual machine (runtime) command somewhere in your path. But if you want to be absolutely sure you're running the right version prepend the path to the JDK binaries as we did for the javac compiler in step 4 above.
-Djava.library.path=..\lib\opencv\build\java\x64 - This tells the virtual machine where the native code libraries are located. The Raspberry PI native files will be different than your windows native files, but the concept should be the same
-classpath ..\lib\opencv\build\java\opencv-2413.jar;target\classes - The first library we pass into the classpath is the same we passed into the compiler's classpath. The second path is where we put our compiled code for our program.
org.team1635.javapkgtut.JavaPkgMain - The last argument is the name of the class that has the Main entry point. Notice that the class has to be qualified with the full package name and it does not have the .class extension.

6. Packaging the application in a jar

[TODO] Coming soon

7. Running the application from a jar

[TODO] Coming soon

8. Same steps using a git project

The code used in this tutorial can be found in github. If you don't have git installed you should download it from here and install it.

Open the git bash window which will open in your home directory (something like /c/Users/[username]). Navigate to a directory where you can try the code in git. Since this project has the same name as the one we build earlier from scratch you can put it in a temporary directory like /c/temp .

[TODO] Finish the git demo

7. Java utility documentation

    Java Compiler: javac
    Java Archive Tool: jar
    Java Virtual Machine: java