or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Spring JCL

1

2

Spring JCL (Java Commons Logging) is Spring's variant of the Apache Commons Logging API that provides a minimized and optimized logging bridge specifically designed for Spring Framework's internal logging needs. It offers special support for Log4J 2, SLF4J, and java.util.logging with automatic detection of available logging frameworks in the classpath.

3

4

## Package Information

5

6

- **Package Name**: org.springframework:spring-jcl

7

- **Package Type**: Maven

8

- **Language**: Java

9

- **Installation**:

10

```xml

11

<dependency>

12

<groupId>org.springframework</groupId>

13

<artifactId>spring-jcl</artifactId>

14

<version>6.2.8</version>

15

</dependency>

16

```

17

18

Gradle:

19

```gradle

20

implementation 'org.springframework:spring-jcl:6.2.8'

21

```

22

23

## Core Imports

24

25

```java

26

import org.apache.commons.logging.Log;

27

import org.apache.commons.logging.LogFactory;

28

```

29

30

For implementation classes (optional):

31

```java

32

import org.apache.commons.logging.LogFactoryService;

33

import org.apache.commons.logging.impl.NoOpLog;

34

import org.apache.commons.logging.impl.SimpleLog;

35

```

36

37

Internal classes (not typically imported directly):

38

```java

39

import org.apache.commons.logging.LogAdapter;

40

```

41

42

## Basic Usage

43

44

```java

45

import org.apache.commons.logging.Log;

46

import org.apache.commons.logging.LogFactory;

47

48

public class MyService {

49

private static final Log logger = LogFactory.getLog(MyService.class);

50

51

public void doSomething() {

52

logger.info("Starting operation");

53

54

try {

55

// Your code here

56

logger.debug("Operation in progress");

57

} catch (Exception e) {

58

logger.error("Operation failed", e);

59

throw e;

60

}

61

62

logger.info("Operation completed");

63

}

64

}

65

```

66

67

## Architecture

68

69

Spring JCL is built around several key components:

70

71

- **LogFactory**: Main entry point providing static factory methods for logger creation

72

- **Log Interface**: Commons Logging compatible interface with six logging levels (trace, debug, info, warn, error, fatal)

73

- **LogAdapter**: Internal adapter that automatically detects available logging frameworks (Log4J 2, SLF4J, java.util.logging)

74

- **Framework Implementations**: Bridge implementations for Log4J 2, SLF4J (with location awareness), and java.util.logging

75

- **Compatibility Layer**: Deprecated classes maintaining binary compatibility with Apache Commons Logging

76

77

## Capabilities

78

79

### Logger Factory

80

81

Creates logger instances with automatic framework detection and optimization.

82

83

```java { .api }

84

/**

85

* Main factory class for obtaining Log instances with automatic adapter detection

86

*/

87

public abstract class LogFactory {

88

/**

89

* Convenience method to return a named logger

90

* @param clazz containing Class from which a log name will be derived

91

* @return Log instance for the class

92

*/

93

public static Log getLog(Class<?> clazz);

94

95

/**

96

* Convenience method to return a named logger

97

* @param name logical name of the Log instance to be returned

98

* @return Log instance for the name

99

*/

100

public static Log getLog(String name);

101

}

102

```

103

104

**Deprecated Methods** (for compatibility):

105

```java { .api }

106

/**

107

* @deprecated in favor of getLog(Class)/getLog(String)

108

*/

109

@Deprecated

110

public static LogFactory getFactory();

111

112

/**

113

* @deprecated in favor of getLog(Class)

114

*/

115

@Deprecated

116

public Log getInstance(Class<?> clazz);

117

118

/**

119

* @deprecated in favor of getLog(String)

120

*/

121

@Deprecated

122

public Log getInstance(String name);

123

124

/**

125

* @deprecated no-op method for compatibility

126

*/

127

@Deprecated

128

public static void release(ClassLoader classLoader);

129

130

/**

131

* @deprecated no-op method for compatibility

132

*/

133

@Deprecated

134

public static void releaseAll();

135

136

/**

137

* @deprecated utility method for object identification

138

* Returns string representation with class name and identity hash code

139

*/

140

@Deprecated

141

public static String objectId(Object o);

142

143

// Abstract methods (for subclass implementation)

144

/**

145

* @deprecated abstract method for attribute access

146

*/

147

@Deprecated

148

public abstract Object getAttribute(String name);

149

150

/**

151

* @deprecated abstract method for attribute name retrieval

152

*/

153

@Deprecated

154

public abstract String[] getAttributeNames();

155

156

/**

157

* @deprecated abstract method for attribute removal

158

*/

159

@Deprecated

160

public abstract void removeAttribute(String name);

161

162

/**

163

* @deprecated abstract method for attribute setting

164

*/

165

@Deprecated

166

public abstract void setAttribute(String name, Object value);

167

168

/**

169

* @deprecated abstract method for factory release

170

*/

171

@Deprecated

172

public abstract void release();

173

```

