grpc-java: grpc-core and grpc-context jars exporting the same package doesnt go well with OSGI

Please answer these questions before submitting your issue.

What version of gRPC are you using?

GRPC version 1.1.2

What JVM are you using (java -version)?

1.8

What did you do?

I am trying to add a GRPC Server into Karaf OSGI Container as a feature. To this library, grpc-core and grpc-context libraries are dependencies.

Because these jars are not OSGI bundles, the osgi wrap is performed. While running the application, we get an error that io.grpc.Context could not be found in bundle grpc-core.jar (NoClassDefFoundError)

For information please refer to the OSGI bundle definitions.

karaf@root()> la |grep -i grpc-core 83 | Active | 80 | 0 | wrap_file__home_apache-karaf-4.0.8_data_kar_mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT_io_grpc_grpc-core_1.1.2_grpc-core-1.1.2.jar

karaf@root()> bundle:headers 83

wrap_file__home_apache-karaf-4.0.8_data_kar_mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT_io_grpc_grpc-core_1.1.2_grpc-core-1.1.2.jar (83)

Bnd-LastModified = 1486762343975 Built-By = root Built-JDK = 1.8.0_45 Created-By = 1.8.0_121 (Oracle Corporation) Generated-By-Ops4j-Pax-From = wrap:file:/home/apache-karaf-4.0.8/data/kar/mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT/io/grpc/grpc-core/1.1.2/grpc-core-1.1.2.jar Implementation-Title = grpc-core Implementation-Version = 1.1.2 Manifest-Version = 1.0 Source-Compatibility = 1.6 Target-Compatibility = 1.6 Tool = Bnd-2.3.0.201405100607

Bundle-ManifestVersion = 2 Bundle-Name = wrap_file__home_apache-karaf-4.0.8_data_kar_mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT_io_grpc_grpc-core_1.1.2_grpc-core-1.1.2.jar Bundle-SymbolicName = wrap_file__home_apache-karaf-4.0.8_data_kar_mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT_io_grpc_grpc-core_1.1.2_grpc-core-1.1.2.jar Bundle-Version = 0 Require-Capability = osgi.ee;filter:=(&(osgi.ee=JavaSE)(version=1.6))

Export-Package = io.grpc;uses:=“com.google.common.base,com.google.errorprone.annotations,javax.annotation,javax.net.ssl”, io.grpc.inprocess;uses:=“com.google.instrumentation.stats,io.grpc,io.grpc.internal”, io.grpc.internal;uses:=“com.google.common.base,com.google.instrumentation.stats, io.grpc,javax.annotation”, io.grpc.util;uses:=“io.grpc,javax.annotation” Import-Package = com.google.common.base;resolution:=optional, com.google.common.io;resolution:=optional, com.google.common.util.concurrent;resolution:=optional, com.google.errorprone.annotations;resolution:=optional, com.google.instrumentation.stats;resolution:=optional, javax.annotation;resolution:=optional, javax.net.ssl;resolution:=optional

karaf@root()> la |grep -i grpc-context 82 | Active | 80 | 0 | wrap_file__home_apache-karaf-4.0.8_data_kar_mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT_io_grpc_grpc-context_1.1.2_grpc-context-1.1.2.jar

karaf@root()> bundle:headers 82

wrap_file__home_apache-karaf-4.0.8_data_kar_mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT_io_grpc_grpc-context_1.1.2_grpc-context-1.1.2.jar (82)

Bnd-LastModified = 1486762343849 Built-By = root Built-JDK = 1.8.0_45 Created-By = 1.8.0_121 (Oracle Corporation) Generated-By-Ops4j-Pax-From = wrap:file:/home/apache-karaf-4.0.8/data/kar/mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT/io/grpc/grpc-context/1.1.2/grpc-context-1.1.2.jar Implementation-Title = grpc-context Implementation-Version = 1.1.2 Manifest-Version = 1.0 Source-Compatibility = 1.6 Target-Compatibility = 1.6 Tool = Bnd-2.3.0.201405100607

Bundle-ManifestVersion = 2 Bundle-Name = wrap_file__home_apache-karaf-4.0.8_data_kar_mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT_io_grpc_grpc-context_1.1.2_grpc-context-1.1.2.jar Bundle-SymbolicName = wrap_file__home_apache-karaf-4.0.8_data_kar_mvm-core-grpcapi-17.6.0-rel.3-SNAPSHOT_io_grpc_grpc-context_1.1.2_grpc-context-1.1.2.jar Bundle-Version = 0

