Bug 514326 - JGit should not force inclusion of log4j
Summary: JGit should not force inclusion of log4j
Status: RESOLVED FIXED
Alias: None
Product: JGit
Classification: Technology
Component: JGit (show other bugs)
Version: 4.2   Edit
Hardware: PC Mac OS X
: P3 normal with 1 vote (vote)
Target Milestone: 5.10   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 549869 520754
  Show dependency tree
 
Reported: 2017-03-28 09:26 EDT by Brian de Alwis CLA
Modified: 2020-12-02 14:27 EST (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Brian de Alwis CLA 2017-03-28 09:26:26 EDT
JGit's feature forces inclusion of log4j and the SLF4j facade.  I don't believe JGit.  This appears to lead to some issues in Neon.3 where some end-users see LinkageErrors when opening EGit views:

   https://www.eclipse.org/forums/index.php/m/1758409/#msg_1758409

org.eclipse.core.runtime.CoreException: Plug-in org.eclipse.egit.ui was unable to load class org.eclipse.egit.ui.internal.repository.RepositoriesView.
[…]
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/eclipse/osgi/internal/loader/EquinoxClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of org/eclipse/osgi/internal/loader/EquinoxClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:336)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:284)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:305)
at org.eclipse.jgit.lib.Repository.<clinit>(Repository.java:109)

The SLF4j backend should be pulled in implicitly.
Comment 1 Massimo Rabbi CLA 2017-04-10 06:19:24 EDT
Hi, not sure but this topic might help, since I was facing a similar problem: https://www.eclipse.org/forums/index.php/m/1758409/#msg_1758409

