Notes for Core Java Volume I (12th): Note 1

 Package & Jar In Java

Attribution Note: These notes are comprehensive study materials derived from Core Java Volume I (12th Edition) by Cay S. Horstmann. The technical explanations, concepts, and many examples are based on the book's content. 

In Java, the word "package" has two meanings depending on context:

1. The Noun (Java `package`): The namespace organization system for your code.

2. The Verb (Packaging a Project): The process of bundling your compiled code and resources into a distributable file (usually a JAR).


Part 1: The Java `package` (Organization)

Before you can bundle code, it must be organized. Java uses a hierarchical system that mirrors the file system.

1. The Concept


A package is a namespace that groups related classes and interfaces. It solves two main problems:

- Naming Collisions: Two developers can both create a class named `User` as long as they are in different packages (e.g., `com.google.User` vs `com.amazon.User`).
    
- Access Control: It allows the use of `protected` and package-private (default) access modifiers to restrict visibility.

2. Directory Mapping (The Golden Rule)


The package name **must** match the directory structure on your disk exactly.

- Code: `package com.example.utils;`
    
- File System:** `project-root/src/com/example/utils/MyClass.java`


3. Reverse Domain Name Convention


To ensure global uniqueness, Java developers use their internet domain name in reverse as the package prefix.

- If your site is `myapp.io`, your root package is `io.myapp`.


Part 2: The JAR File (The Container)

Once your code is organized and compiled, you distribute it as a JAR (Java Archive).


1. What is a JAR?


A JAR file is fundamentally just a ZIP file. You can actually rename .jar to .zip and open it in WinZip or 7-Zip.

It contains:

- Compiled Bytecode: `.class` files (preserving the package directory structure).
    
- Resources: Images, configs (`.xml`, `.properties`).
    
- Metadata: The `META-INF` folder and `MANIFEST.MF`.

2. Types of JARs


- Plain JAR (Library): Contains code but is not executable. Used as a dependency by other projects.
    
- Executable JAR: Has a `Main-Class` defined in the Manifest. Can be run via `java -jar app.jar`.
    
- Fat JAR (Uber-JAR): Contains your code **PLUS** all the third-party libraries (dependencies) you used, extracted and repacked into a single massive file.

Part 3: The Workflow (How to Package)


Here is how the "Packaging" process works, from manual commands (low-level) to modern build tools.

Level 1: The Manual Way (CLI)


This is what happens "under the hood."

1. Compile: Turn Java into Bytecode.

javac -d bin src/com/example/Main.java

2. Create Manifest: Create a text file `manifest.txt`.

Main-Class: com.example.Main

3. Package (The `jar` command):
    
    - `c`: create new archive
        
    - `f`: specify filename
        
    - `m`: include manifest

jar cfm MyApp.jar manifest.txt -C bin .

Level 2: The Modern Way (Maven/Gradle)

In professional development, you rarely use the `jar` command manually. You use a build tool to manage dependencies and packaging instructions.

Using Maven (pom.xml):

You simply run the command:

mvn package

What Maven does automatically:

1. Compiles your code (`src/main/java`) to `target/classes`.
    
2. Copies resources (`src/main/resources`) to `target/classes`.
    
3. Generates a generic `MANIFEST.MF`.
    
4. Zips everything into `target/myapp-1.0.jar`.

Part 4: The "Fat JAR" (Shading) 

This is the most common point of confusion for beginners.

The Problem:

If your project uses a library (like Google Guava), the standard mvn package creates a "Thin JAR" containing only your code. If you try to run it, you get: java.lang.NoClassDefFoundError.

The Solution:

You must create a Fat JAR (or Uber-JAR) that bundles your dependencies inside your JAR.

How to do it (Maven Shade Plugin):

You add this plugin to your pom.xml. It "shades" (merges) your dependencies into your final artifact.

    
      <plugin>
        <groupid>org.apache.maven.plugins</groupid>
        <artifactid>maven-shade-plugin</artifactid>
        <version>3.2.4</version>
        <executions>
          <execution>
            <phase>package<]</phase>
            <goals><goal>shade</goal></goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainclass>com.example.Main</mainclass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    

Part 5: Executing the Package

Once packaged, how do you run it? 1. For Executable JARs:


java -jar MyApp.jar


(Note: This ignores the generic CLASSPATH. It only looks inside the JAR).
2. For Plain JARs (Libraries):

You must add it to the classpath of the app using it:

java -cp MyApp.jar:Dependency.jar com.example.Main




Comments