Thursday, August 18, 2016

Java 8 : How to create executable JAR without IDE, command-line :: explained

  In the world of build tools (Ant, Maven or Gradle) it may seems to not being even useful to think about the command line. The most of famous IDEs (IntelliJ, Eclipse or NetBeans ... others) offers building tools implementation immediately.  
  But in some of very few moments you have only the command line and no internet (someone has turned it off)
What will you do then ? 
  In this post we compile simple project with multiple classes and library dependencies . The classes are located on different places in the project package structure. We will also create appropriate manifest file. 
 The goal of this post to have executable JAR file. Let's call it ExecutableOne.jar. 
The only requirements is to have properly configured java JDK. In this blog post is used java 1.8 build 91. 
  All is ready and we can open the command line and continue...
Let's start with creation of simple project: executable-one
The example project structure is following Maven Standad Directory Layout structure: 
./libs
./out
./README.md
./src
./src/main
./src/main/java
./src/main/java/com
./src/main/java/com/exec
./src/main/java/com/exec/one
./src/main/resources

   As our intent is to create executable JAR file we create main class in the 
package:  com.exec.one 
Package can be find in the folder SRC/MAIN/JAVA of our sample project structure.
1  package com.exec.one;
2
3  public class Main {
4     public static void main(String[] args){                                                                                                                                            
5         System.out.println("Main Class Start");                                                                                                                                        
6     }                                                                                                                                                                                  
7 } 

Inside the folder SRC/MAIN/RESOURCES we create META-INF folder and then inside we place MANIFEST.FM file. 
Let's open the newly created MANIFEST.FM file and put basic description. 

1 Manifest-Version: 1.0   
2 Class-Path: .                                                                                                                                                                          
3 Main-Class: com.exec.one.Main

NOTE: There will be the only one MANIFEST.FM file per JAR file. 
MANIFEST file contains details how JAR file will be used. We don't go into deep details only let's be focused on the option we have defined: 
1. Manifest-Version  : manifest file version 
2. Class-Path: The application or extension class loader uses the value of this attribute to construct its internal search path. Originally class loader downloads and opens each element in its search path. For this purposes simple linear search algorithm has been used.
3. Main-Class: there is the name of the class which will the launcher load at the startup time 
... for more information use google

  Now we create the first version of executable JAR file without any *.jar library. The LIBS folder in our project structure is still empty. 
  First we need to compile the project by using javac and the output we store inside the 
OUT folder. Let's go back to our command line and inside the root of the poject type:
$javac -cp ./src/main/java ./src/main/java/com/exec/one/*.java -d ./out/
project is compiled into the OUT directory. You can check it by using ls command.
  Second step we create executable JAR file from the resources located inside the OUT directory. We go back to the command line and type following command:
$jar cvfm ExecutableOne.jar ./src/main/resources/META-INF/MANIFEST.MF -C ./out/ .
  Brief explanation of the JAR tool options we have used: 
c - indicates we want to create new jar file
v - generates for us verbose output to standard output
f - specifies the jarfile to be created 
m - indicates manifest file we use. Manifest file includes name: value pairs 
option -C indicates temporary changes directory. Classes are added from this directory to the jar file. The dot indicates all classes (files).

FINAL RESULT -> opent the command line and type: 
$java -jar ./ExecutableOne.jar
standard output: 
Main Class Start

The blog post will continue
   The next post will show how to create fatJAR file with libraries without using any IDE, only pure command line.

My GiTHub Project: execute-one


No comments: