【问题标题】:Embed OSGi Felix in Android causes in UnsupportedOperationException: can't load this type of class fileEmbed OSGi Felix in Android 导致 UnsupportedOperationException: can't load this type of class file
【发布时间】:2018-01-11 03:36:19
【问题描述】:

我有一个使用 AndroidStudio 和 Gradle 开发的 android 项目,它嵌入并启动了一个基于 felix 的小型 OSGi 项目。为了调试,我使用带有 Android 8.0、API 26 的 Nexus 5X 模拟器。我使用声明式服务,因此我的项目基于 felix.main、felix.scr 和 felix.configadmin。所有的bundle都是dexified。安装捆绑包工作正常,但如果我通过 bundle.start() 启动捆绑包,我会收到以下关于 felix.scr 和 felix.configadmin 的错误消息(felix.main 和我自己的捆绑包工作正常 -> 状态处于活动状态):

08-03 13:58:00.880 19745-19745/android.cit.tu_berlin.de.helloandroid W/zygote: Skipping duplicate class check due to unrecognized classloader
    08-03 13:58:00.881 19745-19745/android.cit.tu_berlin.de.helloandroid E/OSGIService: catch exception while starting bundle:
    08-03 13:58:00.881 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err: org.osgi.framework.BundleException: Activator start error in bundle org.apache.felix.configadmin [2].
    08-03 13:58:00.881 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.Felix.activateBundle(Felix.java:2276)
    08-03 13:58:00.881 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.Felix.startBundle(Felix.java:2144)
    08-03 13:58:00.881 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
    08-03 13:58:00.881 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984)
    08-03 13:58:00.881 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.cit.tu_berlin.de.helloandroid.OSGIService.startBundle(OSGIService.java:386)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.cit.tu_berlin.de.helloandroid.OSGIService.runSensorVisualisationPlugin(OSGIService.java:248)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.cit.tu_berlin.de.helloandroid.OSGIService.onStartCommand(OSGIService.java:158)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3539)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.app.ActivityThread.-wrap20(Unknown Source:0)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:105)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.os.Looper.loop(Looper.java:164)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6540)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err: Caused by: java.lang.UnsupportedOperationException: can't load this type of class file
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at java.lang.ClassLoader.defineClass(ClassLoader.java:591)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.defineClass(BundleWiringImpl.java:2370)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2154)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1542)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:79)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1415)
    08-03 13:58:00.882 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4468)
    08-03 13:58:00.883 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:     at org.apache.felix.framework.Felix.activateBundle(Felix.java:2221)
    08-03 13:58:00.883 19745-19745/android.cit.tu_berlin.de.helloandroid W/System.err:  ... 15 more

gradle 脚本有以下语句用于解析对 felix jar 的依赖:

provided fileTree(dir: 'src/main/assets/bundles/', include: ['*.jar'])
// for finding Felix.class
compile group: 'org.apache.felix', name: 'org.apache.felix.framework', version: '5.4.0'

我需要将以下属性设置为 felix 以解决对 osgi.ee 的缺失要求(基于 post 中 Christian Schneider 的回答):

configMap.put(Constants.FRAMEWORK_SYSTEMCAPABILITIES, "osgi.ee; osgi.ee=\"JavaSE\";version:List=\"1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8\"");

我想知道该错误是否与 post 相关,特别是与“项目构建路径的参考库条目”部分有关(基于 post 中 Alec B. Plumb 的回答),因为我不知道'不知道为什么“我的”错误报告的第一行说

W/zygote: Skipping duplicate class check due to unrecognized classloader

为什么要重复类?每个库都存在一次,除了 gradle 之外,没有其他项目设置或依赖链接。

我发现了一个类似的post,它通过遵循 Apache Felix 教程步骤解决。很好,但我做了同样的事情,并且错误发生了。

最近几天我尝试了很多,最后几天阅读了很多,但我想我发现的内容与我的问题不符。请帮忙!并提前非常感谢!

08.08.17 更新:

我试图根据 Balazs Zsoldos 的回答找到原始异常,结果如下: getClassByDelegation(String name)中的BundleWiringImpl.class中抛出异常:

