添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • Download
  • Getting Started
  • Members
  • Projects
  • Bugzilla – Bug 370411 ClassNotFoundException for org/slf4j/LoggerFactory upon Xtext generation Last modified: 2017-10-31 11:18:14 EDT
    I have a stock Eclipse SDK with 3.7.1 installed on my Mac. I was trying the basic tutorial (File -> New Xtend Project) and running the MWE2 workflow for generating the xtext, and I received this error:
    1    [main] ERROR mf.mwe2.launch.runtime.Mwe2Launcher  - org/slf4j/LoggerFactory
    java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
    	at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:156)
    	at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
    	at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351)
    	at org.eclipse.emf.mwe.utils.StandaloneSetup.<init>(StandaloneSetup.java:91)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    	at java.lang.Class.newInstance0(Class.java:355)
    	at java.lang.Class.newInstance(Class.java:308)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.create(Mwe2ExecutionEngine.java:155)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.inCase(Mwe2ExecutionEngine.java:104)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.internalSwitch(Mwe2ExecutionEngine.java:66)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.internalApplyAssignments(Mwe2ExecutionEngine.java:142)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.inCase(Mwe2ExecutionEngine.java:114)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.internalSwitch(Mwe2ExecutionEngine.java:66)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.inCase(Mwe2ExecutionEngine.java:80)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.internalSwitch(Mwe2ExecutionEngine.java:66)
    	at org.eclipse.emf.mwe2.language.factory.Mwe2ExecutionEngine.create(Mwe2ExecutionEngine.java:62)
    	at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:88)
    	at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:73)
    	at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:64)
    	at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:55)
    	at org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher.run(Mwe2Launcher.java:74)
    	at org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher.main(Mwe2Launcher.java:35)
    Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
    	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    	... 40 more
    The org.slf4j.LoggerFactory doesn't appear to be present in my runtime:
    594	RESOLVED    org.apache.log4j_1.2.15.v201012070815
    10	RESOLVED    org.apache.commons.logging_1.0.4.v201101211617
    This is using OSX JDK 1.6
    java.runtime.version=1.6.0_29-b11-402-11M3527
    If I manually add the SLF4J to my classpath then it works. However, there's nothing in the manifest which requires it:
    Require-Bundle: org.eclipse.xtext;bundle-version="2.1.0";visibility:=reexport,
     org.eclipse.xtext.xbase;bundle-version="2.1.0";resolution:=optional;visibility:=reexport,
     org.apache.log4j;bundle-version="1.2.15";visibility:=reexport,
     org.apache.commons.logging;bundle-version="1.0.4";resolution:=optional;visibility:=reexport,
     org.eclipse.xtext.generator;resolution:=optional,
     org.eclipse.emf.codegen.ecore;resolution:=optional,
     org.eclipse.emf.mwe.utils;resolution:=optional,
     org.eclipse.emf.mwe2.launch;resolution:=optional,
     org.eclipse.xtext.util,
     org.eclipse.emf.ecore,
     org.eclipse.emf.common,
     org.antlr.runtime,
     org.eclipse.xtext.common.types
    Import-Package: org.apache.log4j,
     org.apache.commons.logging,
     org.eclipse.xtext.xbase.lib,
     org.eclipse.xtend2.lib
    It should be possible to reproduce this with a clean Eclipse 3.7 install on OSX, Xtext 2.2.1 and ensuring that the org.slf4j isn't in your workspace or in the classpath or OSGi runtime. I suspect either you need to add this as a required package (preferably not require-bundle!) or change the log call in the translation step.
    (In reply to comment #1)
    > The same happens with the new> 
    > eclipse-SDK-4.2M7-Xtext-2.3.0M7-linux-gtk.tar.gz
    Please describe the steps to follow.
    > from the itemis site
    I've tried eclipse-SDK-4.2M7-Xtext-2.3.0M7-linux-gtk-x86_64 -> New Xtext project -> run mwe2 workflow and can't reproduce it.
    Please note neither Xtext nor mwe2 depends on slf4j implementation of commons logging. However org.slf4j.api_1.6.4.v20120130-2120.jar is shipped with the itemis distro, so NoClassDefFoundError can't occur in this case.
    So I tried again with a fresh install of eclipse-SDK-4.2M7-Xtext-2.3.0M7-linux-gtk-x86 and you're right, the workflow runs fine...
    as soon as you install mylyn (I installed some connectors from mylyn) then the problem shows up again...
    some mylyn plugins install this plugin
    ./plugins/org.slf4j.jcl_1.6.4.v20111214-2030.jar
    which seems to be the cause of the problem (!?)
    manually removing this plugin and restarting eclipse makes the problem go away...
    > ./plugins/org.slf4j.jcl_1.6.4.v20111214-2030.jar ... its org.apache.httpcomponents.httpclient which is required by org.eclipse.mylyn.commons.repositories.http.core and org.eclipse.mylyn.hudson.core. > which seems to be the cause of the problem (!?) Yes, you are right. org.apache.httpcomponents.httpclient depends on org.apache.commons.logging;version="1.1.1" this package is exported by org.slf4j.jcl_1.6.4.v20111214-2030 so slf4j.jcl became installed and loaded. slf4j.jcl also register o.a.c.logging.LogFactory service as org.apache.commons.logging.impl.SLF4JLogFactory. This class tries to load org/slf4j/LoggerFactory, loading fails because of missing package import org.slf4j;version=1.6.4 :(
    So the problem is, that the java class path is configured using PDE and PDE doesn't resolve transitive import package declarations. 
    I think as long as we start the MWE workflow in a vanilla Java process we'll have to make sure that org.sl4j is pulled in somehow if present (i.e. optional require-bundle or package import).
    (In reply to comment #5)
    > So the problem is, that the java class path is configured using PDE and PDE
    > doesn't resolve transitive import package declarations. 
    > I think as long as we start the MWE workflow in a vanilla Java process we'll
    > have to make sure that org.sl4j is pulled in somehow if present (i.e. optional
    > require-bundle or package import).
    I think, we better must prevent that org.slf4j.jcl is automatically loaded if org.apache.commons.logging is available.  In my test environment, replacing org.apache.commons.logging package import with an optional bundle dependency does the trick.
    In the common case, mwe2 container project uses org.apache.commons.logging, if one (e.g. Knut :)  would like to work with slf4j it can be configured with the corresponding package import org.apache.commons.logging;version="1.1.1",org.slf4j;version="1.6.4"
    Please note that one has to provide additional information in order to configure logging via slf4j properly. Dennis' tests revealed that you'd have to make e.g. logback available along with slf4j to get it right whereas the simple optional bundle dep on commons.logging did the trick with much less effort for the common cases.
    (In reply to comment #5)
    > So the problem is, that the java class path is configured using PDE and PDE
    > doesn't resolve transitive import package declarations. 
    Just a quick note - OSGi does not say anything about transitive dependencies being made avaialble on the classpath, and indeed, shouldn't do. If I import A, and A imports B, I shouldn't have a dependency on B.
    If you use Require-Bundle and the 'visibility:=reexport' then it's possible to expose the transitive dependency set to the client.
    http://eclipsesource.com/blogs/2008/08/22/tip-split-packages-and-visibility/
    but the key premise here is that the dependency set is known (and described properly) by the bundles in question. Unfortunately for the org.slf4j.jcl bundle this does not appear to be the case.
    It might be worth raising the issue with the Mylyn team as they may know of a fix, or may be able to stop bundling the SLF4J implementation. Many OSGi users are moving over to use PAX Logging instead (which again provides an interface for Log4J but does so in a slightly more sane way).
    Found a related bug 339004. Bugfix already introduced bundle requirement to o.a.commons.logging but was removed for unknown reasons (twice!). We really have to use commit message to describe why something was changed. "removed xyz dependency" as commit comment is not enough, everybody can see that xyz dependency was removed, at least in the diff view, but nobody knows why... Note to me: The best reference is a bugzilla bug report.  :p
    When Xtext 2.3.0.v201206120633 is installed from the Juno update site into the Ecipse IDE for Java (http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/junor), the same exception stops Xtext generation. (The generation succeeds when running the Eclipse distribution that includes Xtext from http://www.eclipse.org/Xtext/download.html).
    Is this a new bug?
    Thanks Sebastian, but I don't where my code is involved in the bundle configuration when invoking org.eclipse.xtext.generator.Generator. The exception occurs when I run the mwe2 script to create the Xtext artifacts. Is there a way to configure the Mwe2Launcher with the require-bundle?
    I was under the impression the require-bundle is in the XText plugin. I was guessing that the mwe2 invocation doesn't pick up the configuration that's specified in the plugin (though that's only from reading this bug - I haven't looked at where the bundles are specified and loaded when running with the Java IDE).
    If there's a way to change the way the dependencies are resolved when the mwe2 script is run, I'll give it a try, but it would be good if XText could work when installed from the update site into the Java IDE.
    (I originally asked about this in the e-mail list: http://www.eclipse.org/forums/index.php/t/367736/ )
    (In reply to comment #13)
    > Thanks Sebastian, but I don't where my code is involved in the bundle
    > configuration when invoking org.eclipse.xtext.generator.Generator. The
    > exception occurs when I run the mwe2 script to create the Xtext artifacts. Is
    > there a way to configure the Mwe2Launcher with the require-bundle?
    > I was under the impression the require-bundle is in the XText plugin. I was
    > guessing that the mwe2 invocation doesn't pick up the configuration that's
    > specified in the plugin (though that's only from reading this bug - I haven't
    > looked at where the bundles are specified and loaded when running with the Java
    > IDE).
    > If there's a way to change the way the dependencies are resolved when the mwe2
    > script is run, I'll give it a try, but it would be good if XText could work
    > when installed from the update site into the Java IDE.
    > (I originally asked about this in the e-mail list:
    > http://www.eclipse.org/forums/index.php/t/367736/ )
    Hi John,
    mwe2 launch configs fully rely on the Java classpath that is configured for the project that contains the workflow. If you add a bundle dep, that will be reflected in the mwe2 launch classpath. The plugin deps container does not follow transitive import-package entries in the manifest thus a plain import-package for apache.log4j will not necessarily pick up the required bundles. If slf4j is selected, other import-package clauses in that bundle will not necessarily be used thus you end up with a NoClassDefFound. All these things work like a charm with require-bundle so I recommend to use that one.
    Hope that helps,
    Sebastian
    Thanks again, Sebastian! There must be something that I'm missing. The MANIFEST.MF for my plugin (copied below) includes log4j in its Require-Bundle header. Is that not the correct way to manipulate the project classpath with respect to OSGi bundles? Is there a way to see what OSGi configuration is used to assemble the classpath for the mwe2 launch? 
    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: com.bobberinteractive.lang
    Bundle-Vendor: Bobber Interactive Corp.
    Bundle-Version: 1.0.1
    Bundle-SymbolicName: com.bobberinteractive.lang; singleton:=true
    Bundle-ActivationPolicy: lazy
    Require-Bundle: org.eclipse.xtext;bundle-version="2.3.0";visibility:=reexport,
     org.apache.log4j;bundle-version="1.2.15";visibility:=reexport,
     org.apache.commons.logging;bundle-version="1.0.4";resolution:=optional;visibility:=reexport,
     org.eclipse.xtext.generator;resolution:=optional,
     org.eclipse.emf.codegen.ecore;resolution:=optional,
     org.eclipse.emf.mwe.utils;resolution:=optional,
     org.eclipse.emf.mwe2.launch;resolution:=optional,
     org.eclipse.xtext.util,
     org.eclipse.emf.ecore,
     org.eclipse.emf.common,
     org.antlr.runtime,
     org.eclipse.xtext.common.types,
     org.codehaus.groovy;bundle-version="1.8.6"
    Import-Package: org.apache.commons.logging,
     org.apache.log4j
    Bundle-RequiredExecutionEnvironment: JavaSE-1.6,J2SE-1.5
    Export-Package: com.bobberinteractive.lang,
     com.bobberinteractive.lang.services,
     com.bobberinteractive.lang.serializer,
     com.bobberinteractive.lang.parser.antlr,
     com.bobberinteractive.lang.parser.antlr.internal,
     com.bobberinteractive.lang.validation,
     com.bobberinteractive.lang.scoping,
     com.bobberinteractive.lang.generator,
     com.bobberinteractive.lang.formatting,
     com.bobberinteractive.lang.flow,
     com.bobberinteractive.lang.flow.impl,
     com.bobberinteractive.lang.flow.util
    Hi John, the import package thing seems to confuse the dep resolution. You could try to remove the package import for org.apache.commons.logging or use an explicit version in the package import. Sorry, my comment #14 referred to log4j whereas the error message indicates a problem with commons.logging. But the issue should be the same.
    Thanks for helping, Sebastian: that got it working! I guess I had o.a.c.logging
    in the Import-Package from some earlier effort. It didn't occur to me that the
    import of o.a.c.logging would result in the attempt to load slf4j (when
    Require-Bundle doesn't have that effect).