How to Add Existing Bundles as Declarative Services Within OSGI Enroute - plugins

I have a folder of existing bundled jars I need to use as declarative services. I'm aware of how to treat these like typical Eclipse Plugins and have them declared inside of the typical Component.xml file inside of my plugin project OSGI-INF folder, but now I'd like to follow the OSGI Enroute style of coding and load my bundles as Declarative Services inside there. It seems like services are added to the generated Component.xml for you with OSGI Enroute when you add the #Component annotation, but I'm struggling to figure out how to bring in my pre-existing bundles as Declarative Services since they don't have the annotations in them and I can't change their code (plus they don't have poms). Is there some intuitive way of solving this that I'm missing? Enroute seems like a great way to handle OSGI otherwise.

If I understood your question right, then:
You have legacy bundles
You can not change the code of those bundles
Services with in those bundles are not Declarative Services (using the #Component annotation)
You want to have those services as Declarative Services
In that case you could write the XML files for the Declarative Services yourself:
Add a new Maven module to your project
Add the legacy bundle(s) as dependency
Add the "hand-written" XML files for those services as sources to the module
Let Maven unpack the legacy bundles
Add the "hand-written" XML files to the new bundle with Maven
Update the MANIFEST.MF of the bundle (if necessary)
Package everything back to a OSGi bundle
In the end the #Component annotation is just used to create XML files during the build describing your Declarative Service. If the code for those old service does not change anymore, it would be reasonable to write the XML files by hand.

Related

dependency web application inside another web application

I have a Spring MVC based rest api API_1. I want to create another api API_2 which will use all the same system vars of API_1. Basically I want to create a separate Spring boot rest service and add it as a dependency to API_1.
Is i possible to do this? I don't want to change packaging type from war to ear.
Only thing is I want this api separate project is because I think this feature can be used by other api's accross the project.
I was thinking if I can somehow load API_2 in API_1 after adding the dependency and some configs in web.xml or pom xml (adding some plugin)
If you don't want to create a jar out of war, you can consider maven overlays
An overlay of a WAR file, is simply a Maven project that uses another
project's WAR output as a dependency, rather than a project's JAR.
When the overlay project is built, the underlying project's WAR file
is exploded and files in the overlay project added to it. If an
overlay project has a file with the same path and name as a file in
the underlying WAR it will replace it.

CQ5 - Separate out a servlet's business logic into a standalone bundle

I am new to java, osgi, bundles, cq5 console etc..
Can someone please point me to a tutorial or a starting point from where I can learn how to do what I am trying to achieve.
Basically we have common search functionality in 3-4 CQ5 websites, all of which reside on a single cq instance. This same functionality is implemented in all websites as a servlet and is called from client side using javascript. Redundant code....
We would like to:
a) take this servlet's code out from all the websiteName-core bundles where it resides repeatedly as of now.
b) create a single separate standalone installable OSGI bundle which only contains a servlet.
Then we would like to call this single separated out bundle from all our CQ5 websites's client side.
Aprt from code redundancy, we wish to make this common search bundle shippable so that other development teams can use it in their projects by just installing it in their console and calling the servlet.
Long story short. I want to create an OSGI bundle that has a servlet.
I wish to have an understanding of the whole game here and would prefer to get a tutorial link that explains it from start to end.
You can start by turning the search code into a separate maven multi module project.The archetype and instructions for creating one can be found on adobe's documentation site (link)
The maven multimodule project will have two module's Bundle and content. Bundle will hold all the servlets, OSGI services and back-end stuff. The content module will have all the UI and authoring related stuff like templates and components. It maps to the repository on the CQ server. The UI nodes are serialized and stored on flat file systems as XML documents.
Since it is a maven project on it's own, it's dependencies will be self contained. In the bundle module add the search servlet and all the required classes. The compiled package of this project will be shippable.
As long as the package is installed in the server, any other website will be able to make calls to it.
Servlets in sling are implemented as OSGI services of javax.servlet.Servlet class. Any exported service of the Servlet class will be recognized by the sling servlet resolver, You can get more details of it at this link
Sharath Madappa's answer is correct if you want to create a set of related bundles and distribute them as a CQ content package.
If you just want to create a single bundle to package some OSGi services (including servlets) you just need to build the bundle jar with the required metadata. The Apache Sling GET servlets bundle is a good example of that.

Verify OSGi bundles dependencies (import-package) programmatically

I need to validate whether the imported packages of a bundle are fulfilled by a set of other bundles' export packages. This should not be very hard to implement but I know all the OSGi containers plus eclipse (when you do "validate bundles" in PDE) do this. I just don't know how to find that code. Does anyone know what classes/libraries I could use that already implement all this logic?
My goal is to give a list of files (bundles) in the file system and do an analysis whether the set of bundles is self-contained and if not to show all the missing external imports/requires. all this without actually having to run the bundles in a real container
You should look at the Resolver API in the OSGi spec. Apache Felix has a resolver implementation that is also used by the Equinox framework.

What's the difference between Eclipse Packages and Plug-ins?

