log4j "bridge" and the RootLogger class - log4j

We're trying to force an old vendor-provided Java-program (a JAR) to use log4j2, with the help of the log4j "bridge".
To do this, I:
Deleted all entries starting with org/apache/log4j/* from the vendor's JAR
Added the log4j-1.2-api-2.17.1.jar and the regular log4j-*-2.17.1.jar files to CLASSPATH
The program dies unable to find the org/apache/log4j/spi/RootLogger. Listing the contents of the bridge JAR, I find several classes under the org/apache/log4j/spi/, but the RootLogger is, indeed, missing.
How do I deal with this?

The newest version 2.17.2 of Log4j2 contains a couple of dozen of fixes to the Log4j 1.x bridge (cf. changelog).
Among them the org.apache.log4j.RootLogger class has been added to provide binary compatibility with Log4j 1.x.
Warning: many of the added classes are no-ops and just prevent ClassNotFoundExceptions as the one in your question.

Related

How are logger names defined in Log4j v1 properties configuration?

I'm attempting to convert Log4j v1 properties configuration into some form of Log4j v2 config, but the problem is that I don't know what I'm reading when I look at the v1 properties file. Very little documentation is available for Log4j v1 configuration. In particular, I've managed to infer over six months of work that standard (non-Root) loggers must have defined names. These names appear to be defined implicitly, but the documentation is utterly worthless, and I can't find any clear statement from the developers about how that implicit process works.
Of the following examples I've been able to pull from the Internet, which lines define the names of individual loggers, and which define other properties? Of the lines that define names, what are those names?
log4j.logger.org.apache.axis.utils=ERROR
log4j.logger.strike=DEBUG
log4j.logger.strike.textfiles=DEBUG
log4j.logger.org.krake.strike.trace=INFO
log4j.logger.org.medusa.orm.armadillo.Loader=DEBUG
log4j.logger.org.medusa.orm.armadillo.functions.ProcessBulkErrors=WARN
log4j.logger.org.medusa.orm.engine.Armadillo=INFO
log4j.logger.org.medusa.orm.armadillo.lib=INFO
log4j.logger.org.medusa.orm.armadillo.ORM2ExecutionContext=DEBUG
log4j.logger.org.medusa.orm.armadillo.lib.GetFieldValue=DEBUG
log4j.logger.org.medusa.orm.toolkit.ORMt2ORMx=DEBUG
log4j.logger.org.krake.box.abstraction.slidr.service.job.manager.Cpu=DEBUG
log4j.logger.org.krake.box.abstraction.slidr.service.job.manager.Block=DEBUG
log4j.logger.org.krake.box.abstraction.slidr.service.job.manager.SimpleCloudWorkerManager=INFO
log4j.logger.org.krake.box.abstraction.impl.scheduler.common.AbstractExecutor=DEBUG
log4j.logger.org.krake.box.abstraction.impl.scheduler.pbs.PBSExecutor=DEBUG
log4j.logger.org.krake.box.armadillo.workflow.events.WorkerSweeper=WARN
log4j.logger.org.krake.box.armadillo.workflow.nodes.FlowNode=WARN
log4j.logger.org.krake.box.armadillo.scheduler.WeightedHostScoreScheduler=INFO
log4j.logger.org.krake.box.abstraction.impl.common.task.TaskImpl=INFO
log4j.logger.org.krake.box.abstraction.slidr.rlog=INFO
log4j.logger.com.senatus.impl.execution.ec2=DEBUG
log4j.logger.com.endeca=INFO
log4j.logger.com.endeca.itl.web.metrics=INFO
In short, what is the actual algorithm for defining logger names in Log4j v1's properties-based configuration?
In older software like Log4j 1.2 the best documentation is the javadoc. In the PropertyConfigurator javadoc you can find out that all properties of the form:
log4j.logger.logger_name=[level|INHERITED|NULL], appenderName, appenderName, ...
configure loggers and the logger name is the part of the key after the log4j.logger. prefix.
Other logger configuration options are only described in the source code. For example to configure the logger additivity you need to use this form:
log4j.additivity.logger_name=[true|false]

Apache POI 5 and XMLBeans Classpath issues

I tried answering on the following post, but I don't have the "reputation" and really do not have time to hunt down 10 questions to answer.
Runtime Exception - POI 5 and xmlbeans
With POI 5 and XMLBeans 4 (or 5) in WebLogic server there is a classloader issue where it will try to use the underlying XMLBeans jar in the WebLogic server modules directory.
When packaging in an EAR you can use the weblogic-application.xml descriptor to override class loading with .
However, listing the POI and dependencies packages here will result in further errors.
The class SchemaTypeLoaderImpl is looking in the new (org.apache.xmlbeans.metadata) AND old (schemaorg_apache_xmlbeans) packages.
So you should also include the old package in the override list.
Now SchemaTypeLoaderImpl also tries to load the TypeSystemHolder classes using ClassLoader.getResource before it tries to look it up with Class.forName.
To fix this issue you need to prevent it from finding the old classes, as the previous package override is only giving your application bundled library priority over the underlying server libraries. It is not preventing it from finding these out of date classes and trying to load them as well.
This can be done by using for these resources.
NOTE that I am only using basic XSSFWorkbook XLS functionality!
You may need to track down other resources if you use other POI functionality.
For example the following weblogic-application.xml descriptor allows your application to use bundled POI/XMLBeans libraries and ignore the old resources.
<prefer-application-packages>
<package-name>org.apache.commons.collections4.*</package-name>
<package-name>org.apache.commons.compress.*</package-name>
<package-name>org.apache.poi.*</package-name>
<package-name>org.apache.xmlbeans.*</package-name>
<package-name>org.openxmlformats.*</package-name>
<package-name>schemaorg_apache_xmlbeans.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
<resource-name>schemaorg_apache_xmlbeans/system/sXMLCONFIG/TypeSystemHolder.class</resource-name>
<resource-name>schemaorg_apache_xmlbeans/system/sXMLLANG/TypeSystemHolder.class</resource-name>
<resource-name>schemaorg_apache_xmlbeans/system/sXMLSCHEMA/TypeSystemHolder.class</resource-name>
<resource-name>schemaorg_apache_xmlbeans/system/sXMLTOOLS/TypeSystemHolder.class</resource-name>
</prefer-application-resources>

Groovy-Eclipse 2.5.2: java.lang.ClassNotFoundException: picocli.CommandLine$ParameterException

I'm using Eclipse 4.5 with the Groovy-Eclipse 2.9.2/4.5 plugin which I thought was supposed to have the Groovy 2.5 compiler. However, it didn't have any picocli support so I added the groovy-cli-picocli-2.5.2-indy.jar to my classpath and was able to compile. However #2, when trying to run the script via Eclipse I get:
java.lang.ClassNotFoundException: picocli.CommandLine$ParameterException
It looks like groovy-cli-picocli-2.5.2-indy.jar does not have CommandLine class at all.
I would just throw jars at this from the fullblown picocli distribution but I'm under the impression they all have to somehow wrap nicely into Eclipse Groovy library via groovy.cli.picocli.CliBuilder.
Is my Groovy 2.5.2 missing this or am I somehow missing the boat on how it's supposed to work because picocli is not working for me in this configuration. Thanks!
You are correct: groovy-cli-picocli-2.5.2.jar (and groovy-cli-picocli-2.5.2-indy.jar) do not contain the picocli classes.
You need to add the picocli jar to the classpath.
If you use Maven, the groovy-all POM should include all dependencies.
(My original answer mentioned picocli classes that are shaded into the groovy-2.5.x.jar under the groovyjarjarpicocli package but these are intended for use internally by Groovy and not meant to be used by applications.)

JDK 9: JUnit 5 test compile with SpringExtension produces java.lang.NoClassDefFoundError: org/w3c/dom/ls/DocumentLS

I believe this problem not to be related to module exclusions in JDK 9 (as with java.se.ee), but rather with the fact that JDK 9 includes a newer version of org.w3c.dom.ls in the java.xml module that does not have the DocumentLS class.
The important bit of the stack trace is this:
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [spring-test/test-container.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/ls/DocumentLS
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
Even if I include a runtime dependency with this class, like xerces:xerces 2.4.0, the JDK java.xml module is preferred (I guess).
I am using Gradle 4.1. Is there any way to restrict the scope of a
JDK provided module?
As you have correctly analyzed, the package org.w3c.dom.ls is present in the platform module java.xml. Any class on the class path that is in the same package will be ignored. That's called a split package and several fixes exist - the following two might help you.
Patch java.xml
You can add the classes of the Xerxes JAR to the java.xml module with --patch-module:
java --patch-module java.xml=xerxes-4.0.0.jar ...
I've never tried that with a JAR that contains some of the same classes. As I understand it, the JDK classes will then be replaced with the Xerxes classes, which means they better be a fully binary compatible replacement.
Upgrade java.xml
Another hope is to replace java.xml with the upgrade module path:
The upgrade module path (--upgrade-module-path) contains compiled definitions of modules intended to be used in place of upgradeable modules built-in to the environment (compile time and run time).
You face two problems:
the upgrade module path is supposed to be used only for upgradable modules (which java.xml is not), but I think I've read somewhere that that's not enforced (yet?) - didn't try it
the artifact you replace java.xml with needs to be fully binary compatible update - would that be the case for Xerxes?
From what I can tell, DocumentLS is from a 2002 draft of the W3C API, it doesn't appear to have made it into a released version. It looks like xerces-2.4.0 (from 2006?) includes it but newer versions don't. So upgrading to a more recent Xerces may be needed here. If Spring really depends on DocumentLS then it will need to be updated too.

How to work-a-round with JSF annotation processing bug on Jetty?

There's a bug in JSF loading mechanism for managed beans annotated with annotation #ManagedBean. The mechanism is not activated when running the app via mvn jetty:run. The bug is reported here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=288243
This is a very nasty thing, because jetty:run have great advantages when debugging:
it is fast
it works directly with the jsf files from workspace, without need to use FileSync plugin
However, not supporting the annotation would require downgrading to XML configuration.
Is there any work-a-round for this bug?
source : the link you provided in your question , read Tomaz Lipinsi comments
Hi, I've found a easy workaround for this problem. Actually I don't
use Jetty but Tomcat and Sysdeo Tomcat Launcher but it behaves the
same. JSF2 is looking for annotated classes in two places:
- WEB-INF/classes - so if the app is not packaged into .war, this directory does not exist
- classpath jars (WEB-INF/lib) - similar as above I've tried to override default com.sun.faces.spi.AnnotationProvider to my own so I
could provide him a list of my classes (see JavaDoc for this class).
While I was trying to do this then I hit upon an idea that I could
just simply put my compilled classes in WEB-INF/classes dir. Adding
this to pom.xml solved the problem:
src/main/webapp/WEB-INF/classes
The drawback is that now I have compiled classes in source
dir but the most important is that it works.
Suggest you to read all the comments there.
For avoid a mix between src and classes, you can set in your maven's POM some like this:
<build>
<finalName>my-project</finalName>
<directory>target</directory>
<outputDirectory>${basedir}/target/main/webapp/WEB-INF/classes</outputDirectory>
....
</build>
And in the configuration of jetty's maven-plugin you can try this:
Edit: Jetty's version used is 6.1.26, if tag 'resources' doesn't work try 'resourcesAsCSV' instead
<configuration>
...
<webAppConfig>
<defaultsDescriptor>${basedir}/src/main/webapp/WEB-NF/webdefault.xml</defaultsDescriptor>
<baseResource implementation="org.mortbay.resource.ResourceCollection">
<resources>${basedir}/target/main/webapp,${basedir}/src/main/webapp</resources>
</baseResource>
</webAppConfig>
...
</configuration>
**Note: webdefault.xml is for setting an init-param needed for unblock files while jetty is running, the param is:
<init-param>
<param-name>useFileMappedBuffer</param-name>
<param-value>false</param-value>
</init-param>

Resources