0
# ClassLoader Management
1
2
The Jetty EE10 WebApp module provides specialized ClassLoader implementations that offer isolation, visibility controls, and performance optimizations for web applications. The system includes WebAppClassLoader for general use and CachingWebAppClassLoader for improved performance.
3
4
## WebAppClassLoader
5
6
The primary ClassLoader implementation for web applications with customizable class loading behavior.
7
8
```java { .api }
9
public class WebAppClassLoader extends URLClassLoader
10
implements ClassVisibilityChecker {
11
12
// Constructors
13
public WebAppClassLoader(Context context);
14
public WebAppClassLoader(ClassLoader parent, Context context);
15
16
// Naming and identification
17
public String getName();
18
public void setName(String name);
19
public Context getContext();
20
21
// Classpath management
22
public void addClassPath(Resource resource);
23
public void addClassPath(String classPathList) throws IOException;
24
public void addJars(Resource libs);
25
26
// Resource loading
27
public Enumeration<URL> getResources(String name) throws IOException;
28
public URL getResource(String name);
29
30
// Security and permissions
31
public PermissionCollection getPermissions(CodeSource cs);
32
33
// Class transformation
34
public void addTransformer(ClassFileTransformer transformer);
35
public boolean removeTransformer(ClassFileTransformer transformer);
36
37
// Visibility controls
38
public boolean isProtectedClass(Class<?> clazz);
39
public boolean isHiddenClass(Class<?> clazz);
40
41
// Resource management
42
public void close() throws IOException;
43
44
// Static utility methods
45
public static <T> T runWithServerClassAccess(
46
PrivilegedExceptionAction<T> action) throws Exception;
47
}
48
```
49
50
## CachingWebAppClassLoader
51
52
An optimized ClassLoader that caches resource lookup results for improved performance.
53
54
```java { .api }
55
public class CachingWebAppClassLoader extends WebAppClassLoader {
56
57
// Constructors
58
public CachingWebAppClassLoader(Context context) throws IOException;
59
public CachingWebAppClassLoader(ClassLoader parent, Context context)
60
throws IOException;
61
62
// Overridden methods with caching
63
public URL getResource(String name);
64
public Class<?> loadClass(String name) throws ClassNotFoundException;
65
66
// Cache management
67
public void clearCache();
68
}
69
```
70
71
## Context Interface
72
73
The Context interface provides services that the ClassLoader needs from its WebAppContext.
74
75
```java { .api }
76
public interface Context {
77
// Resource creation
78
Resource newResource(String urlOrPath) throws IOException;
79
80
// Security
81
PermissionCollection getPermissions();
82
83
// Loading behavior
84
boolean isParentLoaderPriority();
85
List<Resource> getExtraClasspath();
86
87
// Visibility controls
88
boolean isHiddenResource(String name, URL parentUrl);
89
boolean isProtectedResource(String name, URL webappUrl);
90
}
91
```
92
93
## ClassVisibilityChecker Interface
94
95
Interface for checking class visibility in web applications.
96
97
```java { .api }
98
public interface ClassVisibilityChecker {
99
boolean isProtectedClass(Class<?> clazz);
100
boolean isHiddenClass(Class<?> clazz);
101
}
102
```
103
104
## Usage Examples
105
106
### Basic WebAppClassLoader Setup
107
108
```java
109
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
110
import org.eclipse.jetty.ee10.webapp.WebAppContext;
111
112
// Create ClassLoader with WebAppContext as context
113
WebAppContext context = new WebAppContext();
114
WebAppClassLoader classLoader = new WebAppClassLoader(context);
115
classLoader.setName("MyAppClassLoader");
116
117
// Add to context
118
context.setClassLoader(classLoader);
119
```
120
121
### Custom Classpath Configuration
122
123
```java
124
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
125
import org.eclipse.jetty.util.resource.ResourceFactory;
126
127
WebAppContext context = new WebAppContext();
128
WebAppClassLoader classLoader = new WebAppClassLoader(context);
129
130
// Add individual JAR files
131
ResourceFactory rf = ResourceFactory.of(context);
132
classLoader.addClassPath(rf.newResource("/path/to/lib/custom.jar"));
133
classLoader.addClassPath(rf.newResource("/path/to/classes/"));
134
135
// Add multiple paths at once
136
classLoader.addClassPath("/path/to/lib1.jar:/path/to/lib2.jar");
137
138
// Add all JARs from a directory
139
classLoader.addJars(rf.newResource("/path/to/lib/"));
140
```
141
142
### Caching ClassLoader for Performance
143
144
```java
145
import org.eclipse.jetty.ee10.webapp.CachingWebAppClassLoader;
146
147
WebAppContext context = new WebAppContext();
148
try {
149
CachingWebAppClassLoader classLoader =
150
new CachingWebAppClassLoader(context);
151
152
context.setClassLoader(classLoader);
153
154
// Later, clear cache if needed
155
classLoader.clearCache();
156
157
} catch (IOException e) {
158
// Handle initialization error
159
}
160
```
161
162
### Class Visibility Controls
163
164
```java
165
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
166
import org.eclipse.jetty.util.ClassMatcher;
167
168
WebAppContext context = new WebAppContext();
169
170
// Configure protected classes (visible to webapp)
171
ClassMatcher protectedClasses = new ClassMatcher();
172
protectedClasses.add("org.eclipse.jetty.http.");
173
protectedClasses.add("jakarta.servlet.");
174
context.setProtectedClassMatcher(protectedClasses);
175
176
// Configure hidden classes (not visible to webapp)
177
ClassMatcher hiddenClasses = new ClassMatcher();
178
hiddenClasses.add("org.eclipse.jetty.util.log.");
179
hiddenClasses.add("org.eclipse.jetty.webapp.");
180
context.setHiddenClassMatcher(hiddenClasses);
181
182
WebAppClassLoader classLoader = new WebAppClassLoader(context);
183
184
// Check visibility
185
Class<?> servletClass = Class.forName("jakarta.servlet.Servlet");
186
boolean isProtected = classLoader.isProtectedClass(servletClass);
187
boolean isHidden = classLoader.isHiddenClass(servletClass);
188
```
189
190
### Class Transformation
191
192
```java
193
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
194
import java.lang.instrument.ClassFileTransformer;
195
196
WebAppClassLoader classLoader = new WebAppClassLoader(context);
197
198
// Add a transformer for bytecode modification
199
ClassFileTransformer transformer = new ClassFileTransformer() {
200
@Override
201
public byte[] transform(ClassLoader loader, String className,
202
Class<?> classBeingRedefined,
203
ProtectionDomain protectionDomain,
204
byte[] classfileBuffer) {
205
// Transform bytecode here
206
return classfileBuffer; // Return modified or original bytecode
207
}
208
};
209
210
classLoader.addTransformer(transformer);
211
212
// Later remove if needed
213
boolean removed = classLoader.removeTransformer(transformer);
214
```
215
216
### Server Class Access
217
218
```java
219
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
220
import java.security.PrivilegedExceptionAction;
221
222
// Execute code with access to server classes
223
String result = WebAppClassLoader.runWithServerClassAccess(
224
new PrivilegedExceptionAction<String>() {
225
@Override
226
public String run() throws Exception {
227
// Code here can access server classes normally hidden from webapps
228
return "Server operation completed";
229
}
230
}
231
);
232
```
233
234
### Resource Loading with Parent-First Strategy
235
236
```java
237
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
238
239
WebAppContext context = new WebAppContext();
240
context.setParentLoaderPriority(true); // Parent-first loading
241
242
WebAppClassLoader classLoader = new WebAppClassLoader(context);
243
244
// This will check parent classloader first
245
URL resource = classLoader.getResource("config.properties");
246
Enumeration<URL> resources = classLoader.getResources("META-INF/services/myservice");
247
```
248
249
### Custom Context Implementation
250
251
```java
252
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
253
254
public class CustomContext implements WebAppClassLoader.Context {
255
256
@Override
257
public Resource newResource(String urlOrPath) throws IOException {
258
// Custom resource creation logic
259
return ResourceFactory.root().newResource(urlOrPath);
260
}
261
262
@Override
263
public PermissionCollection getPermissions() {
264
// Return custom permissions
265
return new Permissions();
266
}
267
268
@Override
269
public boolean isParentLoaderPriority() {
270
return false; // Child-first loading
271
}
272
273
@Override
274
public List<Resource> getExtraClasspath() {
275
// Return additional classpath resources
276
return new ArrayList<>();
277
}
278
279
@Override
280
public boolean isHiddenResource(String name, URL parentUrl) {
281
// Custom logic for hiding resources from webapp
282
return name.startsWith("META-INF/internal/");
283
}
284
285
@Override
286
public boolean isProtectedResource(String name, URL webappUrl) {
287
// Custom logic for protecting resources
288
return name.startsWith("WEB-INF/");
289
}
290
}
291
292
// Use custom context
293
CustomContext context = new CustomContext();
294
WebAppClassLoader classLoader = new WebAppClassLoader(context);
295
```
296
297
## Error Handling
298
299
ClassLoader operations can encounter various exceptions:
300
301
- `IOException` - I/O errors when accessing JAR files or resources
302
- `ClassNotFoundException` - Class cannot be found or loaded
303
- `SecurityException` - Security manager denies access
304
- `IllegalArgumentException` - Invalid classpath entries
305
306
Common error scenarios:
307
- Corrupted or inaccessible JAR files in classpath
308
- Circular class loading dependencies
309
- Missing required classes or resources
310
- Permission issues when accessing files
311
- Invalid URL formats in classpath entries
312
313
## Performance Considerations
314
315
### When to Use CachingWebAppClassLoader
316
317
- Applications with frequent resource lookups
318
- Large classpaths with many JAR files
319
- Development environments with hot reloading
320
- Applications that repeatedly access the same resources
321
322
### Memory Management
323
324
```java
325
// Properly close ClassLoader to free resources
326
try (WebAppClassLoader classLoader = new WebAppClassLoader(context)) {
327
// Use classloader
328
} // Automatically closed
329
330
// Or manually close
331
WebAppClassLoader classLoader = new WebAppClassLoader(context);
332
try {
333
// Use classloader
334
} finally {
335
classLoader.close();
336
}
337
```
338
339
### Cache Management for CachingWebAppClassLoader
340
341
```java
342
CachingWebAppClassLoader classLoader = new CachingWebAppClassLoader(context);
343
344
// Clear cache when needed (e.g., after hot deployment)
345
classLoader.clearCache();
346
347
// Monitor cache effectiveness through logs or JMX
348
```