Modulele Spring-Boot-Loader permit Spring Boot să accepte fișiere jar și război executabile. Dacă utilizați pluginul Maven sau pluginul Gradle, borcanele executabile sunt generate automat și, în general, nu trebuie să cunoașteți detaliile despre modul în care funcționează.

executabil

Dacă aveți nevoie să creați borcane executabile dintr-un alt sistem de construire sau dacă sunteți doar curioși cu privire la tehnologia de bază, această anexă oferă câteva informații.

1. JAR-uri imbricate

Java nu oferă nicio modalitate standard de încărcare a fișierelor jar imbricate (adică fișiere jar care sunt ele însele conținute într-un jar). Acest lucru poate fi problematic dacă trebuie să distribuiți o aplicație autonomă care poate fi rulată din linia de comandă fără despachetare.

Pentru a rezolva această problemă, mulți dezvoltatori folosesc borcane „umbrite”. Un borcan umbrit împachetează toate clasele, din toate borcanele, într-un singur „borcan uber”. Problema cu borcanele umbrite este că devine greu să vezi ce biblioteci sunt de fapt în aplicația ta. Poate fi, de asemenea, problematic dacă același nume de fișier este utilizat (dar cu conținut diferit) în mai multe borcane. Spring Boot adoptă o abordare diferită și vă permite să faceți cuiburi direct.

1.1. Structura fișierului Jar executabil

Fișierele jar compatibile cu Spring Boot Loader ar trebui să fie structurate în felul următor:

Clasele de aplicații trebuie plasate într-un director imbricat BOOT-INF/classes. Dependențele ar trebui plasate într-un director imbricat BOOT-INF/lib.

1.2. Structura fișierului de război executabil

Fișierele de război compatibile cu Spring Boot Loader ar trebui să fie structurate în felul următor:

Dependențele ar trebui plasate într-un director WEB-INF/lib imbricat. Orice dependență care este necesară atunci când rulează încorporat, dar care nu este necesară la implementarea într-un container web tradițional, trebuie plasată în WEB-INF/lib-provided .

1.3. Fișiere index

Arhivele jar și război compatibile cu Spring Boot Loader pot include fișiere index suplimentare în directorul BOOT-INF /. Un fișier classpath.idx poate fi furnizat atât pentru borcane, cât și pentru războaie, oferă ordinea ca borcanele să fie adăugate la clasa de cale. Fișierul layer.idx poate fi utilizat numai pentru borcane, permite împărțirea unui borcan în straturi logice pentru crearea imaginii Docker/OCI.

Fișierele index urmează o sintaxă compatibilă cu YAML, astfel încât să poată fi analizate cu ușurință de instrumente terțe. Cu toate acestea, aceste fișiere nu sunt analizate intern ca YAML și trebuie să fie scrise exact în formatele descrise mai jos pentru a putea fi utilizate.

1.4. Classpath Index

Fișierul index classpath poate fi furnizat în BOOT-INF/classpath.idx. Oferă o listă a numelor de jar (fără a include directorul) în ordinea în care acestea trebuie adăugate la classpath. Fiecare linie trebuie să înceapă cu spațiul de liniuță ("- ·"), iar numele trebuie să fie între ghilimele duble.

De exemplu, având în vedere următorul borcan:

Fișierul index ar arăta astfel:

1.5. Indexul stratului

Fișierul index de straturi poate fi furnizat în BOOT-INF/layer.idx. Oferă o listă de straturi și părțile borcanului care ar trebui să fie conținute în ele. Straturile sunt scrise în ordinea în care trebuie adăugate la imaginea Docker/OCI. Numele straturilor sunt scrise ca șiruri citate prefixate cu liniuță ("- ·") și cu un sufix punct (":"). Conținutul stratului este fie un nume de fișier, fie un director scris ca un șir citat prefixat de spațiu spațiu liniuță ("·· - ·"). Un nume de director se termină cu /, un nume de fișier nu. Când se utilizează un nume de director înseamnă că toate fișierele din acel director se află în același strat.

Un exemplu tipic de index de straturi ar fi:

2. Clasa „JarFile” a Spring Boot

Clasa de bază utilizată pentru a suporta încărcarea borcanelor imbricate este org.springframework.boot.loader.jar.JarFile. Vă permite să încărcați conținutul jar dintr-un fișier jar standard sau din date cu borcan copil imbricate. La prima încărcare, locația fiecărui JarEntry este mapată la un decalaj de fișier fizic al borcanului exterior, așa cum se arată în următorul exemplu:

Exemplul precedent arată cum clasa A. poate fi găsită în/BOOT-INF/classes în myapp.jar la poziția 0063. B.class din borcanul imbricat poate fi de fapt găsit în myapp.jar la poziția 3452, iar C.class este la poziția 3980 .

Înarmat cu aceste informații, putem încărca intrări specifice imbricate căutând partea corespunzătoare a borcanului exterior. Nu trebuie să despachetăm arhiva și nu trebuie să citim toate datele de intrare în memorie.

2.1. Compatibilitate cu „JarFile” Java standard

Spring Boot Loader se străduiește să rămână compatibil cu codul și bibliotecile existente. org.springframework.boot.loader.jar.JarFile se extinde de la java.util.jar.JarFile și ar trebui să funcționeze ca înlocuitor. Metoda getURL () returnează o adresă URL care deschide o conexiune compatibilă cu java.net.JurURLConnection și poate fi utilizată cu URL’sClassLoader Java .

3. Lansarea borcanelor executabile

