0
# JAR and Resource Management
1
2
Low-level JAR file manipulation and resource handling for OSGi bundles, providing fine-grained control over bundle contents.
3
4
## Capabilities
5
6
### Jar
7
8
Represents a JAR file with OSGi-specific operations for reading, writing, and manipulating bundle contents.
9
10
```java { .api }
11
/**
12
* Represents a JAR file with OSGi-specific operations
13
*/
14
public class Jar implements Closeable {
15
/** Create empty JAR */
16
public Jar(String name);
17
18
/** Create JAR from file */
19
public Jar(File file) throws IOException;
20
21
/** Create JAR from input stream */
22
public Jar(String name, InputStream in) throws IOException;
23
24
/** Add resource to JAR */
25
public void putResource(String path, Resource resource);
26
27
/** Get resource from JAR */
28
public Resource getResource(String path);
29
30
/** Remove resource from JAR */
31
public void remove(String path);
32
33
/** Write JAR to file */
34
public void write(File file) throws Exception;
35
36
/** Write JAR to output stream */
37
public void write(OutputStream out) throws IOException;
38
39
/** Get JAR manifest */
40
public Manifest getManifest() throws Exception;
41
42
/** Set JAR manifest */
43
public void setManifest(Manifest manifest);
44
45
/** Get bundle symbolic name from manifest */
46
public String getBsn();
47
48
/** Get bundle version from manifest */
49
public String getVersion();
50
51
/** Get all resource paths */
52
public Set<String> getResources();
53
54
/** Get resources matching pattern */
55
public Map<String, Resource> getResources(String pattern);
56
57
/** Get directories in JAR */
58
public Set<String> getDirectories();
59
60
/** Get JAR name */
61
public String getName();
62
63
/** Set JAR name */
64
public void setName(String name);
65
66
/** Get last modified time */
67
public long lastModified();
68
69
/** Close and clean up resources */
70
public void close();
71
}
72
```
73
74
**Usage Examples:**
75
76
```java
77
import aQute.bnd.osgi.Jar;
78
import aQute.bnd.osgi.Resource;
79
import java.util.jar.Manifest;
80
81
// Create and populate JAR
82
Jar jar = new Jar("mybundle");
83
84
// Set manifest
85
Manifest manifest = new Manifest();
86
manifest.getMainAttributes().putValue("Bundle-SymbolicName", "com.example.mybundle");
87
manifest.getMainAttributes().putValue("Bundle-Version", "1.0.0");
88
jar.setManifest(manifest);
89
90
// Add resources
91
jar.putResource("com/example/MyClass.class",
92
new FileResource(new File("target/classes/com/example/MyClass.class")));
93
jar.putResource("META-INF/MANIFEST.MF",
94
new ManifestResource(manifest));
95
96
// Write to file
97
jar.write(new File("mybundle.jar"));
98
jar.close();
99
100
// Read existing JAR
101
Jar existingJar = new Jar(new File("existing.jar"));
102
System.out.println("Bundle: " + existingJar.getBsn() + " v" + existingJar.getVersion());
103
104
// List all resources
105
for (String path : existingJar.getResources()) {
106
System.out.println("Resource: " + path);
107
}
108
109
existingJar.close();
110
```
111
112
### Resource
113
114
Interface representing a resource within a JAR file, providing access to content and metadata.
115
116
```java { .api }
117
/**
118
* Represents a resource in a JAR file
119
*/
120
public interface Resource extends Closeable {
121
/** Open input stream to read resource content */
122
public InputStream openInputStream() throws IOException;
123
124
/** Write resource content to output stream */
125
public void write(OutputStream out) throws Exception;
126
127
/** Get last modified time */
128
public long lastModified();
129
130
/** Set extra data associated with resource */
131
public void setExtra(String extra);
132
133
/** Get extra data */
134
public String getExtra();
135
136
/** Get resource size */
137
public long size() throws Exception;
138
139
/** Close resource and clean up */
140
public void close();
141
}
142
```
143
144
### Common Resource Implementations
145
146
Standard resource implementations for different content types.
147
148
```java { .api }
149
/**
150
* Resource backed by a file
151
*/
152
public class FileResource implements Resource {
153
public FileResource(File file);
154
public File getFile();
155
}
156
157
/**
158
* Resource with string content
159
*/
160
public class EmbeddedResource implements Resource {
161
public EmbeddedResource(byte[] data, long lastModified);
162
public EmbeddedResource(String data, long lastModified);
163
public byte[] getData();
164
}
165
166
/**
167
* Resource backed by URL
168
*/
169
public class URLResource implements Resource {
170
public URLResource(URL url);
171
public URL getURL();
172
}
173
174
/**
175
* Resource representing a JAR manifest
176
*/
177
public class ManifestResource implements Resource {
178
public ManifestResource(Manifest manifest);
179
public Manifest getManifest();
180
}
181
182
/**
183
* Resource from ZIP entry
184
*/
185
public class ZipResource implements Resource {
186
public ZipResource(ZipFile zip, ZipEntry entry);
187
public ZipEntry getEntry();
188
}
189
```
190
191
**Resource Usage Examples:**
192
193
```java
194
import aQute.bnd.osgi.*;
195
196
// Working with different resource types
197
Jar jar = new Jar("example");
198
199
// File resource
200
jar.putResource("config/app.properties",
201
new FileResource(new File("src/main/resources/app.properties")));
202
203
// String resource
204
String xmlContent = "<?xml version=\"1.0\"?><config></config>";
205
jar.putResource("META-INF/config.xml",
206
new EmbeddedResource(xmlContent, System.currentTimeMillis()));
207
208
// URL resource (from classpath)
209
URL resourceUrl = getClass().getResource("/template.txt");
210
jar.putResource("templates/default.txt",
211
new URLResource(resourceUrl));
212
213
// Read resource content
214
Resource configResource = jar.getResource("config/app.properties");
215
if (configResource != null) {
216
try (InputStream in = configResource.openInputStream()) {
217
Properties props = new Properties();
218
props.load(in);
219
System.out.println("Loaded " + props.size() + " properties");
220
}
221
}
222
223
jar.close();
224
```
225
226
### JAR Manipulation Utilities
227
228
Advanced JAR manipulation and analysis utilities.
229
230
```java { .api }
231
/**
232
* Utilities for JAR analysis and manipulation
233
*/
234
public class JarUtils {
235
/** Copy JAR with filtering */
236
public static void copy(Jar source, Jar dest, String pattern);
237
238
/** Merge multiple JARs */
239
public static Jar merge(Jar... jars) throws IOException;
240
241
/** Extract JAR to directory */
242
public static void extract(Jar jar, File targetDir) throws IOException;
243
244
/** Create JAR from directory */
245
public static Jar create(File sourceDir) throws IOException;
246
247
/** Compare JAR contents */
248
public static boolean equals(Jar jar1, Jar jar2);
249
250
/** Get JAR checksum */
251
public static String checksum(Jar jar) throws Exception;
252
}
253
```
254
255
### Bundle Information
256
257
Classes for extracting and working with OSGi bundle metadata.
258
259
```java { .api }
260
/**
261
* Bundle information extracted from manifest
262
*/
263
public class BundleInfo {
264
public String getSymbolicName();
265
public Version getVersion();
266
public String getName();
267
public String getDescription();
268
public String getVendor();
269
public List<String> getExportedPackages();
270
public List<String> getImportedPackages();
271
public List<String> getRequiredBundles();
272
public boolean isFragment();
273
public String getFragmentHost();
274
}
275
276
/**
277
* Utility for extracting bundle information
278
*/
279
public class BundleInfoReader {
280
/** Read bundle info from JAR */
281
public static BundleInfo read(Jar jar) throws Exception;
282
283
/** Read bundle info from file */
284
public static BundleInfo read(File bundleFile) throws Exception;
285
286
/** Read bundle info from manifest */
287
public static BundleInfo read(Manifest manifest);
288
}
289
```
290
291
**Complete JAR Processing Example:**
292
293
```java
294
import aQute.bnd.osgi.*;
295
import java.util.jar.Manifest;
296
297
// Complete JAR processing workflow
298
try {
299
// Create new bundle JAR
300
Jar bundle = new Jar("com.example.mybundle");
301
302
// Create manifest
303
Manifest manifest = new Manifest();
304
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
305
manifest.getMainAttributes().putValue("Bundle-ManifestVersion", "2");
306
manifest.getMainAttributes().putValue("Bundle-SymbolicName", "com.example.mybundle");
307
manifest.getMainAttributes().putValue("Bundle-Version", "1.0.0");
308
manifest.getMainAttributes().putValue("Bundle-Name", "My Example Bundle");
309
manifest.getMainAttributes().putValue("Export-Package", "com.example.api;version=\"1.0\"");
310
manifest.getMainAttributes().putValue("Import-Package", "org.osgi.framework;version=\"[1.8,2)\"");
311
312
bundle.setManifest(manifest);
313
314
// Add class files
315
File classesDir = new File("target/classes");
316
if (classesDir.exists()) {
317
addDirectory(bundle, classesDir, "");
318
}
319
320
// Add resources
321
bundle.putResource("META-INF/spring/bundle-context.xml",
322
new FileResource(new File("src/main/resources/bundle-context.xml")));
323
324
// Write bundle
325
File outputFile = new File("target/mybundle-1.0.0.jar");
326
bundle.write(outputFile);
327
328
System.out.println("Created bundle: " + outputFile);
329
System.out.println("Bundle-SymbolicName: " + bundle.getBsn());
330
System.out.println("Bundle-Version: " + bundle.getVersion());
331
System.out.println("Resources: " + bundle.getResources().size());
332
333
bundle.close();
334
335
} catch (Exception e) {
336
System.err.println("Failed to create bundle: " + e.getMessage());
337
e.printStackTrace();
338
}
339
340
// Helper method to add directory recursively
341
private static void addDirectory(Jar jar, File dir, String path) throws IOException {
342
for (File file : dir.listFiles()) {
343
String filePath = path.isEmpty() ? file.getName() : path + "/" + file.getName();
344
if (file.isDirectory()) {
345
addDirectory(jar, file, filePath);
346
} else {
347
jar.putResource(filePath, new FileResource(file));
348
}
349
}
350
}
351
```