[slf4j-dev] Service Provider Interface (using jcl104-over-slf4j.jar with axis.jar)

Dave Wallace dwallace at UDel.Edu
Tue Mar 21 19:01:17 CET 2006


I had not modifed jcl104-over-slf4j.jar other than to add
/META-INF/services by unpacking the jar (from the 1.0 release), adding
the file and repacking.
The original, unmodified 1.0 release of jcl104-over-slf4j.jar and the
one you sent me both fail like so:
java.lang.ExceptionInInitializerError
    at org.apache.axis.message.NodeImpl.<clinit>(NodeImpl.java:48)
   .... [Elided] ....
Caused by: org.apache.commons.discovery.DiscoveryException: No
implementation defined for org.apache.commons.logging.LogFactory
    at
org.apache.commons.discovery.tools.ClassUtils.verifyAncestory(ClassUtils.java:176)
    at
org.apache.commons.discovery.tools.SPInterface.verifyAncestory(SPInterface.java:201)
    at
org.apache.commons.discovery.tools.SPInterface.newInstance(SPInterface.java:195)
    at
org.apache.commons.discovery.tools.DiscoverClass.newInstance(DiscoverClass.java:579)
    at
org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:418)
    at
org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:378)
    at
org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:45)
    at java.security.AccessController.doPrivileged(Native Method)
    at
org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:41)
    at
org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:33)
    ... 37 more

I believe that the vm is able to load
org.apache.axis.components.logger.LogFactory because javac tends to fold
public static final variables into generated code, therefore there are
no references to FACTORY_PROPERTIES and FACTORY_DEFAULT in the axis
LogFactory, just the values are stored. So I don't think they can be
overridden without recompiling axis.jar.


Ceki Gülcü wrote:
>
> Dave,
>
> Thank you for the clarifications. Looking at [1] and given that
> o.a.c.logging.LogFactory class as shipped in jcl104-over-slf4j.jar
> does not define FACTORY_PROPERTIES and FACTORY_DEFAULT, do you have an
> idea how can the code run? The code should barf before the find()
> method in DiscoverSingleton can be invoked...
>
> Have you modified jcl104-over-slf4j.jar?
>
> Anyway, at this point, the correct thing to do would be to define the
> missing variables in jcl104-over-slf4j. Would you like to give a
> modified copy of SLF4J a try?
>
> [1]
> http://svn.apache.org/viewcvs.cgi/webservices/axis/trunk/java/src/org/apache/axis/components/logger/LogFactory.java
>
>
> At 06:00 PM 3/21/2006, Dave Wallace wrote:
>> Hi Ceki,
>> I knew I did I horrible job of explaining, there's just too many levels
>> of indirection involved !  :) Anyhow:
>>
>> I am pretty certain that I've gotten rid of commons-logging, I believe
>> the code that caused the problem is actually in
>>  org.apache.axis.components.logger.LogFactory in the _axis.jar_. In
>> which there is a bit of code:
>> -----
>>  return
>> DiscoverSingleton.find(org.apache.commons.logging.LogFactory.class,
>>
>> org.apache.commons.logging.LogFactory.FACTORY_PROPERTIES,
>>
>> org.apache.commons.logging.LogFactory.FACTORY_DEFAULT);
>> ----
>> Since my copy of axis.jar was compiled against commons-logging.jar,
>> org.apache.commons.logging.LogFactory.FACTORY_*  must refer to constants
>> that were _folded into the axis.jar_ code (these constants do not appear
>> in jcl104-over-slf4j.jar) with these values (from commons-logging
>> source):
>> ----
>>    public static final String FACTORY_PROPERTY =
>> "org.apache.commons.logging.LogFactory";
>>    public static final String FACTORY_DEFAULT =
>> "org.apache.commons.logging.impl.LogFactoryImpl";
>> ----
>> And my original failure resulted precisely because I do not have
>> "org.apache.commons.logging.impl.LogFactoryImpl" in my classpath.
>>
>> DiscoverSingleton is from org.apache.commons.discovery.tools:
>> http://jakarta.apache.org/commons/discovery/commons-discovery-0.2/docs/api/org/apache/commons/discovery/tools/DiscoverSingleton.html
>>
>> .
>> Those docs describe how the discovery process works, first looking for
>> the property, then attempting an SPI lookup, then falling back to the
>> default.
>> At any rate, my take on the /META-INF/services SPI mechanism is that it
>> allows jcl104-over-slf4j.jar to announce: "I am the provider of the
>> service named org.apache.commons.logging.LogFactory and the
>> implementation is org.apache.commons.logging.impl.SLF4FLogFactory"
>>
>> -Dave
>>
>> Ceki Gülcü wrote:
>> >
>> > Hello Dave,
>> >
>> > I am a little puzzled by your message. The code contained in
>> > jcl104-over-slf4j.jar makes no use of meta-information or the
>> > org.apache.commons.logging.LogFactory system variable. The fact that
>> > setting JCL related variables has an effect means that you have a copy
>> > of commons-logging.jar or commons-logging-api.jar in your environment.
>> > Have you checked that?
>> >
>> > Cheers,
>> >
>> > At 04:25 PM 3/21/2006, Dave Wallace wrote:
>> >> Hello,
>> >> I recently encountered some trouble adding axis.jar to an existing
>> >> project that uses slf4j and jcl104-over-slf4j.jar to take over
>> logging
>> >> for hibernate and a few other apache commons jars.
>> >> The application failed to load axis.jar until I set this property
>> on the
>> >> Java VM command line:
>> >>
>> -Dorg.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.SLF4FLogFactory.
>>
>> >>
>> >>
>> >> As it turns out, axis.jar uses commons-logging but through a
>> >> commons-discovery mechanism that looks for a factory implementation
>> >> based on the value of a property with a name from
>> >> org.apache.commons.logging.LogFactory.FACTORY_PROPERTY. Hence the
>> >> property is required, but this led me to look a little deeper into
>> the
>> >> discovery mechanism.
>> >>
>> >> Following
>> >>
>> http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider
>> >> I added a file named
>> >> "/META-INF/services/org.apache.commons.logging.LogFactory" to
>> >> jcl104-over-slf4j.jar. The file contained a single line naming
>> >> org.apache.commons.logging.impl.SLF4FLogFactory as a provider of the
>> >> LogFactory service. With this modification the property is no longer
>> >> necessary.
>> >>
>> >> Do you think this might be a good thing to add to the jar
>> permanently so
>> >> that whenever jcl104-over-slf4j.jar is dropped in the classpath it
>> >> becomes a provider of the org.apache.commons.logging.LogFactory
>> service?
>> >>
>> >> - Dave
>> >
>>
>> _______________________________________________
>> dev mailing list
>> dev at slf4j.org
>> http://slf4j.org/mailman/listinfo/dev
>




More information about the slf4j-dev mailing list