[slf4j-user] SLF4J on the Google Android Platform

Chiao Cheng zimazenini at yahoo.com
Wed Mar 10 19:03:37 CET 2010


Thanks for the reply Thorsten.... my comments inline...



----- Original Message ----
> From: Thorsten Möller <Thorsten.Moeller at unibas.ch>
> To: slf4j-user at qos.ch
> Sent: Wed, March 10, 2010 8:13:28 AM
> Subject: Re: [slf4j-user] SLF4J on the Google Android Platform
> 
> Hi Chiao,
> 
> now the promised reply ...
> 
> 
> On Wednesday, March 03, 2010 11:34 AM [GMT+1=CET],
> Chiao Cheng wrote (with possible deletions):
> 
> > Hi All,
> >
> > I was playing around with android and was glad to see that someone
> > already put together a slf4j-android module.  I tried using it and I
> > really like to make some changes so I created another fork.
> >
> > First, I found an old thread explaining why slf4j-android also
> > includes slf4j-api code...
> >
> >> I can already tell you that I needed to merge the SLf4J-API project
> >> and
> >> the new binding implementation into one (Maven) project. The reason
> >> is
> >> rather complicated to explain. In short, it is due to the fact that
> >> SLF4J API removes the dummy impl.* classes during the build from the
> >> target Jar, which is not compatible with the Android Dexer
> > I'm not
> > sure why this would be the case because the dexer is completely ok
> > with dex'ing multiple jars and dependencies.
> 
> The reason is the following (explained not using real class names for 
> brevity): The SLF4J API project contains some "dummy" classes, say C_1 
> ... C_n, which will be compiled during the build but not included in the 
> final binary jar. Furterhmore, other classes in the API project, say D_1 
> ... D_m *depend on* one or more of C_1 ... C_n, that is, they import at 
> least one of them. Now, each SLF4J binding implementation provides 
> "real" implementations of C_1 ... C_n. At runtime, a Java classloader 
> then loads the real implementations C_1 ... C_n when one of D_1 ... D_m 
> is loaded. This works for "standard" Java SDKs. However, on the Android 
> platform, final application archives are created by the Dexer (which 
> does several things which are not relevant here). When the Dexer runs at 
> build time and processes the compiled classes D_1 ... D_m it is somehow 
> (for reasons I don't know) fixated to the original dummy implementations 
> of C_1 ... C_n and not the real implementations provided by the binding 
> implementation. Since the original ones were deleted it cannot find them 
> (even though the real implementations do exist), throws an error 
> message, and stops, rendering the build to fail.
> 

Hmmm... this may have been a problem before but I just started playing with android recently so I do not know the history.   But it does not appear to be a problem now.  I have made the changes in my fork, specifically I have removed the slf4j-api classes from the slf4j-android classes.  So now there are two jars, one for the api and the other just for the android wrapper. I have tested my changes on the android platform and it does work.  Maybe you can try my fork and see for yourself.

Just checkout my fork and do a "maven install" on the slf4j root.  Then change your maven slf4j dependencies to:

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.5.11</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-android</artifactId>
            <version>1.5.11</version>
        </dependency>

> 
> >  I suggest we separate
> > out slf4j-api code from the slf4j-android module.  Once we do this,
> > then it would be easier to keep the two in sync.  With the current
> > setup, it seems like it would be very easy for slf4j-android to fall
> > out of sync with the main api version.
> That's is actually true. The merging of both needed to be done in order 
> to fix the abovementioned problem. I know that it is not optimal. My 
> original idea was to make symbolic links to the SLF4J API classes. This 
> would have prevented them to fall apart. Setting such links is possible 
> in SVN, at least. However, since I couldn't find any information whether 
> Git also supports symbolic links, I finally decided to accept this 
> weakness in order to keep the whole thing simple.
> 
> 
> > And from the web page, it
> > seems like it has already fallen behind.
> Yes, meanwhile there is SLF4J 1.5.11.
> 
> > Next, I found a problem in the recent access modifier changes in
> > slf4j.  Specifically the references from LoggerFactory to private
> > StaticLoggerBinder.SINGLETON.  Even though the java runtime seems to
> > be ok due to shortcircuit logic I'm guessing, the android runtime is
> > not:
> >
> > "access denied from Lorg/slf4j/LoggerFactory; to field
> > Lorg/slf4j/impl/StaticLoggerBinder;.SINGLETON"
> >
> > For now, I had to change StaticLoggerBinder.SINGLETON back to public
> > to avoid these errors.  But, from looking at the code, I do not see
> > any reasons for LoggerFactory to reference
> > StaticLoggerBinder.SINGLETON, other than allowing some modules to
> > work without a getSingleton() method.
> >  But I would love to remove
> > SINGLETON references in the LoggerFactory.  Also seems a bit hacky to
> > have code that tries to access private members.  Are there plans to
> > get rid of the SINGLETON references completely?
> I cannot comment on that since I'm not involved in the API development.

Yea I think this was more of a comment for ceki probably.

> 
> 
> >
> > Finally the only other change I made was to remove the systempath in
> > the pom.xml.  Users can simply install a 3rd party jar in their local
> > repository with the provided maven command so there is really no need
> > to have that.  And to make things simpler, there is already an
> > android-maven-plugin which will install the jars for you in your
> > local-repository
> > (http://code.google.com/p/maven-android-plugin/wiki/GettingStarted).
> Where is this described. I cannot find that.

The standard maven command is here:

http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html

The maven android plugin makes it easier by automatically using that command on your behalf and pre-defines the package and versioning for you.  Since many other people already uses the artifact name and versions from that plugin, it would be nice to have this project also use the same.  

> 
> Anyway, the solution I created (using the system path) is considered a 
> temporary one. Actually, it should work in most cases right away since 
> the ANDROID_HOME variable will be set together with installing the SDK. 
> And I'm not happy with replicating the Android jars in the local Maven 
> repository since everybody would have them on disk anyway. I think a 
> clean solution is to use the toolchains plugin 

It's pretty standard practice to install 3rd party dependencies in the local repository.  That way maven can manage it for you.  And if you look around the maven projects, it's fairly rare to use the "system path" option.

> (http://maven.apache.org/guides/mini/guide-using-toolchains.html) once 
> it is generally available and supported by the android-maven plugin.
> 
> Cheers,
> Thorsten 
> 
> 
> _______________________________________________
> slf4j-user mailing list
> slf4j-user at qos.ch
> http://qos.ch/mailman/listinfo/slf4j-user



More information about the slf4j-user mailing list