Bridge adapter enabling Apache Commons Logging applications to route calls through Log4j 2
npx @tessl/cli install tessl/maven-org-apache-logging-log4j--log4j-jcl@2.25.00
# Apache Log4j Commons Logging Bridge
1
2
A bridge adapter that enables applications using Apache Commons Logging (JCL) to seamlessly route their logging calls through Log4j 2 as the underlying logging implementation. It acts as a compatibility layer that implements the Commons Logging API while delegating actual logging operations to Log4j 2's high-performance logging framework.
3
4
## Package Information
5
6
- **Package Name**: log4j-jcl
7
- **Package Type**: Maven
8
- **Group ID**: org.apache.logging.log4j
9
- **Language**: Java
10
- **Installation**: Add Maven dependency:
11
```xml
12
<dependency>
13
<groupId>org.apache.logging.log4j</groupId>
14
<artifactId>log4j-jcl</artifactId>
15
<version>2.25.1</version>
16
</dependency>
17
```
18
19
## Core Imports
20
21
```java
22
import org.apache.commons.logging.Log;
23
import org.apache.commons.logging.LogFactory;
24
```
25
26
## Basic Usage
27
28
```java
29
import org.apache.commons.logging.Log;
30
import org.apache.commons.logging.LogFactory;
31
32
public class MyClass {
33
private static final Log logger = LogFactory.getLog(MyClass.class);
34
35
public void doSomething() {
36
// Standard Commons Logging API - automatically routed through Log4j 2
37
logger.info("Starting operation");
38
39
try {
40
// Your application logic here
41
if (logger.isDebugEnabled()) {
42
logger.debug("Processing data with detailed info");
43
}
44
45
// All Commons Logging levels supported
46
logger.trace("Detailed execution trace");
47
logger.warn("Warning about potential issue");
48
49
} catch (Exception e) {
50
logger.error("Operation failed", e);
51
logger.fatal("Critical system error occurred", e);
52
}
53
54
logger.info("Operation completed");
55
}
56
57
// Factory can also create loggers by name
58
public void alternativeLoggerCreation() {
59
Log namedLogger = LogFactory.getLog("com.example.specific.Logger");
60
namedLogger.info("Using named logger instance");
61
}
62
}
63
```
64
65
## Architecture
66
67
The bridge uses a three-layer architecture:
68
69
- **LogFactoryImpl**: Main factory implementing Commons Logging's LogFactory interface, discovered automatically via service provider mechanism
70
- **LogAdapter**: Internal adapter managing logger instances and contexts with class loader awareness
71
- **Log4jLog**: Commons Logging Log implementation wrapping Log4j 2's ExtendedLogger with full level mapping
72
73
This design allows existing Commons Logging applications to benefit from Log4j 2's advanced features like asynchronous logging, structured logging, and extensive configuration options without requiring code changes.
74
75
## Capabilities
76
77
### Log Factory Implementation
78
79
The main entry point providing Commons Logging factory functionality with automatic Log4j 2 integration.
80
81
```java { .api }
82
public class LogFactoryImpl extends LogFactory {
83
/**
84
* Gets a logger instance by name
85
* @param name Logger name
86
* @return Log instance backed by Log4j 2
87
* @throws LogConfigurationException If logger creation fails
88
*/
89
public Log getInstance(String name) throws LogConfigurationException;
90
91
/**
92
* Gets a logger instance by class
93
* @param clazz Class to use for logger name (raw type usage for Commons Logging compatibility)
94
* @return Log instance backed by Log4j 2
95
* @throws LogConfigurationException If logger creation fails
96
*/
97
public Log getInstance(Class clazz) throws LogConfigurationException;
98
99
/**
100
* Gets factory attribute value
101
* @param name Attribute name
102
* @return Attribute value or null if not found
103
*/
104
public Object getAttribute(String name);
105
106
/**
107
* Gets all factory attribute names
108
* @return Array of attribute names
109
*/
110
public String[] getAttributeNames();
111
112
/**
113
* Sets factory attribute
114
* @param name Attribute name
115
* @param value Attribute value (null removes attribute)
116
*/
117
public void setAttribute(String name, Object value);
118
119
/**
120
* Removes factory attribute
121
* @param name Attribute name to remove
122
*/
123
public void removeAttribute(String name);
124
125
/**
126
* Releases all logger resources
127
* Clears logger wrappers but underlying Log4j 2 loggers remain managed by their context
128
*/
129
public void release();
130
}
131
```
132
133
### Logger Adapter
134
135
Internal adapter managing logger instances and contexts with class loader awareness.
136
137
```java { .api }
138
public class LogAdapter extends AbstractLoggerAdapter<Log> {
139
/**
140
* Creates a new Log instance for the given name and context
141
* @param name Logger name
142
* @param context Logger context from Log4j 2
143
* @return Log4jLog instance wrapping Log4j 2 logger
144
*/
145
protected Log newLogger(String name, LoggerContext context);
146
147
/**
148
* Gets the appropriate logger context
149
* Determines context based on class loader dependency configuration
150
* @return LoggerContext for current calling context
151
*/
152
protected LoggerContext getContext();
153
}
154
```
155
156
### Commons Logging Log Implementation
157
158
Full implementation of Commons Logging's Log interface with Log4j 2 backing.
159
160
```java { .api }
161
public class Log4jLog implements Log, Serializable {
162
/**
163
* Creates a Log4jLog wrapping the given ExtendedLogger
164
* Uses internal FQCN for proper caller location tracking
165
* @param logger The Log4j 2 ExtendedLogger to wrap
166
*/
167
public Log4jLog(ExtendedLogger logger);
168
169
/**
170
* Check if TRACE level logging is enabled
171
* @return true if TRACE level is enabled
172
*/
173
public boolean isTraceEnabled();
174
175
/**
176
* Check if DEBUG level logging is enabled
177
* @return true if DEBUG level is enabled
178
*/
179
public boolean isDebugEnabled();
180
181
/**
182
* Check if INFO level logging is enabled
183
* @return true if INFO level is enabled
184
*/
185
public boolean isInfoEnabled();
186
187
/**
188
* Check if WARN level logging is enabled
189
* @return true if WARN level is enabled
190
*/
191
public boolean isWarnEnabled();
192
193
/**
194
* Check if ERROR level logging is enabled
195
* @return true if ERROR level is enabled
196
*/
197
public boolean isErrorEnabled();
198
199
/**
200
* Check if FATAL level logging is enabled
201
* @return true if FATAL level is enabled
202
*/
203
public boolean isFatalEnabled();
204
205
/**
206
* Log message at TRACE level
207
* @param message Message object to log
208
*/
209
public void trace(Object message);
210
211
/**
212
* Log message at TRACE level with exception
213
* @param message Message object to log
214
* @param t Exception to log
215
*/
216
public void trace(Object message, Throwable t);
217
218
/**
219
* Log message at DEBUG level
220
* @param message Message object to log
221
*/
222
public void debug(Object message);
223
224
/**
225
* Log message at DEBUG level with exception
226
* @param message Message object to log
227
* @param t Exception to log
228
*/
229
public void debug(Object message, Throwable t);
230
231
/**
232
* Log message at INFO level
233
* @param message Message object to log
234
*/
235
public void info(Object message);
236
237
/**
238
* Log message at INFO level with exception
239
* @param message Message object to log
240
* @param t Exception to log
241
*/
242
public void info(Object message, Throwable t);
243
244
/**
245
* Log message at WARN level
246
* @param message Message object to log
247
*/
248
public void warn(Object message);
249
250
/**
251
* Log message at WARN level with exception
252
* @param message Message object to log
253
* @param t Exception to log
254
*/
255
public void warn(Object message, Throwable t);
256
257
/**
258
* Log message at ERROR level
259
* @param message Message object to log
260
*/
261
public void error(Object message);
262
263
/**
264
* Log message at ERROR level with exception
265
* @param message Message object to log
266
* @param t Exception to log
267
*/
268
public void error(Object message, Throwable t);
269
270
/**
271
* Log message at FATAL level
272
* @param message Message object to log
273
*/
274
public void fatal(Object message);
275
276
/**
277
* Log message at FATAL level with exception
278
* @param message Message object to log
279
* @param t Exception to log
280
*/
281
public void fatal(Object message, Throwable t);
282
}
283
```
284
285
## Types
286
287
```java { .api }
288
/**
289
* Exception thrown for logging configuration problems
290
* Defined in commons-logging library
291
*/
292
public class LogConfigurationException extends RuntimeException {
293
// From org.apache.commons.logging.LogConfigurationException
294
}
295
296
/**
297
* Abstract logger adapter base class from Log4j 2 SPI
298
* Defined in log4j-api library
299
*/
300
public abstract class AbstractLoggerAdapter<T> {
301
// From org.apache.logging.log4j.spi.AbstractLoggerAdapter
302
// Provides logger adapter functionality with generic type support
303
}
304
305
/**
306
* Logger context interface from Log4j 2 SPI
307
* Defined in log4j-api library
308
*/
309
public interface LoggerContext {
310
// From org.apache.logging.log4j.spi.LoggerContext
311
// Provides logger context management functionality
312
}
313
314
/**
315
* Extended logger interface from Log4j 2 API
316
* Defined in log4j-api library
317
*/
318
public interface ExtendedLogger {
319
// From org.apache.logging.log4j.spi.ExtendedLogger
320
// Provides advanced logging functionality beyond basic Logger interface
321
}
322
```
323
324
## Integration Details
325
326
### Automatic Discovery
327
328
The bridge is automatically discovered by Commons Logging through the Java service provider mechanism:
329
- Service file: `META-INF/services/org.apache.commons.logging.LogFactory`
330
- Implementation: `org.apache.logging.log4j.jcl.LogFactoryImpl`
331
332
### Level Mapping
333
334
Commons Logging levels map directly to Log4j 2 levels:
335
336
| Commons Logging | Log4j 2 |
337
|----------------|---------|
338
| TRACE | TRACE |
339
| DEBUG | DEBUG |
340
| INFO | INFO |
341
| WARN | WARN |
342
| ERROR | ERROR |
343
| FATAL | FATAL |
344
345
### Dependencies
346
347
**Required Runtime Dependencies:**
348
- `org.apache.logging.log4j:log4j-api` - Log4j 2 API
349
- `commons-logging:commons-logging` - Apache Commons Logging API
350
351
**Optional Dependencies:**
352
- `org.apache.logging.log4j:log4j-core` - For full Log4j 2 implementation features
353
- `org.apache.logging.log4j:log4j-slf4j-impl` - If also bridging SLF4J logging
354
355
### Thread Safety
356
357
All components are thread-safe:
358
- Factory attributes stored in `ConcurrentHashMap`
359
- Logger management uses thread-safe Log4j 2 components
360
- Logger instances delegate to thread-safe Log4j 2 loggers
361
362
### Serialization Support
363
364
- `Log4jLog` implements `Serializable` with `serialVersionUID = 1L`
365
- Logger instances can be safely serialized and deserialized
366
- Proper caller location tracking maintained through internal FQCN constant
367
368
### Configuration
369
370
The bridge uses Log4j 2's configuration system. Configure Log4j 2 normally using:
371
- `log4j2.xml` configuration files
372
- System properties
373
- Programmatic configuration
374
375
Commons Logging applications will automatically use the configured Log4j 2 settings without code changes.