-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Replace log4j with slf4j #977
base: master
Are you sure you want to change the base?
[WIP] Replace log4j with slf4j #977
Conversation
Perform elementary conversion of log4j constructs with slf4j. It also replaces the usage of `fatal` with `error` methods and calls `toString` on objects passed by parameter to logger methods. This commit doesn't touch classes into: - Applications - Archives - Tests It also leaves frameworks not built by Maven intact.
AjaxRemoteLogging component doesn't support the log level `fatal` anymore. In contrast, `trace` was added as a log level option.
I'm not happy with this change. Anyway, I removed this option because it's impossible to change the log level using slf4j in runtime without knowing the underlying log library being used.
The log level was set as `Level.WARN` in the `WOHelperFunctionDeclarationParser`, `WOHelperFunctionHTMLParser` and `WOHelperFunctionTagRegistry` classes. This configuration was removed because it's impossible to set the log level in runtime using slf4j.
BTW, I'm focusing on issues 2.2 and 2.3 now. |
Regarding points 1.4 and 1.5 I wonder if it would be useful to have an abstraction with different implementations for supported loggers, maybe even as different frameworks. I would then move the remaining log4j depended classes to the corresponding framework. |
That's certainly an option worth pursuing. I can add support for log4j1 to keep the same behavior, and we may add implementation for other frameworks in the future. |
The `ERD2WPage` component uses `log4j` Nested Diagnostic Context (NDC) statements, which `slf4j` doesn't support. For this reason, we're migrating to Mapped Diagnostic Context (MDC) statements.
I found two unmodifiable classes that require log4j. The
Since we can't modify some of these classes, I'm willing to copy the The |
The `com.webobjects.appserver._private.WOCGIFormValues.Encoder` class of the `JavaWebObjects` framework creates a `org.apache.log4j.Logger`. Since we can't modify this class, I had to copy it into the `ERExtensions` framework—to supersede the original class—and reference the `org.slf4j.Logger` interface.
Doesn't slf4j have stub implementations for those cases (e.g. log4j-over-slf4j.jar)? If the really used logging framework is anything other than log4j (or reload4j), than putting log4j-over-slf4.jar in the path should solve the problem. |
I did not know about the Since we're talking about only one class, I still prefer the decompilation course of action (even though it hurts my soul profoundly). It's one less thing to explain/document/break and one less step in the migration path. Anyway, I'd like to hear from others about their take on this subject. |
…rt multiple logging libraries The `ERXLogger` class now implements the `org.slf4j.Logger` interface instead of extending the `org.apache.log4j.Logger` class. It's not connected to `log4j` in any sense anymore. Add a new `ERXNSLogSlf4jBridge` class to make the bridge between `NSLog` and `slf4j`. Move the re-initialization of `log4j` console appenders to the new class `ERXLoggingUtilities` and execute this code only if `log4j` is the chosen `sfl4j` binding. Support setting the log level using distinct log libraries via the `ERXLoggingUtilities` class. Side-effects: - Remove the ability to configure a custom subclass of `ERXLogger` using the `er.extensions.erxloggerclass` property. - Remove the `er.extensions.logging.ERXLogger.Factory` class since it implements `org.apache.log4j.spi.LoggerFactory`. Thus, it's not possible to define a custom `ERXLogger` factory anymore.
I feel your pain, but I support this approach. It's not like this is the first time Wonder will be decompiling a legacy class—we're already doing this in several other places. Meanwhile, I had almost forgotten an issue that @renebock just brought up in #971: JavaXML.framework, among other travesties of software engineering, has classes baked in from an ancient version of Log4j 1.x. We're going to have to address this somehow as well, aren't we? |
Yes, you're correct. It's not an easy fix, though. To be honest, I haven't given this subject much thought. I never bothered about the What alternatives do we have? |
I'll check if we could use the Bill of Materials (BOM) to group all WebObjects and Wonder dependencies, excluding the |
It looks like a wonder-bom may solve the |
I would go for org.apache.commons.io.IOUtils which has a copy function with the same signature. |
Replace `org.apache.log4j.lf5.util.StreamUtils` with `org.apache.commons.io.IOUtils.copy` on `ImageMagickCommandlineMetadataParser`.
…mode Now, Wonder can change the log level of a few logging libraries: log4j 1, reload4j, log4j 2, and logback.
The wonder-bom groups all WebObjects and Wonder dependencies into one pom. It also excludes `JavaXML` as a transitive dependency of the `JavaWebObjects` dependency. `JavaXML` has also been removed as a direct dependency of all frameworks.
I pushed a few changes to this branch:
I've deployed version 7.4-SNAPSHOT to the WOCommunity repository containing all the changes from this pull request. The best way to test it is to import the wonder-bom <dependencyManagement>
<dependencies>
<dependency>
<groupId>wonder</groupId>
<artifactId>wonder-bom</artifactId>
<version>7.4-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> See this guide for more information. You can then remove the version of your WebObjects and Wonder dependencies. The wonder-bom will also exclude the What you can expect from this version:
You must configure your log messages according to the selected logging library since there's no default log configuration for other log libraries besides log4j 1. I'm still not happy with the resulting wonder-bom because it includes other dependencies in addition to the WebObjects and Wonder dependencies. I'm working on it. Please, give it a try and let me know your first impressions. |
The removal of the JavaXML transitive dependency from both applications caused NoClassDefError exceptions. This commit adds the Apache Xerces as an explicit dependency to both projects.
Hi @hprange: are there an plans to merge this PR into master? |
@hprange wrote:
I fear that the the resources of the current snapshot don't match the code in the pull request. e.g the repositories version of ERXGenericRecord imports After excluding log4j 1.x in my pom.xml dependencies, I got some very nasty compiler null pointer exceptions :-( |
@renebock I've been using the changes from this PR in a large-scale app for a while without problems. IMHO, if we put the discussion about dropping the Ant build support aside, this pull request is ready to be merged.
That's correct. GitHub Actions deploy a new SNAPSHOT every time there's a new commit into master. |
I would really appreciate if the 'dropping ant build support' will be split into an PR dedicated to this task. |
Regarding topics 2.6 and 2.8: shouldn't these classes not be moved into separate frameworks (eg. ERXLog4jExtensions, ERXLog4j2Extensions, ERXLogbackLoggingExtensions) in order to keep ERXExtensions clean from dedicated logger implementations? |
As promised, I'm replacing the log4j dependency with slf4j in Wonder. It's still a work in progress. Anyway, I'd like to share my findings and hear from the community.
1. What has been done so far?
org.apache.log4j.Logger
were replaced byorg.slf4j.Logger
.fatal
log messages were replaced byerror
.AjaxRemoteLogging
component doesn't support the log levelfatal
anymore. In contrast,trace
was added as an option.WOHelperFunctionDeclarationParser
,WOHelperFunctionHTMLParser
andWOHelperFunctionTagRegistry
classes.slf4j
doesn't support configuring the log level in runtime.ERD2WDebugFlags.toggleD2WInfo
andERDDebuggingHelp.toggleRuleTracing
methods. I'm not entirely satisfied with this change.2. Open Issues
✅ERXApplication
re-inits the log4j console appenders, so we get logging intoWOOutputPath
again. Does anybody remember what issue this code fixes?Wonder has an✅ERXLogger
class that works as a facade. I'm still investigating if we can replace it with the slf4jLogger
class.Wonder has an✅ERXNSLogLog4jBridge
class that works as a bridge betweenNSLog
andlog4j
. We can create anERXNSLogSlf4jBridge
class to make the bridge betweenNSLog
andslf4j
.The✅ERD2WPage
component onERDirectToWeb
uses theorg.apache.log4j.NDC
class. We should migrate it to use theorg.slf4j.MDC
class instead.The✅ImageMagickCommandlineMetadataParser
class onERAttachment
usesorg.apache.log4j.lf5.util.StreamUtils
. We can replace it by a more general dependency (commons-io?).ERXDirectAction.log4jAction
is an action that opens theERXLog4JConfiguration
component and allows to change log4j configuration in runtime. I'm thinking of leaving it as it is. The application will throw aClassNotFoundException
if somebody uses it and the log4j library is not in the classpath. Any thoughts?StandaloneRunner
class of theERSelenium
useslog4j
extensively to configure the logging behavior of the selenium runner. I'm thinking of leaving it as it is.ERXThreadStorageAppender
extendsorg.apache.log4j.AppenderSkeleton
.ERXPatternLayout
extendsorg.apache.log4j.PatternLayout
.ERXMailAppender
extendsorg.apache.log4j.AppenderSkeleton
.ERXConsoleAppender
extendsorg.apache.log4j.ConsoleAppender
.ERXEOFAppender
extendsorg.apache.log4j.AppenderSkeleton
.Copy the✅WOCGIFormValues
class into theERExtensions
framework and change it to reference theorg.slf4j.Logger
interface.Applications like wotaskd and JavaMonitor still use✅log4j
. We could replace it withlog4j2
.3. Open Questions
Considerations
I would appreciate it if you could look at the proposed changes and help me with the open issues. Your thoughts are always welcome!