I would like to emphasize that I am not proposing that the existing log4j-core.jar cease to be. I completely understand the desire to have a single consumable unit for Java SE and Java EE to make things as simple as possible. This can (and should) remain the output of log4j-core.
For OSGi clients having multiple bundles is much less difficult than having lots of extra, potentially optional, dependencies (almost exactly the opposite to Java SE). This means that libraries like log4j end up with three main options when creating OSGi bundles:
1. Simply use the maven bundle plugin to add OSGi metadata and declare victory. This leads to issues like LOG4J2-238 where OSGi clients are presented with a large number of opaque dependencies. Most of which are completely unnecessary but have to be provided. As an example, to use any functions from log4j-core (even the simplest appender) in OSGi right now I would have to install a mongo driver, a couch driver, the JMS api, the JPA api and a whole heap of other stuff. This effectively makes log4j-core completely unusable for OSGi clients
2. Use the maven bundle plugin to add OSGi metadata, but declare all of the imports as optional (possibly excluding org.apache.logging.log4j.). This means that the log4j-core bundle will always resolve, however it is still very unpleasant to use. Once resolved the log4j-core bundle exposes *all of its exported packages (e.g. o.a.l.l.core.appender.db.nosql.mongo and o.a.l.l.core.appender.db.nosql.couch). These packages will definitely not work unless the relevant dependencies are available, mostly they will throw ClassNotFoundException and NoClassDefFoundError at unpleasant points. The end result is a lot of broken OSGi bundles trying to use features that aren't actually available.
3. Modularise the component into OSGi bundles grouped by function and dependency. This can either be done by splitting the source into multiple maven modules (the aggregate jar can be recreated using the shade plugin), or by using the maven bundle plugin to create bundles from a single source jar (which is what the attached patch does). OSGi clients can then install the parts of log4j that they actually need, for example a simple client can just install the core-osgi-reduced bundle, but one that wants to use mongo can add the core-osgi-nosql-mongo bundle and the mongo driver bundle.
The OSGi bundles created by the patch are as follows:
a) core-osgi-reduced - this is most of the log4j-core jar, with as many external (non o.a.l.l) dependencies removed as possible. Once LOG4J2-238 is addressed this should run using only JDK provided code and have no external dependencies
b) core-osgi-async - this pulls out the o.a.l.l.core.async package to separate the dependency on lmax disruptors. If LOG4J2-238 can't be addressed then this could be pushed back into a)
c) core-osgi-net - this pulls out the o.a.l.l.core.net package to separate the javax.jms, javax.mail and javax.activation dependencies
d) core-osgi-nosql-couch - this pulls out the dependency on LightCouch
e) core-osgi-nosql-mongo - this pulls out the dependency on Mongo
I understand that there's a strong temptation to say "Let's just make X an optional dependency", however in OSGi an optional dependency really is optional, i.e. all the functions of the bundle should continue to work, possibly in a slower or slightly restricted manner. In log4j the "optional" packages would really indicate that some of the exported packages do not work at all. This can and does break OSGi applications.