In Dependencies tab, I have a choice between plug-ins and packages.
What's the difference between them? For org.eclipse.compare, I have it in imported package and also in plug-ins.
I find the jar file in plugins directory, but I don't know where the package file of org.eclipse.compare is located.
In the export menu, it seems like that there seems to be only exporting to jar, not exporting a plugin or packages. How can I export packages?
ADDED
Based on this post - How to import a package from Eclipse? and shiplu's answer. This is what I came to understand. Please correct me if I'm wrong.
In eclipse, when I use come external class, I can use Quick-Assistant or Organize imports (Ctrl-Shift-O) to resolve the reference. Eclipse adds the package that contains the class in Imported Packages for the project that I'm working on. A package can contain multiple classes (types). Eclipse understands what plugin contains the package, and resolve the reference issues.
A plug-in (jar file) can contain multiple packages. By specifying a required plug-ins in the dependencies tab, we can reference all the packages (and classes in the packages) for all the java projects in the eclipse IDE.
And from my experience, I had to add all the dependencies in order to make headless RCP standalone (http://prosseek.blogspot.com/2012/12/headless-rcp-standalone.html).
An Eclipse plug-in is basically an OSGi bundle with additional plugin.xml file which Eclipse IDE understands and interprets.
So the answer to your question lies in the OSGi specification and the OSGi programming model, since, very simply put, Eclipse is an Application running on implementation of OSGi called Equinox.
OSGi is all about having modular applications and so it defines several levels of modularity.
One such level is a bundle-level (module-level) modularity and more fine grained level is the package level modularity.
So you can have your OSGi application (a set of bundles; eclipse is just that) which consists of db-bundle (which provides data store services), app-domain-bundle (which provides your application domain services) and remote-bundle (which exposes to the web your application via REST for example).
And then you say remote-bundle depends on domain-bundle which depends on db-bundle.
Which is all good, but cripples the inherent modularity OSGi provides, because you are basically restricting your application to specific implementations of db-bundle and remote-bundle i.e. to specific implementations of the services they provide.
Instead, you can establish the above dependencies not between bundles but between packages i.e. establish a service-level dependencies.
Then you say domain-bundle requires dbstore.service package to run, it doesn't care which bundle provides it it just needs an instance of this service to be able to work. So you can have multiple bundles providing implementations of the dbstore.service, and the domain-bundle can pick and choose at runtime what service to use.
It is really hard to explain OSGi concepts in just a several sentences, I'd really suggest you dig around the web on this and maybe even have a look at the OSGi specification.
Another way to explain it is to say that bundle/plug-in is a jar file with specific structure and metadata descriptors (MANIFEST.MF and plugin.xml), which describe its contents in Java language concepts - which java packages and services this specific jar contains and will expose to the OSGi runtime so that they can be consumed by other bundles. I.e. the bundle is the physical deployable entity while the descriptors are metadata about what actually is being deployed.
EDIT:
Package or Service-level dependencies also have some drawbacks, as Lii points out in the comments below, the main one being that it adds complexity and dynamics to the dependency model. Have a look at her or his comment below - it is worth reading!
You use Imported Packages when you want to use a specific package but do not care which plugin provides it. OSGI will choose one for you.
Eclipse plugins is something like extension to the IDE itself. But imported packages are actually packages that you'll use in your current project.
One is for development IDE another is for the project you are coding.

Exporting Eclipse RAP war with OSGi bundles with external bundle-path

I have an Eclipse RAP product, I like to export as a web app for use inside Tomcat. For this I use the warproduct exporter in Eclipse, which until now have worked fine.
I have a problem with compilation of one of the OSGi bundles in the product as this refers to a set of external jars using a variable substitution. This is shown in the following fragment from a MANIFEST.MF:
Bundle-Name: ...
Bundle-SymbolicName: ...
Bundle-ClassPath2: external:/A/test1/jakarta-tomcat/shared/lib/a_base.jar
Bundle-ClassPath: external:$A_HOME$/jakarta-tomcat/shared/lib/a_base.jar
If I use the first classpath instead and have the correct /A/test1/jakarta-tomcat/shared/lib/a_base.jar in place, then everything is fine during the compilation... And I can even manually change the MANIFEST.MF afterwards to the correct version with the substitution.
But, I would really like to avoid this extra step, if at all possible!
I think the question is how to pass in a proper value for A_HOME during the compilation?
(Why do this? Above, I just shown a single jar file, but we have a larger number of jar files we want to share between our older Tomcat applications and the newer RAP based application. We know, there are other ways of sharing jars in this situation - e.g. via an OSGi framework extender or the extendedFrameworkExports initialization parameter in web.xml - but we need the chosen method as we use EMF and therefore cannot share the EMF meta data between Tomcat and Eclipse... And thus not the class objects...)
this feature is currently not support within the WAR Products Tooling. I recommend to open a bug against Eclipse Libra and to define the feature request their. Anyway, we have created an example how to build a RAP application with tycho which is pretty easy, maybe you want to take a look: https://github.com/eclipsesource/rap-mobile-demos
Cheers Holger