Ce face jar
Un fișier .jar (Java ARchive) este o arhivă ZIP cu fișiere .class, resurse (imagini, fișiere de configurare) și un manifest, META-INF/MANIFEST.MF. Bibliotecile Java se distribuie aproape mereu ca .jar, iar aplicațiile la fel.
Comanda are o formă scurtă, în stilul lui tar (c = creează, t = listează, x = extrage, f = fișierul, v = detaliat, e = clasa principală), și una lungă, mai lizibilă (--create, --file, --main-class). -C dir . adaugă conținutul directorului dir, fără prefixul lui.
Dacă manifestul are Main-Class, arhiva este „executabilă”: java -jar app.jar. Altfel, jar-ul se pune în classpath (java -cp app.jar ro.dexblog.App). Jar-urile din care depinde aplicația nu sunt incluse automat; uneltele de build (Maven, Gradle) pot crea un „fat jar” cu totul inclus.
Exemple
Exemplul 1: De la surse la un jar executabil
Compilăm în out/, creăm jar-ul cu clasa principală setată în manifest, apoi îl listăm și îl rulăm. Argumentele de după numele jar-ului ajung în args.
// src/ro/dexblog/meteo/Prognoza.java
package ro.dexblog.meteo;
public class Prognoza {
public static String pentru(String oras) {
return switch (oras) {
case "Iași" -> "senin, 14 °C";
case "Cluj" -> "ploaie, 9 °C";
default -> "date indisponibile";
};
}
}
// src/ro/dexblog/meteo/App.java
package ro.dexblog.meteo;
public class App {
public static void main(String[] args) {
String[] orase = args.length > 0 ? args : new String[] {"Iași", "Cluj"};
for (String oras : orase) {
System.out.println(oras + ": " + Prognoza.pentru(oras));
}
}
}
Rezultat în terminal
$ javac -d out src/ro/dexblog/meteo/*.java
$ jar --create --file meteo.jar --main-class ro.dexblog.meteo.App -C out .
$ jar tf meteo.jar
META-INF/
META-INF/MANIFEST.MF
ro/
ro/dexblog/
ro/dexblog/meteo/
ro/dexblog/meteo/App.class
ro/dexblog/meteo/Prognoza.class
$ java -jar meteo.jar Iași Brașov
Iași: senin, 14 °C
Brașov: date indisponibile
Exemplul 2: Manifestul, forma scurtă și jar-ul în classpath
Manifestul conține linia Main-Class adăugată de --main-class. Forma scurtă cvf arată fiecare fișier adăugat și cât s-a comprimat. Fără Main-Class, jar-ul se folosește cu -cp și numele clasei.
$ unzip -p meteo.jar META-INF/MANIFEST.MF
$ jar cvf meteo-v.jar -C out .
$ java -cp meteo-v.jar ro.dexblog.meteo.App Cluj
Rezultat în terminal
Manifest-Version: 1.0
Created-By: 27 (Homebrew)
Main-Class: ro.dexblog.meteo.App
added manifest
adding: ro/(in = 0) (out= 0)(stored 0%)
adding: ro/dexblog/(in = 0) (out= 0)(stored 0%)
adding: ro/dexblog/meteo/(in = 0) (out= 0)(stored 0%)
adding: ro/dexblog/meteo/App.class(in = 1160) (out= 643)(deflated 44%)
adding: ro/dexblog/meteo/Prognoza.class(in = 636) (out= 457)(deflated 28%)
Cluj: ploaie, 9 °C
Greșeli frecvente
- Creezi jar-ul din directorul greșit (
jar cf app.jar out): clasele ajung caout/ro/dexblog/..., iarjavanu le mai găsește. Folosește-C out .. - Rulezi
java -jarpe un jar fărăMain-Class:no main manifest attribute, in app.jar. - Folosești
java -jar app.jarîmpreună cu-cp lib/*pentru dependențe: cu-jar, opțiunea-cpeste ignorată. Pune dependențele înClass-Pathdin manifest sau rulează cu-cpși numele clasei.
Comenzi înrudite
javac: javac este compilatorul Java: transformă fișierele .java în fișiere .class (bytecode) și raportează erorile și avertismentele.java (lansatorul): java pornește mașina virtuală Java și rulează un program: o clasă compilată, un fișier .jar sau direct un fișier sursă .java.Module (module-info.java): Un modul (module-info.java) grupează pachete și declară explicit de ce module depinde (requires) și ce pachete oferă altora (exports).Pachete și importuri (package, import): package așază clasa într-un pachet (un spațiu de nume, ca un director); import permite folosirea claselor din alte pachete după numele scurt.