This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts-site.git
The following commit(s) were added to refs/heads/main by this push:
new f9560de68 docs: replace the removed XWork logging layer with Log4j2 on
the Logging page (#320)
f9560de68 is described below
commit f9560de68b4719d98bba483b97667543e10f9366
Author: Lukasz Lenart <[email protected]>
AuthorDate: Mon Aug 3 16:19:42 2026 +0200
docs: replace the removed XWork logging layer with Log4j2 on the Logging
page (#320)
* docs: replace the removed XWork logging layer with Log4j2 on the Logging
page
The page documented com.opensymphony.xwork2.util.logging.LoggerFactory,
extending LoggerFactory, and -Dxwork.loggerFactory. That layer was
deprecated
in Struts 2.5 and removed in 6.0.0: org/apache/struts2 (com/opensymphony)
xwork2/util/logging has 12 files at STRUTS_2_5_33 and none from STRUTS_6_0_0
onwards, and no source in the current tags reads xwork.loggerFactory. The
examples did not compile and the system property was silently ignored.
Describe how logging actually works instead: Log4j2 via
log4j-api/log4j-core,
configured with log4j2.xml, with the log4j-jcl / log4j-slf4j-impl bridges
covering third-party libraries.
Co-Authored-By: Claude Opus 5 <[email protected]>
* build: ignore vendor/ so bundler's default install path stays out of git
`bundle install --path vendor/bundle` — the standard way to install this
site's gems without touching the system gem dir — drops ~29 gems into
vendor/, which then shows up as untracked on every branch. .bundle and
Gemfile.lock are already ignored; vendor/ was the missing one.
Co-Authored-By: Claude Opus 5 <[email protected]>
---------
Co-authored-by: Claude Opus 5 <[email protected]>
---
.gitignore | 1 +
source/core-developers/logging.md | 122 +++++++-------------------------------
2 files changed, 22 insertions(+), 101 deletions(-)
diff --git a/.gitignore b/.gitignore
index 2899b5fa9..a339f00a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ content
.java-version
target
.bundle
+vendor/
.jekyll-metadata
.jekyll-cache
_site/
diff --git a/source/core-developers/logging.md
b/source/core-developers/logging.md
index 711872a75..220f41524 100644
--- a/source/core-developers/logging.md
+++ b/source/core-developers/logging.md
@@ -10,39 +10,36 @@ parent:
## Logging support
-> As from Struts 2.5 version, the logging layer is deprecated and Struts uses
Log4j2
-> The logging layer will be dropped with the next major release.
+Struts logs through [Log4j2](https://logging.apache.org/log4j/2.x/). The
`struts2-core` artifact declares `log4j-api`
+and `log4j-core`, and configuration is plain Log4j2 configuration — a
`log4j2.xml` on the classpath, typically under
+`src/main/resources`. See [Debugging
Struts](../getting-started/debugging-struts) for an example configuration and
the
+framework packages worth raising to `DEBUG`.
-> Note: support for a custom logging layer has been removed in Struts 6.x
+The pluggable logging layer that XWork used to provide —
`com.opensymphony.xwork2.util.logging.LoggerFactory`, the
+`xwork.loggerFactory` system property and the Commons Logging / SLF4J / JDK
Logger delegates — was deprecated in
+Struts 2.5 and **removed in Struts 6.0.0**. There is no framework-level
logging abstraction to configure any more, and
+setting `-Dxwork.loggerFactory` has no effect.
+{:.alert .alert-warning}
-XWork provides its own layer to support logging - it allows to use many
different implementations.
-
-Currently XWork provides support for the following libraries (in that order
base on classpath discovery):
-
-- Commons Logging
-- [SLF4J](http://www.slf4j.org/)
-- [Log4j2](http://logging.apache.org/log4j/2.x/)
-- JDK Logger
+The Log4j2 bridges for third-party libraries (`log4j-jcl` for Commons Logging,
`log4j-slf4j-impl` for SLF4J) are a
+separate concern and remain available. They route logging emitted by
transitive dependencies into Log4j2.
## Usage
-To use given type of library add it as a Maven dependency or drop into
WEB-INF/lib folder. XWork LoggerFactory class will
-use given logging provider if available.
-
-To add logging to your application simply declare a Logger as follow:
+Declare a Log4j2 logger in your own classes as usual:
```java
-import com.opensymphony.xwork2.util.logging.Logger;
-import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
public class MyAction {
- private static final Logger LOG = LoggerFactory.getLogger(MyAction.class);
+ private static final Logger LOG = LogManager.getLogger(MyAction.class);
private String userName;
public String execute() {
- LOG.debug("MyAction executed with UserName [#0]", userName);
+ LOG.debug("MyAction executed with UserName [{}]", userName);
return "success";
}
@@ -51,87 +48,10 @@ public class MyAction {
}
```
-## Implementing my own factory
-
-You plug in your own logging solution, simple extend LoggerFactory class and
provide a delegate which implements Logger
-interface, like below:
-
-**JdkLoggerFactory which adds support for JDK logging**
-
-```java
-import com.opensymphony.xwork2.util.logging.Logger;
-import com.opensymphony.xwork2.util.logging.LoggerFactory;
-
-/**
- * Creates jdk loggers
- */
-public class JdkLoggerFactory extends LoggerFactory {
-
- @Override
- protected Logger getLoggerImpl(Class<?> cls) {
- return new
JdkLogger(java.util.logging.Logger.getLogger(cls.getName()));
- }
-
- @Override
- protected Logger getLoggerImpl(String name) {
- return new JdkLogger(java.util.logging.Logger.getLogger(name));
- }
-}
-```
-
-**JdkLogger is a wrapper around java.util.logging.Logger and implements Logger
interface**
-
-```java
-import com.opensymphony.xwork2.util.logging.Logger;
-import com.opensymphony.xwork2.util.logging.LoggerUtils;
-
-import java.util.logging.Level;
-
-/**
- * Delegates to jdk logger. Maps fatal to Level.SEVERE along with error.
- */
-public class JdkLogger implements Logger {
-
- private java.util.logging.Logger log;
-
- public JdkLogger(java.util.logging.Logger log) {
- this.log = log;
- }
-
- public void error(String msg, String... args) {
- log.log(Level.SEVERE, LoggerUtils.format(msg, args));
- }
-
- public void error(String msg, Throwable ex, String... args) {
- log.log(Level.SEVERE, LoggerUtils.format(msg, args), ex);
- }
-
- ...
-}
-```
-
-Check [the source
code](http://struts.apache.org/struts-core/apidocs/org/apache/struts2/util/logging/package-summary)
-to see more details.
-
-## Defining which factory to use
-
-Now you must tell XWork/Struts2 to use your implementation, just define system
property like below:
-
-```
--Dxwork.loggerFactory=com.demo.MyLoggerFactory
-```
-
-you can use the same to explicit tell the framework which implementation to
use and don't depend on class discovery, eg.:
+Note the `{}` placeholder — Log4j2 parameterised messages, not the `#0` syntax
used by the removed XWork logger.
-```
--Dxwork.loggerFactory=com.opensymphony.xwork2.util.logging.slf4j.Slf4jLoggerFactory
-```
-
-or
-
-```
--Dxwork.loggerFactory=com.opensymphony.xwork2.util.logging.log4j2.Log4j2LoggerFactory
-```
+## Routing Struts logging elsewhere
-will enable Slf4j or Log4j2 even if there is commons-logging on classpath
available (commons-logging is the first
-LoggerFactory to look for).
+Because Struts logs against the Log4j2 API rather than its own abstraction,
redirecting its output is a Log4j2
+concern: either configure Log4j2 appenders as you need them, or put a bridge
to your logging backend of choice on the
+classpath in place of `log4j-core`. Nothing needs to be declared in
`struts.xml`.