+ All Categories
Home > Documents > Mavenized RCP

Mavenized RCP

Date post: 17-Aug-2015
Category:
Upload: marc-jimenez
View: 47 times
Download: 1 times
Share this document with a friend
31
Building RCP Applications with Maven
Transcript
Page 1: Mavenized RCP

Building RCP Applications with Maven

Page 2: Mavenized RCP

Presentation Overview

1. Dependency Management2. Hybrid solution for Maven/PDE

methodologies3. Rules for synchronization between

Maven/PDE4. Testing in a Maven Environment5. Maven Plugins Designed for RCP applications

Page 3: Mavenized RCP

Dependency Management Overview

1. Maven and PDE Dependencies in a nutshell

Page 4: Mavenized RCP

Maven Dependencies

• All dependencies at build time are managed through a pom.xml file located at the base of each project

• pom.xml files will pull in transitive dependencies from the direct dependencies unless otherwise specified

• Dependencies can either be in-house projects or 3rd party projects

• Sample Dependency Clip: <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.1.2</version></dependency>

Page 5: Mavenized RCP

PDE (Plug-in Development Environment) Dependencies

• All dependencies at compile and runtime are managed through MANIFEST.MF• For a plugin to add another plugin to it’s build-path (compile time) and

classpath or classloader (runtime) each plugin must contain valid OSGI manifest metadata: Bundle-Symbolic-name Bundle-Version Required-Bundles Fragment-Host Eclipse-BuddyPolicy Eclipse-RegisterBuddy etc…

• For this reason, every project needed by an RCP application, has to remain in an OSGi state, regardless of our desire to manage everything entirely through the use of pom.xml files

Page 6: Mavenized RCP

Hybrid solution (Maven/PDE methodologies) Overview

1. A snapshot of today’s dependencies2. The problem of managing dependencies

through 2 different mechanisms simultaneously

3. A Hybrid solution4. A snapshot of today’s dependencies with our

solution

Page 7: Mavenized RCP

PDE View of Dependencies for RCP

Rcp-plugin-C

Rcp-plugin-D

OSGi-plugin-A

OSGi-Plugin-B

OSGi-Plugin-C

Rcp-plugin-B

OSGi-Plugin-D

Rcp-plugin-A

RCP Plugins Backend “RCP Plugins”

Page 8: Mavenized RCP

Organization Problem• In the previous example, legitimate RCP Plugin projects relied on

many different in-house projects (containing common code between server and client) at build-time and runtime that were never intended to be RCP plugins, this meant every java-project required OSGi metadata such as a Manifest.MF file for dependency management

• To continue using these (common code) non-RCP projects directly in an OSGi container we would have to settle on managing pom.xml files and MANIFEST.MF files for every non-RCP project

• This would (in a sense) mean that every change made to one of these 2 dependency management files would have to be scrutinized and applied (in a similar but not necessarily identical manner) to the other file

Page 9: Mavenized RCP

Side by Side example: Trying to keep 2 different dependency mechanisms in sync

Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: com.example.aBundle-Version: 6.6.0.qualifierBundle-Vendor: NiceRequire-Bundle: com.example.b;bundle version="1.0.0”,com.example.c;bundle-version=“2.0.0”Export-Package: com.new.example.a, com.example.b, com.example.c Build-Id: build.id

<groupId>my.example</groupId><artifactId>com.example.a</artifactId><version>6.6.0-SNAPSHOT</version>

<dependency><groupId>my.example</groupId><artifactId>com.example.b</artifactId><version>1.0.0</version></dependency>

<dependency><groupId>my.example</groupId><artifactId>com.example.c</artifactId><version>2.0.0</version></dependency>

OSGi Manifest Maven POM

Page 10: Mavenized RCP

Solution

• Non-RCP projects are not fundamentally different than 3rdparty jars such as Spring, or log4j which are not RCP plugins

• The approach of using an OSGi container fit the mold in that it can be the delivery system for all of our non-RCP dependencies

