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