User Tools

Site Tools


doc:appunti:prog:java_compile_jar_command_line

How to compile a jar from the command line

On a Debian GNU/Linux version 11.0 Bullseye it is required to install the default-jdk package, to have the javac compiler.

Finding the reqired libraries

A Java project generally uses several libraries; you can find lines like this into the .java sources:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

If you don't download and install the proper .jar archives, you will get errors like the following when executing the javac compiler:

./org/vmax/amba/cfg/FirmwareConfig.java:3:
    error: package com.fasterxml.jackson.annotation does not exist
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

Each library may exists on the internet in several versions: it may be an hard work to guess which exact version was used by the developer for each one. You can use several internet repositories to search and download the archives you need, we suggest at least jar-download.com, repo1.maven.org and www.java2s.com.

Where to put the required libraries

The project files are layed-out hierarchically starting from the project's root directory; in our example the source files are into the path org.vmax.amba.

We decided to put the required libraries into a subdirectory relative to the project's root directory; we created a subdirectory named lib and placed all the .jar archives into it. At runtime, the compiled jar archive will search the libraries starting from its directory, descending the same lib subdirectory:

└─ java-project/
   ├─ lib/
   │  ├─ apache-commons-net.jar
   │  ├─ commons-math3-3.0.jar
   │  ├─ ...
   │  └─ slf4j.jar
   └─ org/
      └─ vmax/
         ├─ amba/
         │  ├─ bitrate/
         │  ├─ ...
         │  ├─ AppMain.java
         │  ├─ ...
         │  └─ Utils.java
         └─ midrive/

This may not be the optimal solution, because jar libraries are not installed system-wide and thus they are not shared among other Java programs. This recipe has the advantage that the installation of the Java program and the required libraries can be accomplished by an unprivileged user in its home directory.

Compile the Java code

To be on the safe side, we delete all the previously compiled files which have extension .class, then we create a list of all the .java files which are to be compiled. The CLASSPATH environment variable is intialized with the name of all the jar libraries, separated by a colon:

#!/bin/sh
CLASSPATH="$(echo lib/*.jar | sed 's/\.jar /\.jar:/g')"
find . -name '*.class' | xargs -r rm
find . -name '*.java' > sources.txt
javac --class-path "$CLASSPATH" @sources.txt

Pack the Jar archive

Finally we want to pack the Java program into a jar archive. We have to create a manifest file where we declare the Java class that is the entry point of the program and we list all the libraries that the program depends on. The archive will be named as requested and it will contains all the .class files found by the find command:

#!/bin/sh
CLASSES="$(echo lib/*.jar)"
echo 'Main-Class: org.vmax.amba.AppMain' > manifest.txt
echo "Class-Path: $CLASSES" >> manifest.txt
jar --create --verbose \
    --file='firmware-editor-tool.jar' \
    --manifest='manifest.txt' \
    $(find . -type f -name '*.class')

Running the Java program from jar file

Finally we can start the Java program from the jar archive:

java -jar /path/java-program/firmware-editor-tool.jar

Into the jar archive there is the MANIFEST.MF file, which will indicate where to search for the required libraries, relative to the same jar archive directory.

doc/appunti/prog/java_compile_jar_command_line.txt · Last modified: 2021/11/08 17:16 by niccolo