The full documentation is here:
http://docs.oracle.com/middleware/1212/wls/WLPRG/osgi.htm
In short this feature enables WLS to create an OSGi framework (Apache Felix 4.03) in which OSGi Bundles are installed and accessed by applications.
Applications provide an XML reference element to define the named OSGi framework and Bundle of interest, which is then published into the JNDI tree from where it can be referenced and used.
An OSGi Bundle can be included as part of the application archive being deployed or it can be provided as part of the server library set.
To provide a simple example, the Apache Felix tutorial Dictionary Service was first implemented and packaged as an OSGi Bundle.
The Bundle manifest looks as follows:
Manifest-Version: 1.0 Bnd-LastModified: 1378960044511 Build-Jdk: 1.7.0_17 Built-By: sbutton Bundle-Activator: tutorial.example2.Activator Bundle-ManifestVersion: 2 Bundle-Name: DictionaryService OSGi Bundle Bundle-SymbolicName: tutorial.example2.service.DictionaryService Bundle-Version: 1.0.0.SNAPSHOT Created-By: Apache Maven Bundle Plugin Export-Package: tutorial.example2.service;version="1.0.0.SNAPSHOT" Import-Package: org.osgi.framework;version="[1.6,2)" Tool: Bnd-1.50.0
The Bundle archive contains only a few classes, the
DictionaryService
interface and an Activator
implementation which provides an inner class implementation of the DictionaryService
that is registered when the Bundle
is activated.A small web application was then developed to make use of the
DictionaryService
Bundle using a Servlet.The Servlet performs the following tasks:
- Injects the Bundle reference from JNDI using the
@Resource
annotation - Looks up the
ServiceReference
for theDictionaryService.class
to be used - Obtains an instance of the DictionaryService from the ServiceReference
- Makes calls on the
DictionaryService
to check whether a word is in the known word list
Inject Bundle reference from its JNDI location:
@WebServlet(name = "TestServlet", urlPatterns = {"/TestServlet", "/test", "/osgi"}) public class TestServlet extends HttpServlet { @Resource(lookup = "java:app/osgi/Bundle") Bundle bundle; ... }
The Bundle provides access to the registered Services, in this case the DictionaryService:
if (bundle != null) { BundleContext bc = bundle.getBundleContext(); ServiceReference dictionaryServiceRef = bc.getServiceReference(DictionaryService.class); DictionaryService dictionaryService = (DictionaryService) bc.getService(dictionaryServiceRef); ... }
The methods on the DictionaryService can then be used:
out.printf("<div>wordlist: %s </div>", Arrays.toString(dictionaryService.wordlist())); out.printf("<div>checkWord(\"%s\"): %s</div>", wordToCheck, dictionaryService.checkWord(wordToCheck));
The Bundle then needs to be defined for the web application to use, which is done using the weblogic deployment descriptor. In this example, the weblogic.xml file contains the following entry:
<osgi-framework-reference> <name>test</name> <application-bundle-symbolic-name> tutorial.example2.service.DictionaryService </application-bundle-symbolic-name> </osgi-framework-reference>
The bundle-symbolic-name is used to specify the bundle to be used.
The name element specifies the name of the OSGi framework that has been configured. With WebLogic Server 12c (12.1.2) there are several ways to define and configure OSGi frameworks such as the Admin Console, WLST, programmatically with Java or by directly editing the domain config.xml file.
With this small web application, the DictionaryService Bundle was deployed as part of the WAR file itself. This is performed by placing the JAR file in the WEB-INF/osgi-lib directory, whereupon WLS will detect it and install it. The DictionaryService Bundle could also be installed by copying it into the $ORACLE_HOME/wlserver/server/osgi-lib directory.
With the WAR file packaged and deployed to WLS, the console logs show the DictionaryService Bundle being Activated, where System.out.println() calls were inserted into the start and stop Activator methods to view them being called:
*** START Bundle org.apache.felix.framework.BundleContextImpl@21052189 tutorial.example2.service.DictionaryService ***Finally the TestServlet is accessed, demonstrating the DictionaryService being accessed and used:
5 comments:
Hello Buttso,
Nice article!
I have one question:
How is possible to use few bundles in WAR?
In weblogic-javaee.XSD i found
I have to use "bundles-directory"?
Btw: is in possible to create child directories (2, 3, X )for run-level bundles start?
Best regards,
Vladimir
Hello Buttso,
Nice article!
I have one question:
How is possible to use few bundles in WAR?
In weblogic-javaee.XSD i found
I have to use "bundles-directory"?
Btw: is in possible to create child directories (2, 3, X )for run-level bundles start?
Best regards,
Vladimir
Hi Buttso,
I am always receiving NULL at this line
bundleContext = bundle.getBundleContext();
Do you have any idea what could be the source of the problem?
Thank you in advance
Hi --
Couple of things to look at:
Did you configure an OSGI framework resource on the WLS server?
http://docs.oracle.com/middleware/1212/wls/WLPRG/osgi.htm#BABIIIDF
Did you reference the OSGI resource correctly in the bundle definition?
Did you inject the BundleContext using the required JNDI location?
I have a working example I can send if you like, send me an email at steve_dot_button_at_oracle_dot_com and I'll get it to you.
Hi Steve,
I found your code online: https://java.net/projects/weblogic-examples/sources/weblogic-12c-user-examples/show/steve.button/osgi?rev=178
It is much better now.
Thank you again for your work.
Post a Comment