Open CodingFabian opened 8 years ago
We don't have any OSGi
experience on our team. This is something we would probably need a contribution for.
We currently have shared code for setting the manifest. It is possible to use project-specific pre-existing variables to tune the behavior, like we do with POMs.
Hi
Although this issue is still open, there hasn't been any activity for 5 years. Would contributions to it be accepted?
@ejona86 As you suggested and as described here , I implemented a grpc-java generator plugin for generating a java interface. So far, all of the code-generation is java only (i.e. a java 8 interface with default) using the Salesforce work for connecting the grpc flow control to reactivex Flowable (for streaming). But since OSGi services are interface-based, this generated interface can be used as the contract for the OSGi Remote Service.
This now can be used with bndtools (bndtools.org)...and Eclipse...to easily generate a remote service api (via protoc + grpc, rxjava, and grpc-osgi protoc plugins) to generate java code that can easily be used as an OSGi remote service.. Showing is easier so please see a short video here: https://www.youtube.com/watch?v=4-f4xQBlKr0
Currently, however, since gRPC does not yet produce OSGi manifest meta-data on build, it's necessary for me to embed the gRPC jars into the ECF gRPC distribution provider to get them to run in an OSGi environment. It would be much nicer for consumers and for me for gRPC-java to add manifest meta-data in build (as does protoc, rxjava, and other popular libs) so that they don't have to be embedded in order to be used in OSGi runtime. Thus my interest in contributing to this issue.
I would be willing to contribute additions to the grpc-java build to add manifest.mf meta-data for osgi usage (wihich doesn't effect java usage at all btw), but I would lke to have some assurance from this team that such contributions would be accepted and properly integrated. Is there a particular grpc committer/commiters that handle the build stuff? (appears to be gradle/maven afaict). BTW, osgi meta-data should not be necessary for grpc-java generator. In fact it's probably needed for only 2-3 grpc-java jars.
Using a new Eclipse build technology, that allows for 'automatic' but configurable 'wrapping' of plain 'ol jars as OSGi bundles (with OSGi headers in MANIFEST.MF) I created bundles from the maven-published grpc-java artifacts version 1.39.0.
they resulted in jars with names: wrapped.io.grpc.*.jar in this directory: https://github.com/ECF/grpc-RemoteServicesProvider/tree/master/build/plugins
Note that several of the dependencies of grpc are also 'wrapped' (e.g. perfmark and others...the ones that are not currently OSGi bundles in maven central). These 'wrapped' grpc jars function fully/correctly in an OSGi environment.
There were a couple of changes introduced by defining this .target file: https://github.com/ECF/grpc-RemoteServicesProvider/blob/master/releng/org.eclipse.ecf.provider.grcp.target/ecf-2021-06.target and this new Eclipse build technology that reads the original jar from maven, applies and custom instructions and creates a 'wrapped' version of the jar with an OSGi Manifest. If you look in the target file given you will see some of the instructions that had to be applied to create proper bundles out of grpc 1.39.0 jars are bnd meta-data, which is the same meta-data that can be used with the maven bnd plugin: https://mvnrepository.com/artifact/org.apache.felix/maven-bundle-plugin. What this means is that instructions similar to what are in the target file in my example can be put into the maven bnd plugin and run as part of the grpc build to produce OSGi bundles (jars with an enhanced manifest).
The biggest complication of doing this was the fact that grpc uses the java ServiceLoader to allow for extending grpc (e.g. netty ServerProvider, ManagedChannelProvider, and others). The ServiceLoader is difficult for OSGi to handle as it expects a flat class namespace rather than bundle-specific classloading...so services can be loaded from provider jars. OSGi has, however a spec to deal with the ServiceLoader in OSGi, and there is an implementation of this spec in the bundle: org.apache.aries.spifly.dynamic.bundle. When I use this impl in combination with grpc it works just fine.
If there is someone from grpc willing to work on the build, I would be able to provide the mavn bnd plugin meta-data to allow the creation of OSGi meta-data as part of the grpc build.. Which would then make it unnecessary, of course, to do what I'm currently doing in creating 'wrapped' bundles.
I've created a grpc plugin here: https://github.com/ECF/grpc-osgi-generator that is a grpc-protoc plugin that generates an OSGi service interface (Java8 interface class) from a normal grpc proto file.
For the streaming methods it generates java code that use the reactivex api Flowable and Single classes, and used the Salesforce reactive-grpc implementation to generate implementation classes.
Along with Eclipse + bndtools to run the code generation automatically as part of an Eclipse build, this results in a very nice/automated workflow for generating nearly everything necessary to define, implement and use an OSGi remote service.
Here four videos describing this workflow:
Part 1 - API Generation Part 2 - Remote Service Implementation Part 3 - Remote Service Consumer Part 4 - Remote Service Debugging
There is apparently a move afoot transfer the reactive-grpc project (originally started by Salesforce folks) to the grcp ecosystem:
https://github.com/salesforce/reactive-grpc/issues/306#issuecomment-1407789303
If reactivex-grpc moves to the grpc ecosystem, and if desired by grpc osgi fans, I'm willing to consider donating the ECF https://github.com/ECF/grpc-osgi-generator to the grpc-osgi-generator as well. And I will support it/enhance it if desired (for example, the grpc-osgi-generator could also generate osgi bundle meta-data...in manifest.mf primarily but other meta-data as well...perhaps in a separate protoc plugin).
It would make using gRPC in an OSGi container easier if the jar files would contain the required OSGi headers. This can be as easy as using the
maven-bundle-plugin
. Unfortunately, I am not versed in gradle, so I am unable to provide a patch right now. Is this something you can consider for addition?