I need to access information about all bundles and services of a remote AEM application (Apache Felix).
Information needed for bundles:
Exported packages and version
Imported packages and version
Bundle status
Information needed for service:
Implemented interface
Ranking
path, resourceTypes, selectors for Servlets
How could we possibly gather all the above information via a Java program?
I cannot deploy any custom remote Service on the OSGi container. Have to gather all the details, only via a Remote Java program executed externally.
Chapter 137 of the OSGi Compendium defines the OSGi REST Management Service. This provides all of the information that you're asking for using standard DTOs in a simple REST model.
The URI framework/bundles will list bundles which can be introspected using framework/bundle/{bundleid}, and framework/services will list services which can be introspected using framework/service/{serviceid}
As requested, this solution does not make use of remote services, but as mentioned in one of the comments there is no way to introspect a remote OSGi framework without installing something. In this case you must add a REST Management Service implementation to the remote framework.
Related
Working on a Java-based large distributed system, so there will be multiple services running across multiple machines .....
Looking for an open source framework to be able to manage these services(e.g. start/stop a service, install a new a service remotely etc.)
Apache Karaf seems to be a good choice, but underneath it uses apache felix (an OSGi reference implementation) bundle which I have a hard time to really understand. In particular, it seems to be easy to define and register a service in felix, but how do you invoke such a service remotely? Do you need to have a separate RPC mechanism to achieve that? There seems to be very few links describe it. In general how do people use OSGi? Is Apache felix out of date?
Any other framework that can be used to manage services assuming I will have my own RPC layer (say RMI based or Netty based)?
I guess you have to specify the way you define a service.
There are services, like remote services that use RPC mechanism, for example EJB remote calls.
Another way to define services is to talk of Web-Services, either using SOAP(XML) or JAXRS(JSON) as transport protocol. And there is the definition of services in OSGi which just means a separation of API (service definition) and implementation. As sum-up you could define OSGi as a SOA for Applications within the same VirtualMachine. (it gives much more, but this is one way to look at it from a service perspective)
Apache Karaf is a OSGi server that is comparable to a Application Server, only it works for OSGi applications. It brings a lot of convenience technologies on top of a choosable OSGi framework. That would be either Apache Felix or Eclipse Equinox. Both are OSGi frameworks that provide the basic OSGi infrastructure - SOA in the same JVM.
Now there are a lot of other benefits of it, like starting and stoping services, updating services.
Taking the RPC into account this can easily be achieved, by combining OSGi-Services with CXF for example. It can easily be configured to export an OSGi service as CXF service. (this is very Karaf/CXF specific)
Apache Karaf itself also supports clustering with Apache Karaf Cellar, which also provides a DOSGi service for easier communication of services across cluster groups. DOSGi stands for Distributed OSGi, which can also be achieved by using CXF and much other implementations.
Apache Felix and OSGi in general are far away of being out-of-date. A lot of Java EE Application servers use OSGi as their underlying technology to be modular and have a smaller footprint.
That would be GlassFish, Websphere, Geronimo etc...
Is it possible to create a client that accesses an EJB3 bean, with the client having no dependence on a vendor JAR or configuration? We currently need to support scenarios where our service is deployed on a WebSphere or JBoss server, and the client is deployed as an application either on a WAS or JBoss, or is running as a standalone app.
I used to be able to do to this with EJB2.x beans, I just needed to create stubs using RMIC.
But with EJB3, If I'm connecting to WebSphere I have to include thinclient JARs, plus I have to pre-generate the stubs using WAS tools. For JBoss I have to use jboss-client.jar.
No, this is not possible. This has been made explicit in section 10 of the EJB 3.2 specification:
This chapter describes the interoperability support for accessing an
enterprise bean through the EJB 2.1 remote client view from clients
distributed over a network, and the distributed interoperability
requirements for invocations on enterprise beans from remote clients
that are Java Platform, Enterprise Edition (Java EE) components.
Distributed Interoperability is not defined for the EJB 3.x remote client view.
Also note section 10.5.5:
System value classes are serializable value classes implementing the
javax.ejb.Handle, javax.ejb.HomeHandle, javax.ejb.EJBMetaData,
java.util.Enumeration,java.util.Collection, and java.util.Iterator
interfaces. These value classes are provided by the EJB container
vendor. They must be provided in the form of a JAR file by the
container hosting the referenced bean. For interoperability scenarios,
if a referencing component would use such system value classes at
runtime, the Deployer must ensure that these system value classes
provided by the container hosting the referenced bean are available to
the referencing component. This may be done, for example, by including
these system value classes in the classpath of the referencing
container, or by deploying the system value classes with the
referencing component’s application by providing them to the
deployment tool.
For WebSphere Application Server, the EJB thinclient contains these system value classes as well as the IBM JNDI implementation that uses CosNaming. In theory, this thinclient is not needed if you don't need the system value classes and your client JVM has its own ORB with an implementation of CosNaming.
Short answer: No, it's not possible, as a client needs three things:
The interface classes.
The client libraries of the server AS (yes, sadly)
A configuration telling the client the server address/jndi lookup path (qa, prod etc.)
If your client is running on the same product (let's say JBoss to JBoss communication), you will not be in need of client libraries and just be able to do a remote lookup. If you have a mix of client/server application servers this will make things complicated, as you will have to run client libraries of one product in another server product.
Speaking of standalone applications running as clients, I'd just build and provide 1 heavy client jar/lib containing not only the interface classes, but also the client libs of both servers. Then providing a small helper class that returns the correct InitialContext created and based either on JBoss or Websphere depending on a flag in the client configuration.
I know this last idea ain't a clean solution, though might even work in a different AS product running as "client".
I'm wondering if I can configure an OSGi container like Karaf (or any other popular ones) to download bundles (.BNDs) from a remote repository hosted on another machine, via any networking mechanism out there (RMI, HTTP, URLClassLoader, etc.)?
Ideally, I'd be able to deploy new versions of my bundles to this remote repo at any time, and somehow have that trigger the OSGi container "downloading" (installing/deploying) the remote bundles and hot-deploying them over older versions of the same bundle.
Is this possible? If so, how? Thanks in advance!
OSGi has an API for managing OSGi frameworks on the BundleContext that every bundle activator receives. This API allows you to install/update a bundle via URL or InputStream.
Since this is a standardized API there have been lots of people making bundles that provide a policy around this deployment process. The archetypical one is Apache FileInstall, it watches a directory and automatically installs every bundle found in this directory and uninstall the bundle when it is gone. This works well with for example dropbox. It also supports configuring via the the Configuration Admin service. On the other hand of the spectrum you find Apache Ace which provides a remote management system.
To find the best solution, try to enlist the requirements you have. One or two systems or 1 million? Local or remote over slow lines?
One thing is for sure, you will find some project or provider being able to provide you with an OSGi bundle that implements your desired management policy.
We use Apache Felix and maintain an OBR repository. Once set up you can deploy new versions from the OSGi shell. This does require you to manually log in and enter the command, for example deploy com.example.foo.
Alternatively you can install directly from urls, like install http://example.com/bundles/bundle.jar.
Your last requirement (auto deploy) is trickier. You could perhaps enable a remote shell on your OSGi container and as part of your build push the commands via telnet.
I recommend taking a look at the provisioning of Karaf at documentation for provisioning.
Your able to deploy bundles either with maven urls, http or file references. Or you might deploy your set of bundles either as a feature definition (which loads all required and used bundles from a maven repo) or by deploying a kar file.
In researching OSGi and OSGi containers, I stumbled across this SO question mentioning GlassFish as an OSGi container, and I have to say I'm quite baffled.
How is this possible?!?!
My understanding was that OGS - a Java-compliant app server - has 2 containers:
Web Container: where you deploy WAR files for web apps and services
App Container: where you deploy EJBs for business logic
Where do OSGi bundles fit into this paradigm?!? Does OGS allow you to deploy an OSGi bundle to the app container and treat it like an EJB or something? And if I'm mistaken about how OGS works please correct me! Thanks in advance!
Hmm, a rather total misunderstanding of what OSGi is ...
OSGi is a framework that allows you to organize your code so that you can built it from reusable components that can then collaborate through the service layer (no more Class.forName or XML!).
OSGi frameworks can run standalone, they run inside an application, the can run in a WAR file, and they can run inside an application server. And you can even run OSGi inside OSGi inside OSGi since it does not rely on statics anywhere.
The OSGi Alliance specifies a format for the modules (bundles) so that modules can specify their dependencies. The Alliance also specifies an API to install and manage modules. And last, it specifies a large number of interfaces that are useful when you develop applications.
Websphere, Glassfish, JBoss, Jonas, all support deploying OSGi bundles.
OSGi is a module system that allows to add/remove/upgrade different bundles, handles dependencies, provides runtime information on the status, etc.
When it comes to GlassFish (which has an Apache Felix OSGi container in it), the different features of the application server (eg HTTP server, JMS server, etc.) are implemented as bundles. There is console and web based interface for the OSGi container where you can start, install, remove services (see the PDF below)
As far as Java EE applications go, they can interact with the OSGI container too. For example, an EJB can be exported as an OSGi service and also the EJB can consume an OSGi service itself.
For more info, see http://glassfish.java.net/public/GF-OSGi-Features.pdf
Glassfish internally uses OSGi to provide the features you mentioned. Besides that you can deploy your own OSGi bundles on it. See https://wikis.oracle.com/display/GlassFish/OSGi
There is no real connection between OSGi and Java EE though. You can not yet use JavaEE in OSGi bundles on Glassfish. For this case there are first initiatives like Weld on OSGi: http://www.slideshare.net/TrevorReznik/weldosgi-injecting-easiness-in-osgi
They are not really production ready though.
I have been looking for a solution to create a modular web application, which is modular in the sense that user can provide its own plugin in form of a simple jar which will then provide its own data to my web application and my webapp will be responsible for displaying it.
Now the catch is i want my web app to be as generic as possible without relying on the j2ee web container to support anything . i.e. i cant rely on my web container to provide osgi support and deploy web application as an osgi bundle itself ( which truly makes things very simple for eg. glassfish and WAS).
I am planning to use equinox and only solution i see currently is the servlet bridge they provide on their official site, but to me it is really a pain to delegate everything to a servlet which will in turn interpret the request and find an apropriate bundle Class and then again communicate back somehow only the data to the web application.
To me it would be wonderful if my web app was also a bundle.
Is there anything close to this ideal solution which i can try for? Or any other communication method between the two relams of osgi and web appliction (container)?
The OSGi spec details the WAB (Web Archive Bundle) format.
And Pax Web offers great support for WAB/WAR webapps (PAX Web runs fine on Equinox, Felix, etc)
Using pax web you get the BundleContext via the ServletContext, eg:
BundleContext bundleContext = (BundleContext) getServletContext().getAttribute("osgi-bundlecontext");
For the user driven pluggability you mention, I'd suggested you provide some service interfaces for the plugin bundles to implement and in your webapp use a ServiceTracker to listen for their registration (unless you're using Declarative Services). You also easily be able to install bundles from an upload servlet.
I'm guessing users uploading plugins would have to be logged in and authorized, so security issues will have been met at this point.
EDIT: replying to comment here as not enough space in comment field
Apologies, think I misinterpreted you question - you have an existing webapp container(s) and you want to deploy a WAR with OSGi functionality? If that's the case then either use the ServletBridge as others have mentioned or embed an OSGi framework into your WAR (this is relatively easy, see this for example).
You could even make this optional by attempting to get the BundleContext from the ServletContext and if this returns null then launch your own embedded framework. That way it'll run in a native OSGi container (e.g. Glassfish) or in a Java EE app server.
Otherwise, PaxWeb is an implementation of the HttpService and WebApp OSGi specs, but with lots of extensions to make life easier - but you deploy this to an OSGi container.
You might want to look into Apache Sling. It is a web framework that has an embedded OSGi container. The OSGi container is called Apache Felix and is pretty good.
ServletBridge is for embedding an OSGI contianer within a web container. The other option is to embed a web container (as a bundle) in an OSGI container. The following article has some details on how to achieve this.
http://java.dzone.com/articles/osgi-and-embedded-jetty
You may want to try ChonCMS - http://www.choncms.com
Its architecture is based exactly on what you are asking, it comes with few plugins to enable base CMS functionality, it is modular platform with minor web app container using felix and plugins can be added/removed at run time as well.
Disadvantage might be that it has lack of documentation, but you may ask, it is open source, I'm sure they will be happy to answer questions, and even better you can contribute - it is still in incubation phase.