Require-Capability = osgi.ee;filter:=(&(osgi.ee=JavaSE)(version=1.6))

Export-Package = io.grpc

As you can notice, the problem seems to be because of the same export-packages defined in grpc-core and grpc-context which doesnt seem to go well with OSGI.

I reverted my GRPC version to 1.0.0 in which the jars were broken down to core and context and it worked well.

So the requests are as below:

a) A single jar which includes both core and context b) If context is intended to be separate, i suggest different packages be used in context so that there wont be a collision on the export-packages.

Is there a plan to create a OSGI bundle for these jars?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 16 (5 by maintainers)

Commits related to this issue

Most upvoted comments

I also faced the same problem when deploying gRPC in karaf container. At present I have a solution as follows:

  1. First I use the maven-bundle-plugin and its Export-package instruction to merge the packages in grpc-core and grpc context:
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>3.0.1</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Export-Package>
                io.grpc;version="${grpc.package.version}",
                io.grpc.inprocess;version="${grpc.package.version}",
                io.grpc.internal;version="${grpc.package.version}",
                io.grpc.util;version="${grpc.package.version}"
            </Export-Package>
            <Import-Package>!com.google.errorprone.annotations,*</Import-Package>
        </instructions>
    </configuration>
</plugin>
  1. Then the wrap deployer can be used to “hot deploy” non-OSGi jar files, edit feature.xml as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
    <feature name="${project.artifactId}" version="${project.version}"
             description="${project.description}">
        <feature version="${project.version}">grpc</feature>
        <bundle>mvn:com.google.protobuf/protobuf-java/${protobuf.version}</bundle>
        <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
    </feature>

    <feature name="grpc-netty" version="${project.version}"
             description="gRPC Netty dependencies">
        <bundle>mvn:io.netty/netty-common/${grpc.netty.version}</bundle>
        <bundle>mvn:io.netty/netty-buffer/${grpc.netty.version}</bundle>
        <bundle>mvn:io.netty/netty-transport/${grpc.netty.version}</bundle>
        <bundle>mvn:io.netty/netty-handler/${grpc.netty.version}</bundle>
        <bundle>mvn:io.netty/netty-codec/${grpc.netty.version}</bundle>
        <bundle>mvn:io.netty/netty-codec-http/${grpc.netty.version}</bundle>
        <bundle>mvn:io.netty/netty-codec-http2/${grpc.netty.version}</bundle>
        <bundle>mvn:io.netty/netty-resolver/${grpc.netty.version}</bundle>
    </feature>

    <feature name="grpc" version="${project.version}" description="gRPC dependencies">
        <feature version="${project.version}">grpc-netty</feature>
        <bundle>wrap:mvn:io.grpc/grpc-protobuf-lite/${grpc.version}$Bundle-SymbolicName=io.grpc.grpc-protobuf-lite&amp;Bundle-Version=${grpc.package.version}</bundle>
        <bundle>wrap:mvn:io.grpc/grpc-protobuf/${grpc.version}$Bundle-SymbolicName=io.grpc.grpc-protobuf&amp;Bundle-Version=${grpc.package.version}</bundle>
        <bundle>wrap:mvn:io.grpc/grpc-stub/${grpc.version}$Bundle-SymbolicName=io.grpc.grpc-stub&amp;Bundle-Version=${grpc.package.version}</bundle>
        <bundle>wrap:mvn:io.grpc/grpc-netty/${grpc.version}$Bundle-SymbolicName=io.grpc.grpc-netty&amp;Bundle-Version=${grpc.package.version}</bundle>
        <!--<bundle>wrap:mvn:io.grpc/grpc-auth/${grpc.version}$Bundle-SymbolicName=io.grpc.grpc-auth&amp;Bundle-Version=${grpc.package.version}&amp;Import-Package=!com.google.auth,*</bundle>-->
        <bundle>wrap:mvn:io.grpc/grpc-auth/${grpc.version}$Bundle-SymbolicName=io.grpc.grpc-auth&amp;Bundle-Version=${grpc.package.version}</bundle>
        <bundle>wrap:mvn:com.google.instrumentation/instrumentation-api/0.3.0$Bundle-SymbolicName=com.google.instrumentation.instrumentation-api&amp;Bundle-Version=${google.instrumentation.version}</bundle>
    </feature>
</features>
  1. Refer to: gRPC demo for full application.

Note: the generated code also can run afoul of Java 9 modules. If nothing else, the gRPC generated code is frequently in a separate JAR from the protobuf generated code, but the two exist in the same package.