174

175

### Logging Interface

176

177

Core logging interface providing six logging levels with conditional checks for performance.

178

179

```java { .api }

180

/**

181

* A simple logging interface abstracting logging APIs

182

*/

183

public interface Log {

184

// Level check methods (for performance optimization)

185

boolean isFatalEnabled();

186

boolean isErrorEnabled();

187

boolean isWarnEnabled();

188

boolean isInfoEnabled();

189

boolean isDebugEnabled();

190

boolean isTraceEnabled();

191

192

// Fatal level logging

193

void fatal(Object message);

194

void fatal(Object message, Throwable t);

195

196

// Error level logging

197

void error(Object message);

198

void error(Object message, Throwable t);

199

200

// Warn level logging

201

void warn(Object message);

202

void warn(Object message, Throwable t);

203

204

// Info level logging

205

void info(Object message);

206

void info(Object message, Throwable t);

207

208

// Debug level logging

209

void debug(Object message);

210

void debug(Object message, Throwable t);

211

212

// Trace level logging

213

void trace(Object message);

214

void trace(Object message, Throwable t);

215

}

216

```

217

218

**Usage Examples:**

219

220

```java

221

// Performance-optimized logging

222

if (logger.isDebugEnabled()) {

223

logger.debug("Processing user: " + user.getName() + " with ID: " + user.getId());

224

}

225

226

// Exception logging

227

try {

228

processData();

229

} catch (DataProcessingException e) {

230

logger.error("Failed to process data for user: " + userId, e);

231

throw e;

232

}

233

234

// Different logging levels

235

logger.trace("Entering method with params: " + params);

236

logger.debug("Intermediate calculation result: " + result);

237

logger.info("User " + username + " logged in successfully");

238

logger.warn("Deprecated API usage detected in class: " + className);

239

logger.error("Database connection failed", connectionException);

240

logger.fatal("System is shutting down due to critical error", criticalError);

241

```

242

243

### Service Implementation

244

245

Fallback service implementation for META-INF service discovery compatibility when commons-logging.jar is accidentally on classpath.

246

247

```java { .api }

248

/**

249

* @deprecated since it is only meant to be used in fallback scenario when commons-logging.jar is accidentally on classpath

250

*/

251

@Deprecated

252

public class LogFactoryService extends LogFactory {

253

/**

254

* Constructor that prints compatibility warning about commons-logging.jar conflicts

255

* Prints message: "Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts"

256

*/

257

public LogFactoryService();

258

259

/**

260

* Get logger instance for class - delegates to LogAdapter.createLog()

261

* @param clazz containing Class from which a log name will be derived

262

* @return Log instance for the class

263

*/

264

public Log getInstance(Class<?> clazz);

265

266

/**

267

* Get logger instance by name - delegates to LogAdapter.createLog()

268

* @param name logical name of the Log instance to be returned

269

* @return Log instance for the name

270

*/

271

public Log getInstance(String name);

272

273

// Attribute management methods (for compatibility) - uses ConcurrentHashMap

274

/**

275

* Set attribute value (null values remove the attribute)

276

*/

277

public void setAttribute(String name, Object value);

278

279

/**

280

* Remove attribute by name

281

*/

282

public void removeAttribute(String name);

283

284

/**

285

* Get attribute value

286

* @return attribute value or null if not found

287

*/

288

public Object getAttribute(String name);

289

290

/**

291

* Get all attribute names

292

* @return array of attribute names

293

*/

294

public String[] getAttributeNames();

295

296

/**

297

* Release resources - no-op method for compatibility

298

*/

299

public void release();

300

}

301

```

302

303

### Implementation Classes

304

305

Basic logger implementations for specific use cases.

306

307

```java { .api }

308

/**

309

* Trivial implementation of Log that throws away all messages

310

*/

311

public class NoOpLog implements Log, Serializable {

312

public NoOpLog();

313

public NoOpLog(String name);

314

315

// All methods return false for level checks and are no-op for logging methods

316

}

317

318

/**

319

* @deprecated in spring-jcl (effectively equivalent to NoOpLog)

320

*/

321

@Deprecated

322

public class SimpleLog extends NoOpLog {

323

/**

324

* Constructor that prints deprecation warning

325

* Prints message: "SimpleLog is deprecated and equivalent to NoOpLog in spring-jcl. Use a standard LogFactory.getLog(Class/String) call instead."

326

* @param name logger name

327

*/

328

public SimpleLog(String name);

329

}

330

```

331

332

## Types

333

334

