ClassCastException 在应用程序中使用 log4j 嵌入 osgi felix 而捆绑包使用 log4j
Posted
技术标签:
【中文标题】ClassCastException 在应用程序中使用 log4j 嵌入 osgi felix 而捆绑包使用 log4j【英文标题】:ClassCastException when using log4j in app embedding osgi felix while bundles use log4j 【发布时间】:2017-09-25 20:56:53 【问题描述】:我有一个嵌入 felix osgi 容器的 java 应用程序。 Java 应用程序使用 log4j 2.8.2。
我的一个 osgi 实现包也使用 log4j。因此,我将 jars log4j-api-2.8.2 和 log4j-core-2.8.2 添加到 osgi 系统:
bundleContext.installBundle()
然后使用以下命令开始捆绑:
bundle.start()
安装捆绑包工作正常。除了包“org.apache.felix.scr”的开头抛出异常:
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
我怀疑这是因为 felix SCR 正在尝试加载我使用 log4j 的实现包。而且因为我的应用程序(嵌入 felix 的应用程序)使用 log4j 并且可能使用 ContextSelector。 osgi 可能使用 BundleContextSelector。因此例外。
我想知道我该如何解决这个问题?
我已经尝试将我的应用程序的 ContextSelector 设置为 osgi 的:
System.setProperty("Log4jContextSelector",
"org.apache.logging.log4j.core.osgi.BundleContextSelector")
但那里没有运气。我还尝试生成一个新线程来设置 osgi/felix。我的想法不多了。
我目前已将我的应用程序从 log4j 切换到 java util logging。我的实现 osgi 包可以通过这种方式毫无问题地使用 log4j。
以下是完整的异常跟踪仅供参考:
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)
【问题讨论】:
【参考方案1】:我设法通过以下方式实现了类似的目标:
-
存储线程的上下文类加载器
将线程的上下文类加载器设置为“当前”类加载器(在您的情况下,是 OSGI 捆绑包吗?)
初始化 log4j
将线程的上下文类加载器设置为存储的类加载器
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);
【讨论】:
以上是关于ClassCastException 在应用程序中使用 log4j 嵌入 osgi felix 而捆绑包使用 log4j的主要内容,如果未能解决你的问题,请参考以下文章
android应用程序中的ClassCastException
Java HashMap导致ClassCastException
android.widget.ProgressBar.onRestoreInstanceState 中无法解释的 ClassCastException
如何在模块化的 java 11 应用程序中动态加载 Libreoffice jar,而不从自定义类加载器中获取 ClassCastException