简体   繁体   中英

ClassCastException when using log4j in app embedding osgi felix while bundles use log4j

I have a java application which embeds felix osgi container. The java application uses log4j 2.8.2.

One of my osgi implementation bundles also use log4j. Because of this i added the jars log4j-api-2.8.2 and log4j-core-2.8.2 to the osgi system with:

bundleContext.installBundle()

And start the bundle with:

bundle.start()

Installing the bundles works fine. Except the starting of bundle "org.apache.felix.scr" throws an exception:

    ERROR StatusLogger Unable to create custom ContextSelector. Falling back to default.
     java.lang.ClassCastException: Cannot cast org.apache.logging.log4j.core.osgi.BundleContextSelector to 
org.apache.logging.log4j.core.selector.ContextSelector

I suspect that is because the felix SCR is trying to load my implementation bundle which is using log4j. And because my application (the one that embeds felix) uses log4j and likely the ContextSelector. The osgi likely uses BundleContextSelector. Hence the exception.

I'm wondering how can i solve this?

I already tried setting the ContextSelector for my application to the osgi one:

System.setProperty("Log4jContextSelector",
      "org.apache.logging.log4j.core.osgi.BundleContextSelector")

But no luck there. I also tried spawning a new thread to setup osgi/felix. I'm running out of ideas.

I currently have switched from log4j to java util logging for my application. My implementation osgi bundles can use log4j without problems this way.

Just for reference here's the full exception trace:

