当前位置: 首页 > 知识库问答 >
问题:

在Android中嵌入OSGi Felix原因在Un的操作异常:无法加载这种类型的类文件

锺离昂然
2023-03-14

我有一个Android项目,它嵌入并启动了一个基于felix的小型OSGi项目。为了调试,我使用带有Android 8.0、API 26的Nexus 5X模拟器。我使用声明性服务,因此我的项目基于felix.main、felix.scr和felix.configadmin.所有捆绑包都被定义了。安装捆绑包工作正常,但是如果我通过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(基于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\"");

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

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

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

我找到了一个类似的帖子,它通过遵循Apache Felix教程步骤得到解决。不错,但我也做了同样的事情,而且还发生了错误。

我在过去的几天里尝试了很多,我在过去的几天里阅读了很多,但是我想我发现的并不符合我的问题。请帮帮忙!先谢谢你了!

更新 08.08.17:

我试图根据Balazs Zsoldos的回答找到最初的异常,结果是:异常在getClassByDelegation(字符串名称)的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中,为什么不能解析object类?我检查了包jar中的dex文件及其条目名(可能是绝对路径问题,Balazs Zsoldos提到过)。好吧!没有隐藏的添加。有人能帮忙吗,或者有人有类似的问题和解决方法吗?

更新10.08.17

我想知道的是,为什么只有felix捆绑包会抛出异常。菲利克斯·梅恩捆绑包和我自己的工作都很好,他们都很活跃。为什么我自己的基于声明性服务的捆绑包是活动的,即使felix scr捆绑包没有启动(状态已解析)。似乎felix scr尚未处于主动状态,无法解决对felix scr的依赖。无论如何,为什么索引化的felix libs和我自己的工作都失败了?请帮帮我,我绝望了!

更新 11.08.2017

今天,我尝试在物理Android设备(索尼XPERIA Z2和Android4.4.4,API 19)上运行和调试我的项目,它是有效的。所有捆绑包都处于活动状态。最后几天,我使用了Android8.0、API 26的Nexus 5X模拟器,所以我编辑了我的帖子来添加这些信息。它似乎在很大程度上取决于设备和/或Android版本和API。疯狂!

共有1个答案

商昂然
2023-03-14

您最大的问题是,由于Apache Felix:https://issues.apache.org/jira/browse/FELIX-5643的一个bug,您无法知道最初的异常

如果在基于Android的类加载期间出现异常

  • 异常被吞入
  • Felix返回到正常的JDK类加载机制,该机制抛出您看到的异常

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

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

第一个解决方案让我们很累,因为我们必须打开和关闭异常停止功能。在许多捆绑包中,有一个失败了,在调试过程中很难找到正确的捆绑包。因此,我们只需将BundleWiringImpl类的内容复制到Android开发人员工作室中,并将其更改为注销被吞噬的异常。通过这样做,我们能够在日志中看到原始异常。

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

 类似资料:
  • 问题内容: 我正在编写一些JUnit测试,以验证是否抛出了类型异常。但是,此异常多次包装在其他异常中,例如InvocationTargetException中,而InvocationTargetException又包装在RuntimeException中。 确定MyCustomException是否导致我实际捕获的异常的最佳方法是什么?我想做这样的事情(见下划线): 我想避免称呼一些“层”较深的类

  • 不能使用< code>add或< code>remove等方法修改由< code>Arrays.asList返回的< code>List。但是如果您将它传递给< code>Collections.sort方法,它可以毫无问题地对数组进行排序(我预计会出现异常)。这似乎是一种非常不一致的行为。那么< code>List上允许的操作是什么呢,它由< code>asList方法返回? 我在文档中找不到这

  • 我正在尝试通过DriverManagerDatasorce的数据源对象创建JDBC连接。每次我运行应用程序时 引起的原因:org.springframework.beans.属性BatchUpdateExc的;嵌套的属性AccessExceptions(1)是:属性的访问异常1:org.springframework.beans.方法调用异常:属性'driverClassName'抛出的异常;嵌套

  • SBT将编译后的scala文件放在目标/scala文件夹中- 据我所知,类文件包含JVM字节码。它们与语言无关。 那么,文件夹使用语言名称的原因是什么?我希望Scala和Java的类字段都位于同一个目录中。

  • 原子操作 是个不可分割的操作。 在系统的所有线程中,你是不可能观察到原子操作完成了一半这种情况的; 它要么就是做了,要么就是没做,只有这两种可能。 如果从对象读取值的加载操作是 原子 的,而且对这个对象的所有修改操作也是 原子 的, 那么加载操作得到的值要么是对象的初始值,要么是某次修改操作存入的值。 另一方面,非原子操作可能会被另一个线程观察到只完成一半。 如果这个操作是一个存储操作,那么其他线

  • 如果我们不想付出构建语法分析树的开销,或者想要在分析期间动态地计算值或把东西打印出来,那么可以通过在语法中嵌入任意代码实现。它的比较困难的,因为我们必须明白在语法分析器上的操作的影响,以及在哪里放置这些操作。 为了解释嵌入在语法中的操作,让我们先来看下文件rows.txt中的数据: parrt Terence Parr 101 tombu Tom Burns 020 bk