• This led to the concept of the Bridge project

Page 11: Mavenized RCP

The Bridge• A collection of jars, in 1 single “bundle” that can be used at compile and

runtime by sharing it’s classpath with any bundle that requires it• Requires a valid OSGi MANIFEST.MF, bundle-name, bundle-version, etc…• All jars intended to be shared are required to be listed on the bundle-

classpath in the MANIFEST.MF, and all shared packages coming from those jars must be listed in the Export-Package section

• It is created using the Apache-Maven-Bundle plugin All jars placed in the Bridge come from Maven dependencies managed by a

single pom.xml The Manifest.MF file that defines this OSGi container is configured through

the pom file, for our example it automatically outputs out all of the jars on the bundle-classpath, ignores transitive maven dependencies, and lists out all packages to be exported to the classpath. It is a great solution that now requires only minimal configuration going forward

Page 12: Mavenized RCP

Bridge Introspection:Jar Root Jar/lib

Page 13: Mavenized RCP

Bridge Manifest file generated by the Maven Bundle Plugin

Manifest-Version: 1.0

Bnd-LastModified: 1429799922717

Build-Jdk: 1.7.0_75

Built-By: Marc Jimenez

Bundle-ClassPath: lib/common.ui.commons-6.6.0.0-RCP-20150422.151838-41.j

ar,lib/common.domain-6.6.0.0-RCP-20150422.151826-41.jar,lib/common.serv

ices.api-6.6.0.0-RCP-20150422.151834-45.jar,lib/common.generators.api-6

.6.0.0-RCP-20150422.151836-41.jar,lib/common.commons-6.5.0.0-RCP-201412

17.171620-1.jar,lib/kernel.commons-6.6.0.0-RCP-20150422.203255-50.jar,l

ib/kernel.api-6.6.0.0-RCP-20150422.203309-52.jar,lib/kernel.domain-6.6.

0.0-RCP-20150422.203303-50.jar,lib/common.event.common-6.6.0.0-RCP-2015

0422.151830-41.jar,lib/common.event.listener.api-6.6.0.0-RCP-20150422.1

51832-41.jar,lib/common.rtu.common-6.6.0.0-RCP-20150422.151832-41.jar

Bundle-ManifestVersion: 2

Bundle-Name: workstation.bridge

Bundle-SymbolicName: workstation.bridge

Bundle-Version: 1.0.0.SNAPSHOT

Created-By: Apache Maven Bundle Plugin

Eclipse-BuddyPolicy: registered

Embed-Dependency: *;scope=compile

Embed-Directory: lib

Embed-Transitive: false

Embedded-Artifacts: lib/common.ui.commons-6.6.0.0-RCP-20150422.151838-41

.jar;g="com.nice.wfm";a="common.ui.commons";v="6.6.0.0-RCP-SNAPSHOT",li

b/common.domain-6.6.0.0-RCP-20150422.151826-41.jar;g="com.nice.wfm";a="

common.domain";v="6.6.0.0-RCP-SNAPSHOT",lib/common.services.api-6.6.0.0

-RCP-20150422.151834-45.jar;g="com.nice.wfm";a="common.services.api";v=

"6.6.0.0-RCP-SNAPSHOT",lib/common.generators.api-6.6.0.0-RCP-20150422.1

51836-41.jar;g="com.nice.wfm";a="common.generators.api";v="6.6.0.0-RCP-

SNAPSHOT",lib/common.commons-6.5.0.0-RCP-20141217.171620-1.jar

Export-Package: com.iex;version="1.0.0",com.iex.tv.build;uses:="com.iex.

tv.core.framework,org.springframework.core.io";version="1.0.0",com.iex.

tv.commons.metaData.annotations;version="1.0.0",com.iex.tv.core.concurr

ent;version="1.0.0",com.iex.tv.core.datetime;uses:="com.iex.tv.core.fra

mework,com.iex.tv.core.model,com.iex.tv.core.utils

Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"

Tool: Bnd-2.3.0.201405100607

Page 14: Mavenized RCP

BRIDGE PLUGIN

View of dependencies for RCP with the Bridge

Rcp-Plugin-C

Rcp-Plugin-D

Common-Code-Jar-A

Common-Code-Jar-B

Common-Code-Jar-C

Rcp-Plugin-B

Common-Code-Jar-D

Rcp-Plugin-A

Page 15: Mavenized RCP

Guidelines for project synchronization

• Managing names and versions is crucial to keeping everything in sync at build time

Page 16: Mavenized RCP

Staying in sync• Managing an RCP application through maven means that we must keep certain artifacts in

sync. OSGi (MANIFEST.MF, feature.xml, category.xml, site.xml) Maven (pom.xml)

• Each OSGi artifact is identified by a bundle name and must reflect each Maven artifact name OSGi - Bundle-Name=workstation.acd MAVEN - <artifactId>workstation.acd</artifactId>

• Moreover, it is important to keep the versions in sync between OSGi and Maven OSGi - Bundle-Version=6.6.0.qualifier Maven - <version>6.6.0-SNAPSHOT</version> (Maven’s convention for snapshot artifacts for development is to have the word “SNAPSHOT”; for OSGi

that convention is to have “.qualifier”)• In order to ensure everything is kept in sync, it is not recommended to change any of these

version numbers either for OSGi or Maven by hand, but instead to allow tycho to do this work for us. The maven command: “mvn org.eclipse.tycho:tycho-versions-plugin:set-version -DnewVersion=“6.6.0-SNAPSHOT” The above command will result in all pom.xml file versions for the project to update to “6.6.0-

SNAPSHOT” while simultaneously updating all OSGi versions to “6.6.0.qualifier”, thus keeping everything perfectly in sync between releases.

Page 17: Mavenized RCP

Unit Testing Considerations

1. What was done in the past2. Alternative approach3. Pros and Cons

Page 18: Mavenized RCP

Previous Test project setup• Previous approach used a gargantuan plugin to hold all unit tests• Our RCP product consisted of roughly 130 plugins each consisting of

many packages that could be tested• The gargantuan plugin was setup with package names that mirrored the

multitude of package names of any of the 130 plugins for which we wanted to test

• Running this enormous test plugin inside of Eclipse resulted in a single JVM loading everything for the test plugin into a single classloader; thus giving us the ability to test any protected and default methods that existed in our production code from our test plugin (provided that our Test-Class lived in a package that mirrored the Class it intended to test)

• Previously our tests were not executed as part of our build, instead tests were only run by development within Eclipse

Page 19: Mavenized RCP

View of Single Test Plugin

TestPlugin

Plugin 1

JVM

Plugin 2

Plugin 3

Plugin 4

Page 20: Mavenized RCP

Alternative Approach• An alternative to a single test project is multiple test projects• Each new “test” project is created as a plugin fragment to the actual

plugin that it is intended to test• Using Bundle Fragments we can appropriately mirror the package

structure to put test classes into the same package when loading tests into an OSGi container

• Each new test fragment will of course require a Manifest file with a new Manifest header “Fragment-Host=“XX” which specifies a Bundle which this fragment can attach to at runtime

• This becomes very useful since the Tycho Surefire plugin is now the tool of choice for executing unit tests within our Maven Build Process

• The Tycho Surefire plugin will create an OSGi process and install the Test plugin as a bundle alongside all other required Bundles listed in the test plugin’s Manifest.MF

Page 21: Mavenized RCP

View of Multiple Test Plugins in separate JVMs

TestPlugin-A JVM

Plugin-A TestPlugin-B JVM

Plugin-B

Page 22: Mavenized RCP

Pros and cons of a single test plugin

• Pros– single point of failure in a build system– Single test means single OSGi process for testing within a Maven

build (very efficient)

• Cons– A monolithic plugin can only reliably test all protected and

default accessor methods outside of an OSGi container environment (other than testing Public methods, this approach can’t provide adequate test coverage within a Maven style Build)

– Running such a large test plugin with so many dependencies requires an excessive amount of memory to start up

Page 23: Mavenized RCP

Pros and Cons of Test Fragments

• Pros– We have the ability to test all but private methods throughout

an entire RCP application using a Maven build– Tests are split out and don’t all have to be run at once when

wanting to run just the set of tests for a particular RCP plugin• Cons

– Number of RCP projects in the build reactor essentially doubles (for each RCP bundle we now have a fragment bundle as well)

– Each test fragment will create an OSGi process to run it’s own set of tests, that means many OSGi processes created and destroyed throughout an entire build, this can cause significant build slowness

Page 24: Mavenized RCP

Tycho: The Maven plugin for RCP

1. What is Tycho and how is it used?2. Setting up Packaging Types for RCP Resources3. Materializing RCP applications

Page 25: Mavenized RCP

What is Tycho

• Tycho is THE tool that glues Maven back to a system that is still tightly coupled to OSGi metadata

• Tycho is a set of maven plugins for: initial pom creation - tycho-pomgeneratorartifact versioning - tycho-versionsCompilation - tycho-compilerPackaging - tycho-packagingEclipse Process Creation - tycho-eclipserunTesting - tycho-surefire

Page 26: Mavenized RCP

Steps to setting up Tycho1. To begin we need a pom file for each RCP project

– From the root of the overall project we need to run this command: “mvn org.eclipse.tycho:tycho-pomgenerator-plugin:generate-poms -DgroupId="com.example"”

2. Need to verify that the plugins have the correct packaging type: eclipse-plugin eclipse-feature eclipse-test eclipse-repository

3. Need to verify artifact names from the pom.xml files match the Bundle-Symbolic-Name from each Manifest.MF file

4. Need to verify the pom versions match the Bundle-Version numbers from the Manifest.MF file5. Must add an Eclipse repository location since we will require Eclipse framework jars for the RCP build:

<repositories><repository> <id>eclipse-indigo</id> <url>http://nexus.dfw.nicelabs.com/content/repositories/eclipse-indigo/</url> <layout>p2</layout></repository></repositories>

6. It is also recommended to configure the parent pom file for the overall project to specify the platform for the desired product

Operating System Architecture

Page 27: Mavenized RCP

Target Platform Configuration

• The Target Platform Configuration gives us a very simple mechanism to specifying the flavor that we will generate for our product

• The Target Platform is also necessary for determining the OS specific platform jars to use when executing our unit tests that require a Windowing System

• We can specify a single platform or multiple platforms for which we can generate executables Windows (32-bit, 64-bit) Linux (32-bit, 64-bit) Mac (32-bit, 64-bit)

Page 28: Mavenized RCP

Target Platform Configuration for Windows 64 Bit

<plugin><groupId>org.eclipse.tycho</groupId><artifactId>target-platform-configuration</artifactId><version>0.22.0</version>

<configuration><environments>

<environment><os>win32</os><ws>win32</ws><arch>x86_64</arch>

</environment></environments><pomDependencies>consider</pomDependencies>

</configuration></plugin>

Page 29: Mavenized RCP

Target Platform Configuration for Windows 32-bit and Mac 64-bit

<plugin><groupId>org.eclipse.tycho</groupId><artifactId>target-platform-configuration</artifactId><version>${tycho-version}</version>

<configuration><environments><!—WINDOWS--><environment><os>win32</os><ws>win32</ws><arch>x86</arch></environment><!—MAC--><environment><os>mac</os><ws>cocoa</ws><arch>x86_64</arch></environment></environments><pomDependencies>consider</pomDependencies>

</configuration></plugin>

Page 30: Mavenized RCP

Final View of our RCP product

Page 31: Mavenized RCP

Done!


Recommended