由于 karaf

问题描述

考虑以下场景,其中我遇到了意外错误并且无法修复它。

在 Opendaylight 原型项目中,当我在 pom.xml 中只声明一个依赖项(即 io-example)时,我只使用了一个类(比如来自 io-example 依赖项的 test.class),没有错误

但是如果我在 pom.xml 中再添加一个依赖项 (io-example-api),我会得到 java.lang.NoClassDefFoundError: io/example/test.class 在 org.opendaylight.gnmi.impl.base.OpenconfigInter ………………………………………………………………………………………………………………………………………………………… ………………………………………………………………………………………………………………………………………………………… 引起:java.lang.classNotFoundException:org.opendaylight 找不到 io.example.Test

我发现io.example-api有io-example作为依赖..总结一下问题,如果我在pom.xml中只有io-example,没有问题。如果我在 pom.xml 中有 io-example 和 io-example-api,我会收到 NoclassDef 错误

即使我在依赖项部分尝试了排除选项,也没有任何效果

提前致谢...

已编辑:

类名:io.grpc.Context

依赖:

<dependency>
           <groupId>io.grpc</groupId>
            <artifactId>grpc-context</artifactId>
            <version>1.38.0</version>
       </dependency>

       <dependency>
             <groupId>io.grpc</groupId>
             <artifactId>grpc-api</artifactId>
             <version>1.38.0</version>
       </dependency>

在 karaf 容器中,我运行了“package:exports”命令,结果是,

opendaylight-user@root>package:exports -p io.grpc
 
        io.grpc   0.0.0  354 wrap_file__home_verizon_gnmi_gnmi_karaf_target_assembly_system_io_grpc_grpc-api_1.38.0_grpc-api-1.38.0.jar

    io.grpc   0.0.0  355 wrap_file__home_verizon_gnmi_gnmi_karaf_target_assembly_system_io_grpc_grpc-context_1.38.0_grpc-context-1.38.0.ja



opendaylight-user@root>package:exports -d
       io.grpc  0.0.0  354 355

You can see that,io.grpc package exported by two bundles (354 and

355)..

解决方法

OSGi 和 Karaf 中 ClassNotFoundException 的一个常见原因是多个包导出具有相同版本的相同包。这会导致仅导入其中一个,其中可能包含也可能不包含您的 Test 类。

使用 package:exports 命令检查哪些包导出 io.example:

packages:exports -p io.example

我猜测添加依赖项会导致您的包从 io.example 而不是 io-example-api 导入包 io-example

对此的解决方案是确保只有一个包导出 io.example 包。

[编辑] 我不熟悉 grpc,但似乎有 issue on github 和一些您可以查看的解决方法。

您还可以尝试创建一个包,嵌入这些有问题的依赖项并导出包以供其他包使用。

  1. 使用原型 karaf-bundle-archetype 创建一个新的捆绑项目
  2. 添加 grpc-contextgrpc-api 依赖项
  3. 配置 maven-bundle-plugin 以 emped grpc 依赖项并导出 io.grpc 包及其子包。
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>${maven-bundle-plugin.version}</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>
                ${project.groupId}.${project.artifactId}
            </Bundle-SymbolicName>
            <Bundle-Version>${project.version}</Bundle-Version>
            <Bundle-Activator>com.example.Activator</Bundle-Activator>
            <Import-Package>
                *;resolution:=optional
            </Import-Package>
            <Export-Package>
                io.grpc*;-split-package:=merge-first
            </Export-Package>
            <Emped-Dependency>
                grpc-context;scope=compile|runtime;inline=true,grpc-api;scope=compile|runtime;inline=true
            </Emped-Dependency>
        </instructions>
    </configuration>
</plugin>

成功地将包安装到 Karaf 4.2.11 并在包和另一个包中“使用”导出的 io.grpc.Context 类。

简单地从两个捆绑包的激活器中调用这个

Context grpcContext = Context.current();
System.out.println(grpcContext.getClass().getName());

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...