public Class getClassByDelegation(String name) throws ClassNotFoundException {
        if(name != null && name.length() > 0 && name.charAt(0) == 91) {
            return Class.forName(name, false, this.getClassLoader());
        } else if(this.isFiltered(name)) {
            throw new ClassNotFoundException(name);
        } else {
            ClassLoader cl = this.getClassLoaderInternal();
            if(cl == null) {
                throw new ClassNotFoundException("Unable to load class \'" + name + "\' because the bundle wiring for " + this.m_revision.getSymbolicName() + " is no longer valid.");
            } else {
                return cl.loadClass(name);
            }
        }
    }

最后一行 (cl.loadClass(name)) 抛出异常。为了完整起见,此处的值:

cl = org.apache.felix.configadmin
name = org.apache.felix.cm.impl.ConfigurationManager

不幸的是,我无法调试该方法,所以我停在那里并将 AndroidStudio 设置为捕获所有异常。下一站是由 DexFile.class 中抛出的异常引起的

cause = java.lang.ClassNotFoundException: java.lang.Object
detailedMessage = Failed resolution of: Ljava/lang/Object

那是什么鬼?为什么在 DexFile.class 中以及为什么无法解析对象类?我检查了捆绑 jar 中的 dex 文件及其条目名称(可能是绝对路径问题,Balazs Zsoldos 提到)。好的!没有隐藏的添加。任何人都可以帮助或是否有人有类似的问题以及如何解决的想法?

10.08.17 更新

我想知道为什么只有 felix 包会抛出异常。 Felix-Main 捆绑包和我自己的工作正常,它们处于活动状态。为什么即使 felix-scr 包没有启动(状态已解决),我自己的基于声明性服务的包也可能处于活动状态。似乎 felix-scr 尚未处于激活状态以解决对 felix-scr 的依赖。 无论如何,为什么dexified felix libs和我自己的工作失败了?请帮忙,我很绝望!

11.08.2017 更新

今天我尝试在物理 android 设备(Sony XPERIA Z2 with Android 4.4.4, API 19)上运行和调试我的项目,它可以工作。所有捆绑包都处于活动状态。最近几天,我使用 Nexus 5X 模拟器和 Android 8.0,API 26,所以我编辑了我的帖子以添加该信息。它似乎在很大程度上取决于设备和/或 android 版本和 API。疯了!

【问题讨论】:

    标签: android gradle osgi activator


    【解决方案1】:

    您最大的问题是由于 Apache Felix 的错误,您无法知道原始异常:https://issues.apache.org/jira/browse/FELIX-5643

    如果在基于 Android 的类加载过程中出现异常

    • 异常被吞下
    • Felix 回退到正常的 JDK 类加载机制,该机制会引发您看到的异常

    我们可以通过两种方式暂时解决这个问题:

    我们确实在 Android Studio 中的 BundleContextImpl.getDexFileClass(...) 函数的开头设置了一个断点,在它停止后,我们确实设置了 Android dev studio 来捕获所有异常。通过这样做,我们能够找到最初的原因。

    第一个解决方案让我们感到疲倦,因为我们不得不打开和关闭异常停止功能。由于许多捆绑包都失败了,因此在调试过程中很难找到正确的捆绑包。因此,我们简单地将BundleWiringImpl类的内容复制到Android开发者工作室中,并修改为注销吞咽异常。通过这样做,我们能够在日志中看到原始异常。

    顺便说一句:最烦人的问题如下。正如教程所说,我们对罐子进行了分类。然而,aapt 命令就是那么丑陋,如果你用绝对 URL 指定 classes.dex 文件,ZIP 的条目将具有相同的名称(如果你使用 Windows,则包括驱动器号)。例如:classes.dex 在 zip 中的条目名称是 c:\classes.dex 并且没有 ZIP 编辑器显示其名称的 _c:_ 部分。因此我们列出了Java中ZIP/JAR的入口名称,并找出真正的入口名称。

    【讨论】:

    • 非常感谢您的回复。我明天去试试,希望能找到原来的原因。但是真的很高兴知道我可以从哪里开始找到错误!这很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2019-05-03
    • 2018-10-21
    • 2016-01-12
    • 1970-01-01
    • 2022-12-27
    • 2016-11-04
    相关资源
    最近更新 更多