Clasa org.springframework.boot.loader.Launcher este o clasă specială bootstrap care este utilizată ca punct de intrare principal al unui jar executabil. Este actuala clasă principală din fișierul dvs. jar și este utilizată pentru a configura un URLClassLoader adecvat și, în cele din urmă, pentru a apela metoda main.

Există trei subclase de lansare (JarLauncher, WarLauncher și PropertiesLauncher). Scopul lor este de a încărca resurse (fișiere .class și așa mai departe) din fișiere jar imbricate sau fișiere de război în directoare (spre deosebire de cele explicite din clasa). În cazul JarLauncher și WarLauncher, căile imbricate sunt fixate. JarLauncher arată în BOOT-INF/lib /, iar WarLauncher arată în WEB-INF/lib/și WEB-INF/lib-provided /. Puteți adăuga borcane suplimentare în acele locații dacă doriți mai multe. PropertiesLauncher arată în mod implicit în BOOT-INF/lib/în arhiva aplicației dvs. Puteți adăuga locații suplimentare setând o variabilă de mediu numită LOADER_PATH sau loader.path în loader.properties (care este o listă separată prin virgule de directoare, arhive sau directoare din arhive).

3.1. Launcher Manifest

Trebuie să specificați un Launcher adecvat ca atribut Main-Class al META-INF/MANIFEST.MF. Clasa reală pe care doriți să o lansați (adică clasa care conține o metodă principală) ar trebui specificată în atributul Start-Class.

Următorul exemplu arată un MANIFEST.MF tipic pentru un fișier jar executabil:

Pentru un fișier de război, ar fi după cum urmează:

4. Caracteristici PropertiesLauncher

PropertiesLauncher are câteva caracteristici speciale care pot fi activate cu proprietăți externe (proprietăți de sistem, variabile de mediu, intrări de manifest sau loader.properties). Următorul tabel descrie aceste proprietăți:

Classpath separate prin virgulă, cum ar fi lib, $/app/lib. Intrările anterioare au prioritate, cum ar fi o cale -classpath regulată pe linia de comandă javac.

Folosit pentru a rezolva căile relative din loader.path. De exemplu, dat loader.path = lib, atunci $/lib este o locație classpath (împreună cu toate fișierele jar din acel director). Această proprietate este, de asemenea, utilizată pentru a localiza un fișier loader.properties, ca în exemplul următor/opt/app. .

Argumente implicite pentru metoda principală (spațiu separat).

Numele clasei principale de lansat (de exemplu, com.app.Application).

Numele fișierului de proprietăți (de exemplu, lansator). Valoarea implicită este încărcătorul .

Calea către fișierul de proprietăți (de exemplu, classpath: loader.properties). Valoarea implicită este loader.properties .

Semnalizator boolean pentru a indica faptul că toate proprietățile ar trebui adăugate la proprietățile sistemului. Valoarea implicită este falsă .

Când este specificat ca variabile de mediu sau intrări de manifest, trebuie utilizate următoarele nume:

Următoarele reguli se aplică pentru lucrul cu PropertiesLauncher:

loader.properties este căutat în loader.home, apoi în rădăcina classpath și apoi în classpath:/BOOT-INF/classes. Este utilizată prima locație în care există un fișier cu acel nume.

loader.home este locația directorului unui fișier de proprietăți suplimentar (suprascriind valoarea implicită) numai atunci când loader.config.location nu este specificat.

loader.path poate conține directoare (care sunt scanate recursiv pentru fișierele jar și zip), căi de arhivare, un director dintr-o arhivă care este scanat pentru fișiere jar (de exemplu, dependencies.jar!/lib), sau comportamentul JVM implicit al modelelor wildcard ). Căile de arhivare pot fi relative la loader.home sau oriunde în sistemul de fișiere cu un jar: file: prefix.

loader.path (dacă este gol) implicit la BOOT-INF/lib (adică un director local sau unul imbricat dacă rulează dintr-o arhivă). Din acest motiv, PropertiesLauncher se comportă la fel ca JarLauncher atunci când nu este furnizată nicio configurație suplimentară.

loader.path nu poate fi utilizat pentru a configura locația loader.properties (calea de clasă utilizată pentru a căuta aceasta din urmă este calea de clasă JVM la lansarea PropertiesLauncher).

Înlocuirea substituentului se face din variabilele de sistem și de mediu plus proprietățile fișierului în sine pe toate valorile înainte de utilizare.

Ordinea de căutare a proprietăților (în cazul în care are sens să privim în mai multe locuri) sunt variabilele de mediu, proprietățile sistemului, loader.properties, manifestul de arhivă explodat și manifestul de arhivă.

5. Restricții de borcan executabile

Trebuie să luați în considerare următoarele restricții atunci când lucrați cu o aplicație ambalată Spring Boot Loader:

Comprimare intrare zip: ZipEntry pentru un borcan imbricat trebuie salvat utilizând metoda ZipEntry.STORED. Acest lucru este necesar pentru a putea căuta direct către conținutul individual din borcanul imbricat. Conținutul fișierului jar imbricat în sine poate fi în continuare comprimat, la fel ca orice alte intrări din borcanul exterior.

System classLoader: aplicațiile lansate ar trebui să utilizeze Thread.getContextClassLoader () la încărcarea claselor (majoritatea bibliotecilor și cadrelor o fac în mod implicit). Încercarea de a încărca clasele de jar imbricate cu ClassLoader.getSystemClassLoader () nu reușește. java.util.Logging folosește întotdeauna sistemul de încărcare a claselor. Din acest motiv, ar trebui să luați în considerare o implementare de înregistrare diferită.

6. Soluții alternative pentru un singur borcan

Dacă restricțiile precedente înseamnă că nu puteți utiliza Spring Boot Loader, luați în considerare următoarele alternative: