Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
public2015-11-04
•
1
•
OSGi from the Trenches
Painless Server Side Development
Date: 2015-11-04
Location: OSGi Community E...
public2015-11-04 2
What we do
▪ Platform development for products and in-house
projects, server side
▪ Plain OSGi – no Ecl...
public2015-11-04 3
Integrating…
Eclipse: Equinox, EclipseLink, Jetty, Gemini (JPA, Blueprint,
Naming)
Apache: CXF, ActiveM...
public2015-11-04 4
Pain?
▪ Bad OSGi metadata
▪ Missing Import-Package,
▪ version range does not match 

documented compati...
public2015-11-04 5
What does it feel like?
public2015-11-04 6
Create your own Launcher!
FrameworkFactory frameworkFactory =

ServiceLoader.load(FrameworkFactory.clas...
public2015-11-04 7
OsgiContainerConfiguration config = new DefaultOsgiContainerConfiguration();
…
framework.init();
for (B...
public2015-11-04 8
Startlevelspublic class DefaultOsgiContainerConfiguration implements OsgiContainerConfiguration {
publi...
public2015-11-04 9
Which Bundles to install?
Maven
▪ create one pom.xml for each deployment to define application‘s bundle...
public2015-11-04 10
How about the IDE?
Launch / Debug
Just run mvn rt:launch
! no plugin necessary
Test
Just run the JUnit...
public2015-11-04 11
Demo
public2015-11-04 12
JUnit integration
▪ Analogous to the SuiteRunner, create an OsgiTestSuite that is responsible
for sett...
public2015-11-04 13
Example
@RunWith(OsgiTestSuite.class)
@SuiteClasses(MyITCase.class)
public class MyIT {}
//No RunWith ...
public2015-11-04 14
public2015-11-04 15
Bundle creation (Maven)
mvn process-classes: 

create target/classes/META-INF/MANIFEST.MF using maven-...
public2015-11-04 16
Bundle creation (Eclipse)
m2e “Tycho Project Configurators“ configures affected
projects to rebuild MA...
public2015-11-04 17
How to tackle bad OSGi Metadata?
"traditional" approach
▪ Open the .jar with the tool of your choice a...
public2015-11-04 18


Fix Metadata at Runtime
▪ Use a Java DSL to describe the difference:
bundles("org.apache.cxf.*")

.h...
public2015-11-04 19
Last but not Least
Open an issue with the library‘s owner, document
which headers must be changed:
! E...
public2015-11-04 20
public2015-11-04 21
Questions
?
Upcoming SlideShare
Loading in …5
×

OSGi from the Trenches- Painless Server Side Development - Magnus Jungsbluth & Domagoj Cosic

513 views

Published on

OSGi Community Event 2015

Selecting the right toolchain that “just works” for a new OSGi based effort is still a difficult task. Many developers struggle and perceive OSGi to be overly complex and too painful. We would like to share our experience using a holistic approach to OSGi server side development based on plain Equinox that covers IDE, dependency management, build and integration testing.</p>
This approach differs from others in that it focuses on getting the average developer on board quickly and involves writing some small (core) parts of the toolchain yourself to put you in the driver’s seat. The only preconditions for this approach are Maven and an m2e plugin for Eclipse to execute Bnd on each incremental build. Our approach is particularly valuable in product-line or platform development.

Using essential code snippets and brief live demos we will demonstrate:
• How to develop your own OSGi launcher
• How to use the launcher during development (IDE + Maven) and deployment
• How to use the launcher for JUnit based integration tests
• How to single source dependency management from the pom.xml: no target platforms, no config.inis, and no manual editing of MANIFEST.MF files (let Bnd do its job)

In the second part, we will show you how to tackle bad OSGi metadata at runtime using a simple Java DSL. We will specifically address a live patching mechanism of MANIFEST.MF files based on Equinox hooks that allows third-party .jar files to remain unchanged. This has many advantages both from a licensing and from a maintainability perspective.

Published in: Technology
  • Be the first to comment

OSGi from the Trenches- Painless Server Side Development - Magnus Jungsbluth & Domagoj Cosic

  1. 1. public2015-11-04 • 1 • OSGi from the Trenches Painless Server Side Development Date: 2015-11-04 Location: OSGi Community Event / EclipseCon 2015, Ludwigsburg, Germany Speakers: Magnus Jungsbluth, Domagoj Cosic
  2. 2. public2015-11-04 2 What we do ▪ Platform development for products and in-house projects, server side ▪ Plain OSGi – no Eclipse RCP
  3. 3. public2015-11-04 3 Integrating… Eclipse: Equinox, EclipseLink, Jetty, Gemini (JPA, Blueprint, Naming) Apache: CXF, ActiveMQ, Camel, Felix, ServiceMix Bundles Spring: Core, MVC, Data, Security, Shell Diverse: Vaadin, QueryDSL, Camunda BPM...
  4. 4. public2015-11-04 4 Pain? ▪ Bad OSGi metadata ▪ Missing Import-Package, ▪ version range does not match 
 documented compatibility, ▪ missing resolution:=optional ▪ Implicit assumptions on Start Levels ▪ Differences between Test, Deployment and Development
  5. 5. public2015-11-04 5 What does it feel like?
  6. 6. public2015-11-04 6 Create your own Launcher! FrameworkFactory frameworkFactory =
 ServiceLoader.load(FrameworkFactory.class).iterator().next(); Framework framework = frameworkFactory.newFramework(Collections.emtpyMap()); framework.start(); [1] http://njbartlett.name/2011/07/03/embedding-osgi.html
  7. 7. public2015-11-04 7 OsgiContainerConfiguration config = new DefaultOsgiContainerConfiguration(); … framework.init(); for (BundleMetaData bundleMeta : config.getBundlesToInstall()) { Bundle bundle = framework.getBundleContext() .installBundle(“reference:” + bundleMeta.getLocation()); applyStartLevel(bundle, config.getStartLevelToApply(bundleMeta)); bundle.start(); } framework.start(); In-code configuration … aka "beware of another XML format"
  8. 8. public2015-11-04 8 Startlevelspublic class DefaultOsgiContainerConfiguration implements OsgiContainerConfiguration { public DefaultOsgiContainerConfiguration() { withDefaultStartLevel("org.apache.cxf.*", 9); withDefaultStartLevel("javax.persistence", 4); } @Override public void withDefaultStartLevel(String pattern, int level) { defaultStartLevels.put( Pattern.compile(pattern.replace(".", ".").replace("*", ".*")), level); } @Override public Integer getStartLevelToApply(BundleMetaData bundleMeta) { Integer startLevel = null; for (Entry<Pattern, Integer> entry : defaultStartLevels.entrySet()) { if (entry.getKey().matcher(bundleMeta.getBundleSymbolicName()).matches()) { startLevel = entry.getValue(); } } return startLevel; } } ! uniform behavior throughout different applications on the same platform
  9. 9. public2015-11-04 9 Which Bundles to install? Maven ▪ create one pom.xml for each deployment to define application‘s bundles ▪ Custom Maven Plugin starts the framework with runtime+compile (transitive!) dependencies from that pom.xml JUnit ▪ Start all OSGi Bundles that are on the Classpath
 (TCCL.getResources("/META-INF/MANIFEST.MF")) ▪ ! Either IDE or Maven will provide the dependencies on the class path of the JUnit launcher Deployment (launcher.jar) ▪ Scan bin/bundles and install all .jars from that directory
  10. 10. public2015-11-04 10 How about the IDE? Launch / Debug Just run mvn rt:launch ! no plugin necessary Test Just run the JUnit test as you always do ! no plugin necessary
  11. 11. public2015-11-04 11 Demo
  12. 12. public2015-11-04 12 JUnit integration ▪ Analogous to the SuiteRunner, create an OsgiTestSuite that is responsible for setting up the container and SuiteClasses to define the actual test classes
 
 ! still have the @RunWith annotation at your free disposal ▪ Use Boot Delegation to delegate all test libraries (org.junit.*, org.mockito.*, ...) ▪ No special bundle configuration necessary (tradeoff flexibility), aimed at integration tests with fixed set of bundles
  13. 13. public2015-11-04 13 Example @RunWith(OsgiTestSuite.class) @SuiteClasses(MyITCase.class) public class MyIT {} //No RunWith annotation necessary public class MyITCase { @Test public void shouldDoFoobar() { } }
  14. 14. public2015-11-04 14
  15. 15. public2015-11-04 15 Bundle creation (Maven) mvn process-classes: 
 create target/classes/META-INF/MANIFEST.MF using maven-bundle- plugin:manifest mvn package: 
 create .jar using maven-jar-plugin (Ordinary “jar“ packaging>) !Simple, standard Maven setup that does not deviate much from non-OSGi builds.
  16. 16. public2015-11-04 16 Bundle creation (Eclipse) m2e “Tycho Project Configurators“ configures affected projects to rebuild MANIFEST.MF on each incremental build (equivalent to process-classes in Maven) à target/classes is always a valid bundle ! perfectly fits Eclipse IDE's incremental build philosophy
  17. 17. public2015-11-04 17 How to tackle bad OSGi Metadata? "traditional" approach ▪ Open the .jar with the tool of your choice and fiddle with the MANIFEST.MF until your test is green. ▪ Create a patch version and deploy it to your local repository (Nexus / Artifactory). ▪ Maintain this patch for a while (a.k.a ,"Rip your hair out")
  18. 18. public2015-11-04 18 
 Fix Metadata at Runtime ▪ Use a Java DSL to describe the difference: bundles("org.apache.cxf.*")
 .having(Constants.IMPORT_PACKAGE)
 .matching("org.springframework.beans.*")
 .widenUpperVersionRange("5"); bundles("org.apache.cxf.*")
 .having(Constants.IMPORT_PACKAGE)
 .matching("org.springframework.beans.*")
 .ensureDirective("resolution", "optional"); ▪ add it to the default configuration of you launcher ▪ continue with what you were originally doing ("relax")
  19. 19. public2015-11-04 19 Last but not Least Open an issue with the library‘s owner, document which headers must be changed: ! Exactly the same information you just defined using the DSL!
  20. 20. public2015-11-04 20
  21. 21. public2015-11-04 21 Questions ?

×