```java { .api }

335

/**

336

* Main logging interface with six levels: trace, debug, info, warn, error, fatal

337

*/

338

public interface Log {

339

// See Logging Interface section above for complete method signatures

340

}

341

342

/**

343

* Abstract factory class for obtaining Log instances

344

*/

345

public abstract class LogFactory {

346

// See Logger Factory section above for complete method signatures

347

}

348

349

/**

350

* Service implementation extending LogFactory for compatibility

351

* @deprecated only for fallback compatibility scenarios

352

*/

353

@Deprecated

354

public class LogFactoryService extends LogFactory {

355

// See Service Implementation section above for complete method signatures

356

}

357

358

/**

359

* No-operation logger implementation

360

*/

361

public class NoOpLog implements Log, java.io.Serializable {

362

// See Implementation Classes section above for complete method signatures

363

}

364

365

/**

366

* @deprecated Simple logger implementation (equivalent to NoOpLog)

367

*/

368

@Deprecated

369

public class SimpleLog extends NoOpLog {

370

// See Implementation Classes section above for complete method signatures

371

}

372

```

373

374

### LogAdapter (Internal)

375

376

Internal adapter class that handles automatic logging framework detection and logger creation.

377

378

```java { .api }

379

/**

380

* Internal adapter class for framework detection and logger creation

381

* This class is not part of the public API but is referenced by LogFactory

382

*/

383

final class LogAdapter {

384

/**

385

* Create Log instance using detected logging framework

386

* @param name the logger name

387

* @return Log instance using the best available logging framework

388

*/

389

public static Log createLog(String name);

390

}

391

```

392

393

**Internal Implementation Classes:**

394

395

```java { .api }

396

// Log4J 2 implementation (when Log4J 2 is available)

397

private static class Log4jLog implements Log, Serializable {

398

public Log4jLog(String name);

399

// Implements all Log interface methods with Log4J 2 ExtendedLogger

400

}

401

402

// SLF4J implementation (when SLF4J is available)

403

private static class Slf4jLog<T extends Logger> implements Log, Serializable {

404

public Slf4jLog(T logger);

405

// Implements all Log interface methods with SLF4J Logger

406

}

407

408

// SLF4J with location awareness (when LocationAwareLogger is available)

409

private static class Slf4jLocationAwareLog extends Slf4jLog<LocationAwareLogger> {

410

public Slf4jLocationAwareLog(LocationAwareLogger logger);

411

// Implements all Log interface methods with location-aware SLF4J logging

412

}

413

414

// Java Util Logging implementation (fallback)

415

private static class JavaUtilLog implements Log, Serializable {

416

public JavaUtilLog(String name);

417

// Implements all Log interface methods with java.util.logging.Logger

418

}

419

```

420

421

**Note:** These internal classes are implementation details and should not be used directly. Use `LogFactory.getLog()` methods instead.

422

423

## Framework Detection

424

425

Spring JCL automatically detects and prioritizes logging frameworks through the LogAdapter class in this order:

426

427

1. **Log4J 2 with SLF4J Bridge Detection** - If both `org.apache.logging.log4j.spi.ExtendedLogger` and `org.apache.logging.slf4j.SLF4JProvider` are detected along with `org.slf4j.spi.LocationAwareLogger`, it uses SLF4J with location awareness to avoid the log4j-to-slf4j bridge conflict

428

2. **Log4J 2 Direct** - Uses `org.apache.logging.log4j.spi.ExtendedLogger` directly when available (and no SLF4J bridge detected)

429

3. **SLF4J with Location Awareness** - Uses `org.slf4j.spi.LocationAwareLogger` when available

430

4. **SLF4J Basic** - Uses `org.slf4j.Logger` when available

431

5. **Java Util Logging** - Falls back to `java.util.logging.Logger` as default

432

433

The detection is automatic and requires no configuration. The LogAdapter uses Class.forName() to detect available logging frameworks on the classpath.

434

435

## Error Handling

436

437

Spring JCL handles logging framework detection failures gracefully:

438

439

- **ClassNotFoundException**: Framework not available during Class.forName() check, tries next option

440

- **NoClassDefFoundError**: Framework partially available during Class.forName() check, tries next option

441

- **Any Throwable during detection**: Catches all exceptions during Class.forName() and continues to next framework

442

- **Service Discovery Issues**: LogFactoryService prints warning about commons-logging.jar conflicts and continues

443

- **SimpleLog Usage**: Prints deprecation warning and continues with NoOpLog behavior

444

445

No exceptions are thrown during logger creation - the system always provides a working logger instance, falling back to java.util.logging if all other frameworks fail.

446

447

## Best Practices

448

449

- **Framework Usage**: Spring JCL is designed for Spring Framework internal logging. For application code, prefer direct use of Log4J 2, SLF4J, or java.util.logging

450

- **Performance**: Use level check methods (`isDebugEnabled()`, etc.) before expensive string operations

451

- **Class-based Loggers**: Prefer `LogFactory.getLog(Class.class)` over string names for better IDE support

452

- **Exception Logging**: Always include the exception as the second parameter for proper stack trace logging

453

- **Avoid Deprecated Methods**: Use `LogFactory.getLog()` instead of deprecated `getInstance()` methods