OSGi Enablement For Apache Tuscany


Published on

OSGi Enablement for Apache Tuscany

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

OSGi Enablement For Apache Tuscany

  1. 1. OSGi Enablement for Apache Tuscany Raymond Feng [email_address]
  2. 2. Overview
  3. 3. Motivations <ul><li>Provide modularity for Tuscany to formalize/enforce the SPI contracts and minimize the package dependencies across modules </li></ul><ul><li>Enable Tuscany to work with OSGi environment such as JEE application servers, Eclipse RCP or Spring DM </li></ul><ul><li>Provide versioning and isolation so that Tuscany extensions can depend on different versions of the same library </li></ul><ul><li>Provide lifecycle management for extensions: install/uninstall/start/stop a module </li></ul>
  4. 4. Objectives <ul><li>Tuscany runtime will be able to run in both non-OSGi and OSGi environment </li></ul><ul><ul><li>No OSGi APIs should be used for non-OSGi specific modules </li></ul></ul><ul><li>Build a consistent OSGi story to facilitate developing, building, launching, running and testing Tuscany </li></ul><ul><ul><li>Makes developers’ life a bit easier to work with OSGi </li></ul></ul>
  5. 5. What problems do we try to solve? <ul><li>Turning Tuscany modules into OSGi bundles </li></ul><ul><li>Turning 3 rd party dependencies into OSGi bundles </li></ul><ul><li>Developing, building, launching, running and testing with OSGi </li></ul><ul><li>Producing distributions that are compatible with the OSGi bundle structure in an efficient way (in one-two minutes) </li></ul>
  6. 6. Turning Tuscany modules into OSGi bundles
  7. 7. Creating bundles for Tuscany modules <ul><li>Modularize Tuscany after the maven modules </li></ul><ul><ul><li>One OSGi bundle per maven module </li></ul></ul><ul><ul><li>Be consistent for build, packaging and runtime </li></ul></ul><ul><ul><li>Much easier to aggregating than decomposing </li></ul></ul><ul><li>Developers are responsible for authoring and maintaining MANIFEST.MF (instead of MF generation tools) </li></ul><ul><ul><li>Tooling friendly </li></ul></ul><ul><ul><li>Developers pay more attentions to the dependencies </li></ul></ul>
  8. 8. Things to consider to create an OSGi bundle for a module <ul><li>Add META-INF/MANIFEST.MF (don’t stop here …) </li></ul><ul><li>Clean up module dependencies and package visibilities </li></ul><ul><li>Prepare for code changes </li></ul><ul><ul><li>Service Discovery </li></ul></ul><ul><ul><li>ClassLoading </li></ul></ul>
  9. 9. Rules of thumb <ul><li>Identify the absolutely necessary SPI packages that need to be exported </li></ul><ul><ul><li>Don't try to export everything </li></ul></ul><ul><ul><li>For model modules, try to only export the package that contains the interfaces </li></ul></ul><ul><ul><li>Try not to export any package from the xxx-runtime moudles </li></ul></ul><ul><ul><li>Any classes that can be accessed via the ExtensionPointRegistry using interfaces should not be exported </li></ul></ul><ul><li>Only import other packages when it's needed </li></ul><ul><ul><li>For example, we used to have a lot of modules pull in assembly for just a constant for the SCA namespace </li></ul></ul><ul><ul><li>Avoid DynamicImport-Package=* </li></ul></ul><ul><ul><li>Avoid Require-Bundle </li></ul></ul><ul><li>Do not export &quot;private&quot; packages as a workaround or hack which can fail the &quot;clean SPI&quot;. Refactor things into SPIs if necessary </li></ul>
  10. 10. Granularity Discussion <ul><li>180+ bundles cumbersome </li></ul><ul><li>Multiple bundles required to enable one capability </li></ul><ul><li>Much debate about right level of granularity (flexibility vs. usability) </li></ul><ul><li>Some opinions </li></ul><ul><ul><li>Fine-grained bundles suitable for developer view </li></ul></ul><ul><ul><li>Features/Profiles used to “group” bundles to provide a user view </li></ul></ul><ul><ul><ul><li>Inspired by Eclipse Features </li></ul></ul></ul>
  11. 11. Dealing with 3 rd party jars
  12. 12. Handling 3 rd party jars <ul><li>We have to live with the reality: </li></ul><ul><ul><li>Many 3 rd party jars are not OSGi bundles. No repo is available to get all converted bundles </li></ul></ul><ul><ul><ul><li>We need to convert them (build time, run time) </li></ul></ul></ul><ul><ul><li>Some of the 3 rd party bundles are broken (w/ bogus MF) </li></ul></ul><ul><ul><ul><li>We need to fix them (replacing the MF) </li></ul></ul></ul><ul><ul><li>More and more 3 rd party jars are upgraded to be OSGi bundles </li></ul></ul><ul><ul><ul><li>We should be able to incrementally consume 3 rd party jars as OSGi bundles </li></ul></ul></ul>
  13. 13. Converting 3 rd party jars to OSGi bundles <ul><li>A folder bundle is created to represent a 3 rd party jar </li></ul><ul><li>The folder structure looks like: </li></ul><ul><ul><li>jaxb-impl-2.1.12 </li></ul></ul><ul><ul><ul><li>META-INF </li></ul></ul></ul><ul><ul><ul><ul><li>MANIFEST.MF </li></ul></ul></ul></ul><ul><ul><ul><li>jaxb-impl-2.1.12.jar </li></ul></ul></ul><ul><li>It is non-invasive and flexible </li></ul><ul><ul><li>The original jar is not changed (avoid legal, signature issues) </li></ul></ul><ul><ul><li>Multiple jars can be easily aggregated (control the bundle granularity) </li></ul></ul><ul><ul><li>The MANIFEST.MF can be easily customized </li></ul></ul>third-party.jar MANIFEST Bundle-Classpath: third-party.jar Dynamic-Import-Package: * Export-Package: ... ... third-party.jar Install OSGi Framework third-party-osgi.jar third-party.jar MANIFEST Bundle-Classpath: third-party.jar Import-Package: ... Export-Package: ... ...
  14. 14. Sample META-INF/MANIFEST.MF <ul><li>Manifest-Version: 1.0 </li></ul><ul><li>Bundle-ManifestVersion: 2 </li></ul><ul><li>Bundle-SymbolicName: com.sun.xml.bind.jaxb-impl </li></ul><ul><li>Bundle-Name: com.sun.xml.bind.jaxb-impl </li></ul><ul><li>Bundle-Version: 2.1.12 </li></ul><ul><li>DynamicImport-Package : javax.transaction;version=&quot;1.1&quot;,javax.transacti </li></ul><ul><li>on.xa;version=&quot;1.1&quot;,* </li></ul><ul><li>Bundle-ClassPath : jaxb-impl-2.1.12.jar </li></ul><ul><li>Export-Package : com.sun.xml.bind.v2.schemagen;version=2.1.12,com.sun.x </li></ul><ul><li>ml.bind.v2.util;version=2.1.12,com.sun.xml.txw2.annotation;version=2. </li></ul><ul><li>1.12,com.sun.xml.bind.v2.model.runtime;version=2.1.12,com.sun.xml.bin </li></ul><ul><li>d.v2.runtime;version=2.1.12,com.sun.xml.txw2.output;version=2.1.12,co </li></ul><ul><li>m.sun.xml.bind.v2;version=2.1.12,com.sun.istack;version=2.1.12,com.su </li></ul><ul><li>n.xml.bind.v2.runtime.property;version=2.1.12,com.sun.xml.bind.v2.run </li></ul><ul><li>time.unmarshaller;version=2.1.12,com.sun.xml.bind.v2.model.nav;versio </li></ul><ul><li>n=2.1.12,com.sun.xml.bind.marshaller;version=2.1.12,com.sun.xml.bind. </li></ul><ul><li>v2.runtime.reflect.opt;version=2.1.12,com.sun.xml.bind.v2.runtime.out </li></ul><ul><li>put;version=2.1.12,com.sun.xml.txw2;version=2.1.12,com.sun.xml.bind.v </li></ul><ul><li>2.schemagen.xmlschema;version=2.1.12,com.sun.xml.bind.v2.runtime.refl </li></ul><ul><li>ect;version=2.1.12,com.sun.xml.bind.v2.model.impl;version=2.1.12,com. </li></ul><ul><li>sun.xml.bind.unmarshaller;version=2.1.12,com.sun.xml.bind.util;versio </li></ul><ul><li>n=2.1.12,com.sun.xml.bind;version=2.1.12,com.sun.istack.localization; </li></ul><ul><li>version=2.1.12,META-INF.services;partial=true;mandatory:=partial,com. </li></ul><ul><li>sun.xml.bind.v2.model.annotation;version=2.1.12,com.sun.xml.bind.api. </li></ul><ul><li>impl;version=2.1.12,com.sun.xml.bind.api;version=2.1.12,com.sun.xml.b </li></ul><ul><li>ind.v2.model.core;version=2.1.12,com.sun.xml.bind.v2.bytecode;version </li></ul><ul><li>=2.1.12,com.sun.xml.bind.v2.schemagen.episode;version=2.1.12,com.sun. </li></ul><ul><li>xml.bind.annotation;version=2.1.12 </li></ul>
  15. 15. Developing Tuscany with OSGi
  16. 16. Checking out source code and building with maven <ul><li>Check out the Tuscany source code from SVN </li></ul><ul><ul><li>svn co https://svn.apache.org/repos/asf/tuscany/java/sca/ </li></ul></ul><ul><li>Run maven build </li></ul><ul><ul><li>mvn clean install -fn </li></ul></ul><ul><li>Generate Eclipse projects </li></ul><ul><ul><li>mvn -Peclipse </li></ul></ul>
  17. 17. Setting up Eclipse PDE <ul><li>Download Eclipse (w/ plugin development) </li></ul><ul><ul><li>http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-jee-galileo-SR1-win32.zip </li></ul></ul><ul><li>Configure PDE target platform </li></ul><ul><ul><li>File  Open File </li></ul></ul><ul><ul><ul><li><tuscany>scadistributionall argetfeatures uscany-pde35.target </li></ul></ul></ul><ul><ul><li>Click on “Set as target platform” </li></ul></ul><ul><li>Load Tuscany modules into Eclipse </li></ul><ul><ul><li>File  Import …  General  Import Existing Projects … </li></ul></ul>
  18. 18. What’s happening during the Tuscany build? <ul><li>Validating OSGi constraints to report bundle resolution issues during compilation </li></ul><ul><li>Generating PDE project so that Tuscany modules can be loaded in Eclipse to leverage the nice OSGi tooling </li></ul><ul><li>Generating OSGi bundles for 3 rd party jars </li></ul><ul><li>Generating PDE target platform definitions so that 3 rd party bundles can be used in Eclipse as plugin dependencies </li></ul><ul><li>Generating Equinox configuration so that Tuscany distribution can be directly loaded as an OSGi framework </li></ul>
  19. 19. Maven/OSGi Tools provided by Tuscany <ul><li>Maven-bundle-plugin </li></ul><ul><ul><li>Generates bundles for 3 rd party jars </li></ul></ul><ul><ul><li>Generates OSGi enabled PDE projects </li></ul></ul><ul><ul><li>Version 1.0.4 released at 10/09/2009 </li></ul></ul><ul><li>Maven-eclipse-compiler </li></ul><ul><ul><li>Expose OSGi aware Eclipse JDT compiler </li></ul></ul><ul><ul><li>Expose Eclipse OSGi bundle validation </li></ul></ul><ul><ul><li>Version 1.0.1 released on 04/07/2009 </li></ul></ul><ul><li>Maven-osgi-junit-plugin </li></ul><ul><ul><li>JUnit tests in a OSGi enabled environment </li></ul></ul><ul><ul><li>Version 1.0 released on 10/28/2009 </li></ul></ul><ul><li>https://svn.apache.org/repos/asf/tuscany/maven-plugins/trunk / </li></ul>
  20. 20. Development Time <ul><li>Eclipse PDE provides nice OSGi tooling </li></ul><ul><ul><li>Graphical editor for MANIFEST.MF (w/ additional tools to analyze/calculate dependencies) </li></ul></ul><ul><ul><li>Plugin Dependencies Classpath Container </li></ul></ul><ul><ul><li>Compilation errors/warning for OSGi constraint violations (w/ Quick Fix suggestions) </li></ul></ul><ul><ul><li>OSGi test environment to validate and launch OSGi framework (w/ console) </li></ul></ul>
  21. 21. Runtime <ul><li>Provide a SCA node launcher to start an OSGi runtime and run SCA application with the OSGi-enabled Tuscany runtime </li></ul><ul><li>We need to use Tuscany's service discovery mechanism to discover and instantiate the factories </li></ul><ul><ul><ul><li>Change how JDK factories such as XMLInputFactory, XPathFactory, and DocumentBuilderFactory, are discovered and instantiated </li></ul></ul></ul><ul><ul><ul><li>XMLInputFactory.newInstance() used the JSE service provider pattern which doesn't work with OSGi </li></ul></ul></ul><ul><li>Adjust the code that assumes there is a flat thread context classloader that can access all the classes in the Tuscany runtime </li></ul><ul><ul><ul><li>With OSGi, there is a network of classloaders (one classloader per module) and the class visibility is constrained by the OSGi headers such as Import-Package and Export-Package </li></ul></ul></ul><ul><ul><ul><li>The classloader for the current class is a good starting point for Class.forName() with OSGi </li></ul></ul></ul>
  22. 22. Launching OSGi framework within Eclipse PDE
  23. 23. Launching OSGi from Tuscany distribution <ul><li>Equinox: </li></ul><ul><ul><li>java -jar osgi-3.5.0-v20090520.jar -clean -console -configuration ..featuresconfiguration </li></ul></ul><ul><li>http://cwiki.apache.org/confluence/display/TUSCANYxDOCx2x/Running+Tuscany+SCA+2.x+with+Equinox+and+Felix </li></ul>
  24. 24. Testing Tuscany with OSGi
  25. 25. A few options <ul><li>Tuscany maven-osgi-junit plugin </li></ul><ul><ul><li>Generate two bundles for the main and test classes respectively. The test bundle is a fragment of the main bundle. </li></ul></ul><ul><ul><ul><li>For example, the plugin generates the following bundles for sample-calculator-osgi.jar: * sample-calculator-osgi-osgi.jar * sample-calculator-osgi-osgi-tests.jar </li></ul></ul></ul><ul><ul><li>Find the EquinoxHost class from tuscany-node-launcher-equinox and create an instance </li></ul></ul><ul><ul><li>Start the equinox runtime </li></ul></ul><ul><ul><li>Set up the classloader for surefire so that it uses OSGi classloading for the test cases with the test bundle. </li></ul></ul><ul><ul><li>Delegate to surefire to run the unit tests </li></ul></ul><ul><li>Apache Felix junit4osgi </li></ul><ul><ul><li>http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html </li></ul></ul>
  26. 26. Trouble-shooting OSGi related issues
  27. 27. Common traps <ul><li>System packages need to be explicitly imported, such as javax.xml.namespace </li></ul><ul><li>Be careful of TCCL (ThreadContext Classloader) </li></ul><ul><ul><li>No well-defined TCCL in OSGi </li></ul></ul><ul><ul><li>Equinox uses ContextFinder to find the closest class on the calling stack that is loaded by an OSGi bundle </li></ul></ul><ul><ul><li>JDK and some 3 rd party libraries uses service discover pattern relying on TCCL being able to load/see everything </li></ul></ul>
  28. 28. Some tips <ul><li>Most common exceptions: </li></ul><ul><ul><li>ClassNotFoundException </li></ul></ul><ul><ul><li>NoClassDefFoundError </li></ul></ul><ul><li>Bundle is not resolved: </li></ul><ul><ul><li>Missing Import-Package (including system packages from the JDK) </li></ul></ul><ul><ul><li>Split package from Export-Package </li></ul></ul><ul><ul><li>Different versions of the same package are exported </li></ul></ul><ul><ul><li>Chain of bundle resolution (Exported packages from unresolved bundle cannot be seen.) </li></ul></ul>
  29. 29. Useful Links <ul><li>http://cwiki.apache.org/autoexport-2.2.9/TUSCANYxDOCx2x/osgi-enablement-for-tuscany-runtime.html </li></ul><ul><li>Infoq.com articles: </li></ul><ul><ul><li>http:// www.infoq.com /articles/modular-java-what-is-it </li></ul></ul><ul><ul><li>http:// www.infoq.com /articles/modular-java-static-modularity </li></ul></ul><ul><ul><li>http://www.infoq.com/articles/modular-java-dynamic-modularity </li></ul></ul><ul><li>http://www.dynamicjava.org/ </li></ul>