ERROR StatusLogger Unable to create custom ContextSelector. Falling back to default.
 java.lang.ClassCastException: Cannot cast org.apache.logging.log4j.core.osgi.BundleContextSelector to org.apache.logging.log4j.core.selector.ContextSelector
    at java.lang.Class.cast(Class.java:3369)
    at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOf(LoaderUtil.java:201)
    at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOfProperty(LoaderUtil.java:226)
    at org.apache.logging.log4j.core.impl.Log4jContextFactory.createContextSelector(Log4jContextFactory.java:97)
    at org.apache.logging.log4j.core.impl.Log4jContextFactory.<init>(Log4jContextFactory.java:58)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:94)
    at com.okwant.emap.impl.ui.UIImpl.<clinit>(UIImpl.java:18)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:237)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:109)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:906)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:879)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:749)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:675)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:430)
    at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657)
    at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341)
    at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:390)
    at org.apache.felix.scr.impl.Activator.access$200(Activator.java:54)
    at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:265)
    at org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:254)
    at org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:227)
    at org.apache.felix.utils.extender.AbstractExtender.addingBundle(AbstractExtender.java:187)
    at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:469)
    at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:415)
    at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
    at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
    at org.osgi.util.tracker.BundleTracker.open(BundleTracker.java:156)
    at org.apache.felix.utils.extender.AbstractExtender.startTracking(AbstractExtender.java:150)
    at org.apache.felix.utils.extender.AbstractExtender.doStart(AbstractExtender.java:142)
    at org.apache.felix.scr.impl.Activator.doStart(Activator.java:172)
    at org.apache.felix.utils.extender.AbstractExtender.start(AbstractExtender.java:114)
    at org.apache.felix.scr.impl.Activator.restart(Activator.java:142)
    at org.apache.felix.scr.impl.config.ScrConfigurationImpl.configure(ScrConfigurationImpl.java:196)
    at org.apache.felix.scr.impl.config.ScrConfigurationImpl.start(ScrConfigurationImpl.java:117)
    at org.apache.felix.scr.impl.Activator.start(Activator.java:110)
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2238)
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2144)
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984)
    at com.okwant.emap.client.HostActivator.installAndStartSystemBundles(HostActivator.java:82)
    at com.okwant.emap.client.HostActivator.start(HostActivator.java:37)
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
    at org.apache.felix.framework.Felix$SystemBundleActivator.start(Felix.java:4860)
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
    at org.apache.felix.framework.Felix.init(Felix.java:844)
    at org.apache.felix.framework.Felix.init(Felix.java:625)
    at org.apache.felix.framework.Felix.start(Felix.java:963)
    at com.okwant.emap.client.ClientOsgi.setupOsgi(ClientOsgi.java:55)
    at com.okwant.emap.client.ClientFrame.doInit(ClientFrame.java:30)
    at com.okwant.emap.client.ClientApp.<init>(ClientApp.java:21)
    at com.okwant.emap.client.ClientApp.main(ClientApp.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
ERROR StatusLogger Unable to create custom ContextSelector. Falling back to default.
 java.lang.ClassCastException: Cannot cast org.apache.logging.log4j.core.osgi.BundleContextSelector to org.apache.logging.log4j.core.selector.ContextSelector
    at java.lang.Class.cast(Class.java:3369)
    at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOf(LoaderUtil.java:201)
    at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOfProperty(LoaderUtil.java:226)
    at org.apache.logging.log4j.core.impl.Log4jContextFactory.createContextSelector(Log4jContextFactory.java:97)
    at org.apache.logging.log4j.core.impl.Log4jContextFactory.<init>(Log4jContextFactory.java:58)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:94)
    at com.okwant.emap.impl.ui.UIImpl.<clinit>(UIImpl.java:18)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:237)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:109)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:906)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:879)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:749)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:675)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:430)
    at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657)
    at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341)
    at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:390)
    at org.apache.felix.scr.impl.Activator.access$200(Activator.java:54)
    at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:265)
    at org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:254)
    at org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:227)
    at org.apache.felix.utils.extender.AbstractExtender.addingBundle(AbstractExtender.java:187)
    at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:469)
    at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:415)
    at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
    at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
    at org.osgi.util.tracker.BundleTracker.open(BundleTracker.java:156)
    at org.apache.felix.utils.extender.AbstractExtender.startTracking(AbstractExtender.java:150)
    at org.apache.felix.utils.extender.AbstractExtender.doStart(AbstractExtender.java:142)
    at org.apache.felix.scr.impl.Activator.doStart(Activator.java:172)
    at org.apache.felix.utils.extender.AbstractExtender.start(AbstractExtender.java:114)
    at org.apache.felix.scr.impl.Activator.restart(Activator.java:142)
    at org.apache.felix.scr.impl.config.ScrConfigurationImpl.configure(ScrConfigurationImpl.java:196)
    at org.apache.felix.scr.impl.config.ScrConfigurationImpl.start(ScrConfigurationImpl.java:117)
    at org.apache.felix.scr.impl.Activator.start(Activator.java:110)
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2238)
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2144)
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984)
    at com.okwant.emap.client.HostActivator.installAndStartSystemBundles(HostActivator.java:82)
    at com.okwant.emap.client.HostActivator.start(HostActivator.java:37)
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
    at org.apache.felix.framework.Felix$SystemBundleActivator.start(Felix.java:4860)
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
    at org.apache.felix.framework.Felix.init(Felix.java:844)
    at org.apache.felix.framework.Felix.init(Felix.java:625)
    at org.apache.felix.framework.Felix.start(Felix.java:963)
    at com.okwant.emap.client.ClientOsgi.setupOsgi(ClientOsgi.java:55)
    at com.okwant.emap.client.ClientFrame.doInit(ClientFrame.java:30)
    at com.okwant.emap.client.ClientApp.<init>(ClientApp.java:21)
    at com.okwant.emap.client.ClientApp.main(ClientApp.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

I managed to do achieve a similar thing by:

  1. Storing the thread's context classloader
  2. Setting the thread's context class loader to the "current" one (in your case, the OSGI bundle one?)
  3. Initializing log4j
  4. Setting the thread's context class loader to the stored one
    ClassLoader contextClassLoader =
        Thread.currentThread().getContextClassLoader();
    Logger mine;
    LoggerContext loggerContext;
    try {
      Thread.currentThread().setContextClassLoader(Foo.class.getClassLoader());
      loggerContext = (LoggerContext) LogManager.getContext(null,
          true, new File("log4j2_2.xml").toURI());

      mine = loggerContext.getLogger("internal");
    } finally {
      if (contextClassLoader != null) {
        Thread.currentThread().setContextClassLoader(contextClassLoader);
      }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM