0
# Library Management
1
2
Comprehensive system for handling dependency libraries including scope classification, coordinate tracking, inclusion/exclusion logic, and integration with build tools. The library management system ensures proper dependency resolution and packaging for executable archives.
3
4
## Capabilities
5
6
### Library Representation
7
8
Core class representing a single library dependency with metadata and packaging instructions.
9
10
```java { .api }
11
public class Library {
12
/**
13
* Create a library with basic file and scope information.
14
*
15
* @param file the library JAR file
16
* @param scope the library scope (COMPILE, RUNTIME, PROVIDED, CUSTOM)
17
*/
18
public Library(File file, LibraryScope scope);
19
20
/**
21
* Create a library with complete metadata and packaging options.
22
*
23
* @param name the library name (derived from file if null)
24
* @param file the library JAR file
25
* @param scope the library scope
26
* @param coordinates the Maven/Gradle coordinates
27
* @param unpackRequired whether the library needs to be unpacked
28
* @param local whether this is a local/project library
29
* @param included whether to include this library in the archive
30
*/
31
public Library(String name, File file, LibraryScope scope, LibraryCoordinates coordinates,
32
boolean unpackRequired, boolean local, boolean included);
33
34
/**
35
* Get the library name (typically the JAR filename without extension).
36
*
37
* @return the library name
38
*/
39
public String getName();
40
41
/**
42
* Get the library file.
43
*
44
* @return the JAR file for this library
45
*/
46
public File getFile();
47
48
/**
49
* Get the library scope.
50
*
51
* @return the scope (COMPILE, RUNTIME, PROVIDED, CUSTOM)
52
*/
53
public LibraryScope getScope();
54
55
/**
56
* Get the library coordinates (group:artifact:version).
57
*
58
* @return the coordinates, or null if not available
59
*/
60
public LibraryCoordinates getCoordinates();
61
62
/**
63
* Check if this library requires unpacking.
64
* Some libraries need to be unpacked rather than included as nested JARs.
65
*
66
* @return true if unpacking is required
67
*/
68
public boolean isUnpackRequired();
69
70
/**
71
* Check if this is a local library (part of the project).
72
*
73
* @return true if this is a local/project library
74
*/
75
public boolean isLocal();
76
77
/**
78
* Check if this library should be included in the archive.
79
*
80
* @return true if the library should be included
81
*/
82
public boolean isIncluded();
83
}
84
```
85
86
### Library Collections
87
88
Interface for providing collections of libraries to the packaging process.
89
90
```java { .api }
91
public interface Libraries {
92
/**
93
* Process all libraries using the provided callback.
94
* The callback is invoked once for each library that should be included.
95
*
96
* @param callback the callback to process each library
97
* @throws IOException if library processing fails
98
*/
99
void doWithLibraries(LibraryCallback callback) throws IOException;
100
101
/**
102
* Empty libraries collection.
103
*/
104
Libraries NONE = callback -> {
105
// No libraries to process
106
};
107
}
108
```
109
110
### Library Processing
111
112
Callback interface for processing individual libraries during packaging.
113
114
```java { .api }
115
@FunctionalInterface
116
public interface LibraryCallback {
117
/**
118
* Process a single library.
119
* Called once for each library that should be included in the archive.
120
*
121
* @param library the library to process
122
* @throws IOException if library processing fails
123
*/
124
void library(Library library) throws IOException;
125
}
126
```
127
128
### Library Scopes
129
130
Interface defining the different scopes for library dependencies.
131
132
```java { .api }
133
public interface LibraryScope {
134
/**
135
* Compile-time and runtime dependency.
136
* Included in the final archive.
137
*/
138
LibraryScope COMPILE = /* implementation */;
139
140
/**
141
* Runtime-only dependency.
142
* Included in the final archive but not needed for compilation.
143
*/
144
LibraryScope RUNTIME = /* implementation */;
145
146
/**
147
* Provided by the runtime environment.
148
* Not included in the final archive.
149
*/
150
LibraryScope PROVIDED = /* implementation */;
151
152
/**
153
* Custom scope with user-defined behavior.
154
*/
155
LibraryScope CUSTOM = /* implementation */;
156
}
157
```
158
159
### Library Coordinates
160
161
Interface for Maven/Gradle artifact coordinates providing metadata about library origins.
162
163
```java { .api }
164
public interface LibraryCoordinates {
165
/**
166
* Get the group ID (Maven) or organization (Gradle).
167
*
168
* @return the group ID
169
*/
170
String getGroupId();
171
172
/**
173
* Get the artifact ID or module name.
174
*
175
* @return the artifact ID
176
*/
177
String getArtifactId();
178
179
/**
180
* Get the version string.
181
*
182
* @return the version
183
*/
184
String getVersion();
185
186
/**
187
* Create coordinates from individual components.
188
*
189
* @param groupId the group ID
190
* @param artifactId the artifact ID
191
* @param version the version
192
* @return new coordinates instance
193
*/
194
static LibraryCoordinates of(String groupId, String artifactId, String version);
195
196
/**
197
* Convert coordinates to standard notation string (group:artifact:version).
198
*
199
* @param coordinates the coordinates to convert
200
* @return the standard notation string
201
*/
202
static String toStandardNotationString(LibraryCoordinates coordinates);
203
}
204
```
205
206
### Default Coordinates Implementation
207
208
```java { .api }
209
public class DefaultLibraryCoordinates implements LibraryCoordinates {
210
/**
211
* Create coordinates with group, artifact, and version.
212
*
213
* @param groupId the group ID
214
* @param artifactId the artifact ID
215
* @param version the version
216
*/
217
public DefaultLibraryCoordinates(String groupId, String artifactId, String version);
218
}
219
```
220
221
### Special Library Types
222
223
```java { .api }
224
public class JarModeLibrary extends Library {
225
/**
226
* Special library for JAR mode support.
227
* Provides tools functionality for JAR introspection and manipulation.
228
*/
229
public static final JarModeLibrary TOOLS = /* implementation */;
230
}
231
```
232
233
## Usage Examples
234
235
### Basic Library Collection
236
237
```java
238
import org.springframework.boot.loader.tools.*;
239
import java.io.File;
240
import java.util.List;
241
242
// Create a simple library collection
243
List<File> libraryFiles = List.of(
244
new File("lib/spring-boot-3.2.0.jar"),
245
new File("lib/spring-context-6.0.0.jar"),
246
new File("lib/logback-classic-1.4.5.jar"),
247
new File("lib/jackson-core-2.15.0.jar")
248
);
249
250
Libraries libraries = callback -> {
251
for (File libFile : libraryFiles) {
252
// Determine scope based on naming convention
253
LibraryScope scope = libFile.getName().contains("test")
254
? LibraryScope.PROVIDED
255
: LibraryScope.COMPILE;
256
257
callback.library(new Library(libFile, scope));
258
}
259
};
260
261
// Use with repackager
262
Repackager repackager = new Repackager(new File("myapp.jar"));
263
repackager.repackage(libraries);
264
```
265
266
### Advanced Library Configuration
267
268
```java
269
import org.springframework.boot.loader.tools.*;
270
import java.io.File;
271
272
// Create libraries with full metadata
273
Libraries libraries = callback -> {
274
// Runtime dependency with coordinates
275
LibraryCoordinates springCoords = LibraryCoordinates.of(
276
"org.springframework", "spring-core", "6.0.0"
277
);
278
callback.library(new Library(
279
"spring-core-6.0.0.jar",
280
new File("lib/spring-core-6.0.0.jar"),
281
LibraryScope.RUNTIME,
282
springCoords,
283
false, // no unpacking required
284
false, // not local
285
true // include in archive
286
));
287
288
// Local project dependency that needs unpacking
289
callback.library(new Library(
290
"my-custom-lib.jar",
291
new File("build/libs/my-custom-lib.jar"),
292
LibraryScope.COMPILE,
293
LibraryCoordinates.of("com.example", "my-custom-lib", "1.0.0"),
294
true, // requires unpacking
295
true, // local library
296
true // include in archive
297
));
298
299
// Provided dependency (excluded from final archive)
300
callback.library(new Library(
301
"servlet-api.jar",
302
new File("provided/servlet-api.jar"),
303
LibraryScope.PROVIDED,
304
LibraryCoordinates.of("javax.servlet", "servlet-api", "3.1.0"),
305
false, // no unpacking needed
306
false, // not local
307
false // exclude from archive (provided by container)
308
));
309
};
310
```
311
312
### Gradle Integration Example
313
314
```java
315
import org.springframework.boot.loader.tools.*;
316
import java.io.File;
317
import java.util.Set;
318
319
// Example integration with Gradle dependency resolution
320
public class GradleLibraries implements Libraries {
321
private final Set<File> compileClasspath;
322
private final Set<File> runtimeClasspath;
323
private final Set<File> providedClasspath;
324
325
public GradleLibraries(Set<File> compileClasspath, Set<File> runtimeClasspath, Set<File> providedClasspath) {
326
this.compileClasspath = compileClasspath;
327
this.runtimeClasspath = runtimeClasspath;
328
this.providedClasspath = providedClasspath;
329
}
330
331
@Override
332
public void doWithLibraries(LibraryCallback callback) throws IOException {
333
// Process compile dependencies
334
for (File file : compileClasspath) {
335
callback.library(new Library(file, LibraryScope.COMPILE));
336
}
337
338
// Process runtime-only dependencies
339
for (File file : runtimeClasspath) {
340
if (!compileClasspath.contains(file)) {
341
callback.library(new Library(file, LibraryScope.RUNTIME));
342
}
343
}
344
345
// Process provided dependencies (marked as excluded)
346
for (File file : providedClasspath) {
347
callback.library(new Library(
348
file.getName(),
349
file,
350
LibraryScope.PROVIDED,
351
null, // no coordinates
352
false, false, false // exclude from archive
353
));
354
}
355
}
356
}
357
```
358
359
### Maven Integration Example
360
361
```java
362
import org.springframework.boot.loader.tools.*;
363
import java.io.File;
364
import java.util.List;
365
366
// Example integration with Maven dependency resolution
367
public class MavenLibraries implements Libraries {
368
private final List<MavenArtifact> artifacts;
369
370
public MavenLibraries(List<MavenArtifact> artifacts) {
371
this.artifacts = artifacts;
372
}
373
374
@Override
375
public void doWithLibraries(LibraryCallback callback) throws IOException {
376
for (MavenArtifact artifact : artifacts) {
377
LibraryScope scope = mapMavenScope(artifact.getScope());
378
LibraryCoordinates coords = LibraryCoordinates.of(
379
artifact.getGroupId(),
380
artifact.getArtifactId(),
381
artifact.getVersion()
382
);
383
384
boolean include = !LibraryScope.PROVIDED.equals(scope);
385
386
callback.library(new Library(
387
artifact.getFile().getName(),
388
artifact.getFile(),
389
scope,
390
coords,
391
artifact.requiresUnpacking(),
392
artifact.isLocal(),
393
include
394
));
395
}
396
}
397
398
private LibraryScope mapMavenScope(String mavenScope) {
399
switch (mavenScope) {
400
case "compile": return LibraryScope.COMPILE;
401
case "runtime": return LibraryScope.RUNTIME;
402
case "provided": return LibraryScope.PROVIDED;
403
case "test": return LibraryScope.PROVIDED; // exclude test deps
404
default: return LibraryScope.CUSTOM;
405
}
406
}
407
}
408
```
409
410
### Library Filtering and Transformation
411
412
```java
413
import org.springframework.boot.loader.tools.*;
414
import java.io.File;
415
import java.util.function.Predicate;
416
417
// Wrapper for filtering libraries
418
public class FilteredLibraries implements Libraries {
419
private final Libraries delegate;
420
private final Predicate<Library> filter;
421
422
public FilteredLibraries(Libraries delegate, Predicate<Library> filter) {
423
this.delegate = delegate;
424
this.filter = filter;
425
}
426
427
@Override
428
public void doWithLibraries(LibraryCallback callback) throws IOException {
429
delegate.doWithLibraries(library -> {
430
if (filter.test(library)) {
431
callback.library(library);
432
}
433
});
434
}
435
}
436
437
// Usage examples
438
Libraries allLibraries = /* ... */;
439
440
// Only include compile and runtime libraries
441
Libraries filtered = new FilteredLibraries(allLibraries, library ->
442
LibraryScope.COMPILE.equals(library.getScope()) ||
443
LibraryScope.RUNTIME.equals(library.getScope())
444
);
445
446
// Exclude snapshot versions
447
Libraries noSnapshots = new FilteredLibraries(allLibraries, library -> {
448
LibraryCoordinates coords = library.getCoordinates();
449
return coords == null || !coords.getVersion().contains("SNAPSHOT");
450
});
451
452
// Only local libraries
453
Libraries localOnly = new FilteredLibraries(allLibraries, Library::isLocal);
454
```
455
456
### Library Inspection
457
458
```java
459
import org.springframework.boot.loader.tools.*;
460
import java.io.IOException;
461
462
// Inspect libraries before packaging
463
public void inspectLibraries(Libraries libraries) throws IOException {
464
System.out.println("Library Analysis:");
465
System.out.println("==================");
466
467
libraries.doWithLibraries(library -> {
468
System.out.printf("Name: %s%n", library.getName());
469
System.out.printf(" File: %s%n", library.getFile().getAbsolutePath());
470
System.out.printf(" Scope: %s%n", library.getScope());
471
System.out.printf(" Size: %,d bytes%n", library.getFile().length());
472
System.out.printf(" Local: %s%n", library.isLocal());
473
System.out.printf(" Included: %s%n", library.isIncluded());
474
System.out.printf(" Unpack Required: %s%n", library.isUnpackRequired());
475
476
LibraryCoordinates coords = library.getCoordinates();
477
if (coords != null) {
478
System.out.printf(" Coordinates: %s%n",
479
LibraryCoordinates.toStandardNotationString(coords));
480
}
481
System.out.println();
482
});
483
}
484
```
485
486
### JAR Mode Libraries
487
488
```java
489
import org.springframework.boot.loader.tools.*;
490
491
// Include JAR mode tools for runtime introspection
492
Libraries librariesWithTools = callback -> {
493
// Add your regular libraries
494
// ... regular library processing ...
495
496
// Add JAR mode tools for runtime capabilities
497
callback.library(JarModeLibrary.TOOLS);
498
};
499
500
// Enable JAR mode in repackager
501
Repackager repackager = new Repackager(new File("myapp.jar"));
502
repackager.setIncludeRelevantJarModeJars(true);
503
repackager.repackage(librariesWithTools);
504
505
// The resulting JAR can be inspected at runtime:
506
// java -Djarmode=tools -jar myapp.jar
507
```
508
509
## Library Processing Pipeline
510
511
The library management system processes dependencies through these stages:
512
513
1. **Collection**: Libraries are gathered from build tools (Maven, Gradle) or custom sources
514
2. **Classification**: Each library is assigned a scope (COMPILE, RUNTIME, PROVIDED, CUSTOM)
515
3. **Metadata Extraction**: Coordinates and other metadata are collected
516
4. **Filtering**: Libraries are filtered based on inclusion rules and scope policies
517
5. **Location Determination**: The layout system determines where each library should be placed
518
6. **Packaging**: Libraries are written to the appropriate locations in the archive
519
520
This pipeline ensures that only necessary dependencies are included while maintaining proper classpath organization for runtime execution.