I was able to detect that I had also a 1.7.10 version of the org.slf4j.api installed that was causing the conflict. I ended up removing it from the target platform. It appears to fix the issue. Errors disappeared and I was able also to open the GIT perspective of my runtime environment.
Comment 2 Massimo Rabbi CLA 2017-04-10 06:22:12 EDT
(In reply to Massimo Rabbi from comment #1)
> Hi, not sure but this topic might help, since I was facing a similar
> problem: https://www.eclipse.org/forums/index.php/m/1758409/#msg_1758409
> 
> I was able to detect that I had also a 1.7.10 version of the org.slf4j.api
> installed that was causing the conflict. I ended up removing it from the
> target platform. It appears to fix the issue. Errors disappeared and I was
> able also to open the GIT perspective of my runtime environment.

I did not realise you were the author of the post also on the forum. Indeed refining the platform bundles worked. Regards.
Comment 3 Matthias Sohn CLA 2017-04-13 17:46:57 EDT
slf4j related bundles related bundles in Neon
---------------------------------------------
Neon.0 http://download.eclipse.org/releases/neon/201606221000,
Neon.1 http://download.eclipse.org/releases/neon/201609281000,
       http://download.eclipse.org/releases/neon/201610111000
Neon.2 http://download.eclipse.org/releases/neon/201612211000 :

org.slf4j.api	1.7.2.v20121108-1250
org.slf4j.api.source	1.7.2.v20121108-1250
org.slf4j.impl.log4j12	1.7.2.v20131105-2200
org.slf4j.jcl	1.7.2.v20130115-1340

Neon.3 http://download.eclipse.org/releases/neon/201703231000 :

org.slf4j.api	1.7.2.v20121108-1250
org.slf4j.api	1.7.10.v20160921-1923
org.slf4j.api.source	1.7.2.v20121108-1250
org.slf4j.impl.log4j12	1.7.2.v20131105-2200
org.slf4j.jcl	1.7.2.v20130115-1340

--------------------------------------------------------
slf4j api and bridges in Neon.3 
--------------------------------------------------------
the log4j slf4j bridge is included by jgit feature
org.eclipse.jgit.pgm.feature.group 4.6.1.201703071140-r
and requires org.slf4j.api [1.7.2,1.7.3) :

<?xml version='1.0' encoding='UTF-8'?>
<units size='1'>
  <unit id='org.slf4j.impl.log4j12' version='1.7.2.v20131105-2200' singleton='false'>
    <update id='org.slf4j.impl.log4j12' range='[0.0.0,1.7.2.v20131105-2200)' severity='0'/>
    <properties size='9'>
      <property name='df_LT.Bundle-Name' value='SLF4J LOG4J-12 Binding'/>
      <property name='df_LT.Bundle-Description' value='SLF4J LOG4J-12 Binding'/>
      <property name='df_LT.Bundle-Vendor' value='Eclipse.org'/>
      <property name='org.eclipse.equinox.p2.name' value='%Bundle-Name'/>
      <property name='org.eclipse.equinox.p2.description' value='%Bundle-Description'/>
      <property name='org.eclipse.equinox.p2.provider' value='%Bundle-Vendor'/>
      <property name='iplog.bug_id' value='7666'/>
      <property name='iplog.contact.name' value='Gunnar Wagenknecht'/>
      <property name='iplog.contact.email' value='gunnar@wagenknecht.org'/>
    </properties>
    <provides size='6'>
      <provided namespace='org.eclipse.equinox.p2.iu' name='org.slf4j.impl.log4j12' version='1.7.2.v20131105-2200'/>
      <provided namespace='osgi.bundle' name='org.slf4j.impl.log4j12' version='1.7.2.v20131105-2200'/>
      <provided namespace='java.package' name='org.slf4j.impl' version='1.7.2'/>
      <provided namespace='org.eclipse.equinox.p2.eclipse.type' name='bundle' version='1.0.0'/>
      <provided namespace='osgi.fragment' name='org.slf4j.api' version='1.7.2.v20131105-2200'/>
      <provided namespace='org.eclipse.equinox.p2.localization' name='df_LT' version='1.0.0'/>
    </provides>
    <requires size='2'>
      <required namespace='osgi.bundle' name='org.slf4j.api' range='[1.7.2,1.7.3)'/>
      <required namespace='java.package' name='org.apache.log4j' range='0.0.0'/>
    </requires>
    <artifacts size='1'>
      <artifact classifier='osgi.bundle' id='org.slf4j.impl.log4j12' version='1.7.2.v20131105-2200'/>
    </artifacts>
    <touchpoint id='org.eclipse.equinox.p2.osgi' version='1.0.0'/>
    <touchpointData size='1'>
      <instructions size='1'>
        <instruction key='manifest'>
          Bundle-SymbolicName: org.slf4j.impl.log4j12&#xA;Bundle-Version: 1.7.2.v20131105-2200&#xA;Fragment-Host: org.slf4j.api;bundle-version=&quot;[1.7.2,1.7.3)&quot;
        </instruction>
      </instructions>
    </touchpointData>
  </unit>
</units>

the logback bridge is included by jubula feature
org.eclipse.jubular.feature.feature.group 4.0.0.201611231023
and also requires org.slf4j.api [1.7.2,1.7.3):

<?xml version='1.0' encoding='UTF-8'?>
<units size='1'>
  <unit id='ch.qos.logback.slf4j' version='1.0.7.v201505121915' singleton='false'>
    <update id='ch.qos.logback.slf4j' range='[0.0.0,1.0.7.v201505121915)' severity='0'/>
    <properties size='5'>
      <property name='df_LT.Bundle-Vendor.0' value='Eclipse Orbit'/>
      <property name='df_LT.Bundle-Name.0' value='Logback Native SLF4J Logger'/>
      <property name='org.eclipse.equinox.p2.name' value='%Bundle-Name.0'/>
      <property name='org.eclipse.equinox.p2.provider' value='%Bundle-Vendor.0'/>
      <property name='org.eclipse.equinox.p2.bundle.localization' value='fragment'/>
    </properties>
    <provides size='6'>
      <provided namespace='org.eclipse.equinox.p2.iu' name='ch.qos.logback.slf4j' version='1.0.7.v201505121915'/>
      <provided namespace='osgi.bundle' name='ch.qos.logback.slf4j' version='1.0.7.v201505121915'/>
      <provided namespace='java.package' name='org.slf4j.impl' version='1.7.2'/>
      <provided namespace='org.eclipse.equinox.p2.eclipse.type' name='bundle' version='1.0.0'/>
      <provided namespace='osgi.fragment' name='org.slf4j.api' version='1.0.7.v201505121915'/>
      <provided namespace='org.eclipse.equinox.p2.localization' name='df_LT' version='1.0.0'/>
    </provides>
    <requires size='3'>
      <required namespace='osgi.bundle' name='org.slf4j.api' range='[1.7.2,1.7.3)'/>
      <required namespace='osgi.bundle' name='ch.qos.logback.core' range='[1.0.7,1.0.8)'/>
      <required namespace='osgi.bundle' name='ch.qos.logback.classic' range='[1.0.7,1.0.8)'/>
    </requires>
    <artifacts size='1'>
      <artifact classifier='osgi.bundle' id='ch.qos.logback.slf4j' version='1.0.7.v201505121915'/>
    </artifacts>
    <touchpoint id='org.eclipse.equinox.p2.osgi' version='1.0.0'/>
    <touchpointData size='1'>
      <instructions size='1'>
        <instruction key='manifest'>
          Bundle-SymbolicName: ch.qos.logback.slf4j&#xA;Bundle-Version: 1.0.7.v201505121915&#xA;Fragment-Host: org.slf4j.api;bundle-version=&quot;[1.7.2,1.7.3)&quot;
        </instruction>
      </instructions>
    </touchpointData>
  </unit>
</units>

The 1.7.10 version of org.slf4j.api is required by
com.spotify.docker.client 3.6.8.v20161117-2005

All other components I found in Neon.2 p2 repository require org.slf4j.api with varying version ranges which AFAICS include both 1.7.2 and 1.7.10

So it seems unless you have installed com.spotify.docker.client or some other bundle
requiring a higher version of org.slf4j.api than 1.7.2 p2 runtime wiring should be able
to conclude that 1.7.2 should be used which should work with both the available logback
and log4j bridges.
Or did I miss something ?

I don't know how I can ensure that a logging implementation including it's slf4j bridge is
installed with jgit/egit without including the bridge in a feature. If log4j is present
but not the log4j bridge nothing would be logged since the bridge is missing. Same if
logback implementation is available without its slf4j bridge.

Any hints what I miss here ?
Comment 4 Benjamin Brandl CLA 2017-04-25 10:02:37 EDT
It seems like org.slf4j.log4j from version 1.7.2 has been renamed to org.slf4j.log4j in version 1.7.10. The latter bundle misses a corresponding version of org.slf4j.impl.logj12 in both repositories of neon and oxygen.
Comment 5 Dani Megert CLA 2017-04-25 10:17:18 EDT
(In reply to Benjamin Brandl from comment #4)
> It seems like org.slf4j.log4j from version 1.7.2 has been renamed to
> org.slf4j.log4j in version 1.7.10.

You just wrote "org.slf4j.log4j" twice which looks identical to me. Typo?
Comment 6 Benjamin Brandl CLA 2017-04-25 10:26:55 EDT
(In reply to Dani Megert from comment #5)
> (In reply to Benjamin Brandl from comment #4)
> > It seems like org.slf4j.log4j from version 1.7.2 has been renamed to
> > org.slf4j.log4j in version 1.7.10.
> 
> You just wrote "org.slf4j.log4j" twice which looks identical to me. Typo?

Yes, sorry. I meant org.slf4j.log4j (version 1.7.2) has been renamed to org.slf4j.apis.log4j (version 1.7.10). At least the bundle content seems identical to me.
Comment 7 Matthias Sohn CLA 2017-04-25 10:35:12 EDT
we only can update if the 1.7.10 log4j bridge is available in Orbit, which requires a CQ before it can be added
Comment 8 Tobias Verbeke CLA 2017-05-02 07:53:42 EDT
(from an end user perspective: installing Docker Tools after installing EGit on Neon.3 no longer allows to open Git Staging view, Git Repositories View etc.)
Comment 9 Brian de Alwis CLA 2017-05-02 22:34:18 EDT
org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml includes:
  - org.slf4j.api
  - org.slf4j.impl.log4j12
  - org.apache.log4j

I don't see any code in JGit that uses log4j — it looks like it's only used as a logging backend via SLF4j.  The choice of an slf4j backend should be left to the product and so org.slf4j.impl.log4j and org.apache.log4j should not be referenced in this feature.

It seems unlikely that JGit depends on a specific version of org.slf4j.api, and so it should be pulled in by reference from a bundle import-package and left for p2 to find a satisfying version.

So org.eclipse.jgit.feature should only include 
  - org.eclipse.jgit
  - org.eclipse.jgit.archive

Does JGit need specific versions of com.jcraft.jsch, javaewah, org.apache.commons.compress?  Or can it use normal bundle Import-Package/Require-Bundle to pull in a compatible version?
Comment 10 Gunnar Wagenknecht CLA 2017-05-03 02:49:59 EDT
(In reply to Brian de Alwis from comment #9)
> So org.eclipse.jgit.feature should only include 
>   - org.eclipse.jgit
>   - org.eclipse.jgit.archive

+1 

I would also suggest to not include 3rd party dependencies directly in the main feature and let p2 handle resolution at install time based on Import-Package declarations in the bundles.
Comment 11 Matthias Sohn CLA 2017-05-03 03:27:32 EDT
JGit has only a dependency to the slf4j api and these dependencies are package dependencies. But if no slf4j bridge is installed and a suitable log4j configuration is present no JGit logs will be written. So I am wondering how can we ensure that the log4j bridge is installed without including it in a JGit feature ?
Comment 12 Gunnar Wagenknecht CLA 2017-05-03 03:52:16 EDT
(In reply to Matthias Sohn from comment #11)
> JGit has only a dependency to the slf4j api and these dependencies are
> package dependencies. But if no slf4j bridge is installed and a suitable
> log4j configuration is present no JGit logs will be written. So I am
> wondering how can we ensure that the log4j bridge is installed without
> including it in a JGit feature ?

The thing is, M2E is offering a separate feature which install Logback as an SLF4J backend. They are also using SLF4J. Now this will create a conflict.

The question is: when are the logs wanted/necessary?

I don't think they are required by default. Plus, EGit uses the error reported which does not handle custom logs. Thus I think it safe it install none by default and offer a feature with a specific logging backend (including a sane default configuration). 

Using an extra feature, one could also instruct p2 to uninstall other implementations (eg., the simple/noop implementation).

https://www.eclipse.org/forums/index.php/t/572486/
Comment 13 Gunnar Wagenknecht CLA 2017-05-03 06:35:42 EDT
BTW, I don't know how much value would be in having this:
https://git.eclipse.org/r/96277
Comment 14 Eclipse Genie CLA 2018-12-03 11:26:25 EST
New Gerrit change created: https://git.eclipse.org/r/133407
Comment 15 Eclipse Genie CLA 2020-06-01 18:36:41 EDT
Gerrit change https://git.eclipse.org/r/133407 was merged to [master].
Commit: http://git.eclipse.org/c/jgit/jgit.git/commit/?id=166c85e0cf4087297e14d9192e2c3cfcccf225b2