Posted by & filed under Software, Software Development.

  • DZone
  • Reddit
  • HackerNews
  • Twitter
  • Facebook
  • Google Plus
  • Pinterest
  • StumbleUpon
  • LinkedIn
  • Tumblr
  • BlinkList
  • Mister Wong
  • Add to favorites
  • Email

This post is attended to everyone who is creating Java applications with Eclipse Rich Client Platform. This article describes a working tycho configuration on working project (demo) project. That project can be build fully automatically with tycho on your CI server e.g. Jenkins.
If you have developed Eclipse RCP, you maybe also come to the conclusion that PDE-Build out of Eclipse IDE is not really an apropriate and stable way to build serious, production ready applications. But also automatization of PDE Build was not straightforward task, and a such is still not well documented (IMHO).
Furthermore maybe you heard about some alternatives like buckminister approach or athena. There is also a couple more approaches, but my focus yet is on tycho because i believe it has bright feature.
So again this post describe kick stat tycho approache the next topic may cover, artifact repository, CI Server or, advanced tycho tasks, fill fre to comment…

Tycho

Let me introduce tycho in few words here. Technically tycho is a set of maven plugins. But let it be said at the beginning, tycho tries to use all the eclipse PDE/JDT metadata first, everywhere it’s possible and therefore one of the goals of tycho project is to minimise configuraton duplication in maven artefacts. I try to show how this works on a working example.

But first here is the self-speaking list of tychos packaging types, i will covers here some of them more detailed.

  • eclipse-plugin result in Eclipse Plug-In bundle
  • eclipse-test-plugin result in a test Plugin
  • eclipse-feature wich eclipse feature as Result
  • eclipse-application builds Eclipse Applicaton
  • eclipse-repository builds repository an executables
  • eclipse-update-site responisble for update-sites

Tycho current release is 0.13.0 and is used in my example.

Example Application.

In this article used applicaton is Open source and can be cloned from GitHub (Shuron’s RCP Life Game). This app is a very basic but working implementation of Conways Life Game. Technically it consist of: one parent project, one plugin project, one feature, as well as one target and a one repository projects. If you check that out, you will be able to start the game out of eclipse IDE by klicking on the “Launch Eclipse Application” Button in open org.holbreich.lfgm.eclipse-repository/example.product file.
As you know an RCP application “have to” be build with some set of the eclipse platform plugins – target platform. That is where we start.

Target platform

The definition of the target platform in eclipse can be stored in file with file-extension .target. So my example target platform definition looks like following.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.6"?>
<target name="eclipse 3.7.1 (indigo)" sequenceNumber="16">
 <locations>
  <location includeAllPlatforms="false" includeMode="planner" includeSource="false" type="InstallableUnit">
  <unit id="org.eclipse.rcp.source.feature.group" version="3.7.1.r37x_v20110729-9DB5FmNFnFLSFCtLxnRfMqt15A4A"/>
  <unit id="org.eclipse.equinox.sdk.feature.group" version="3.7.1.R37x_v20110907-7M7W8h8eNV4Vrz-hz01A7SL_MhZP"/>
  <unit id="org.eclipse.pde.feature.group" version="3.7.1.r37x_v20110810-0800-7b7qFVtFEx2XnmZ4jlM5mjM"/>
  <repository location="http://download.eclipse.org/releases/indigo"/>
 </location>
</locations>
</target>

Maven’s central project configuration file is pom.xml. The Element build of the pom.xml is a central element where all the needed (plugin) declarations are placed, so that maven is able to get the knowlege about how to compile and build desired artefacts. Typically you’ll find here the definition of needed maven plugins with their configurations, executions and goals. Please see pom.xml Reference on detailed information on how it works toghether in maven.

The target platfrom which was mentioned abow is introduced to maven through mavens’s build-helper-maven-plugin as an artifact. See the configuration section of that plugin.

 <build>
    <plugins>
       <plugin>
        <!-- Id and version of build helper plugin -->
	<groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
	<version>1.3</version>
		<executions>
		<execution>
		  <id>attach-artifacts</id>
		  <phase>package</phase>
		  <goals>
			<goal>attach-artifact</goal>
		  </goals>
		  <configuration>
		        <artifacts>
                             <artifact>
				 <file>indigo.target</file>
				 <type>target</type>
				 <classifier>indigo</classifier>
			     </artifact>
		         </artifacts>
		  </configuration>
		</execution>
		</executions>
	</plugin>
	</plugins>
</build>

Now our target platform can be used whenever we like and we would like to use it nearly everywhere, so that leads to the idea to provide this last configuration only once in the parent pom.xml of the maven parent project for the whole Life Game Application.

Parent project

A parent project is a maven way to handle a kind of configuration inheritance. My so called parent project defines some usefull and multiply used things for all of the modules used in the current application and also provides me the ability to build the whole application at once. Let me show you the whole file here, excuse me if it appears a bit unreadable now.

<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 

http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>org.holbreich.lfgm</groupId>
  <artifactId>parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>Shuron's Life Game Maven Parent Project</name>

  <properties>
    <!-- just some properties, tycho version and encoding -->
  <tycho-version>0.13.0</tycho-version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
<!-- eclipse IDE flat project style. So parent project is only sibling folder
   therefore has to acces his modules by "../". Here are all the child modules. -->
	<modules>
		<module>../org.holbreich.lfgm</module>
		<module>../org.holbreich.lfgm.target</module>
		<module>../org.holbreich.lfgm.feature</module>
		<module>../org.holbreich.lfgm.eclipse-repository</module>
	</modules>

	<build>
		<plugins>
                  <!-- defintion of tychos target-platform-configuration plugin -->
			<plugin>
				<groupId>org.eclipse.tycho</groupId>
				<artifactId>target-platform-configuration</artifactId>
				<version>${tycho-version}</version>
				<configuration>
					<resolver>p2</resolver>
					<target>
                            <!--  A reference to target platform artefact: -->
						<artifact>
							<groupId>org.holbreich.lfgm</groupId>
							<artifactId>target-platform</artifactId>
							<version>1.0.0-SNAPSHOT</version>
							<classifier>indigo</classifier>
						</artifact>
					</target>
					<ignoreTychoRepositories>true</ignoreTychoRepositories>
                           <!-- Environment configuration for the taget platform -->
					<environments>
						<environment>
							<os>win32</os>
							<ws>win32</ws>
							<arch>x86</arch>
						</environment>
						<environment>
							<os>linux</os>
							<ws>gtk</ws>
							<arch>x86</arch>
  						</environment>
					</environments>
				</configuration>
			</plugin>
                 <!-- defintion of tycho-maven-plugin -->
			<plugin>
				<groupId>org.eclipse.tycho</groupId>
				<artifactId>tycho-maven-plugin</artifactId>
				<version>${tycho-version}</version>
				<extensions>true</extensions>
			</plugin>
		</plugins>
	</build>
</project>

As already mentioned in the comments of the pom.xml that defines known modules and a set of plugins with their configuration, here actually two plugins:

  • target-platform-configuraton – which refers to allready discussed target platform artifact and provides aditional environment configuration.
  • tycho-maven-plugin – which cdefines  addtional packaging types like eclipse-plugin and eclipse feature.

That definition allows you to minimize pom.xml of the plugin’s and features self.

Plug-in pom.xml

As all used plugins are already defined in the parent, the actual the pom.xml file of the pluign project is pretty short and looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 

http://maven.apache.org/xsd/maven-4.0.0.xsd"

	xmlns="http://maven.apache.org/POM/4.0.0" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<artifactId>org.holbreich.lfgm</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<packaging>eclipse-plugin</packaging>
	<!-- Parent reference -->
	<parent>
    	 <artifactId>parent</artifactId>
    	 <groupId>org.holbreich.lfgm</groupId>
    	 <version>1.0.0-SNAPSHOT</version>
    	 <relativePath>../org.holbreich.lfgm.parent/pom.xml</relativePath>
  	</parent>
</project>

And this is great, becuase in a larg application you will have much of the plugings with their simple pom files.
You see the important moment is the reference to the parent and declaration of the packaging type eclipse-plugin. Eclipse Feature project uses eclipse-feature packaging target, but looks most the same, so i’m not showing it here.

Repository

And finally Repositoy Plugin come into play. It’s defines routines for the last assembly and packing of a product. Here i bring only the build element of the pom.xml file where the execution element of tycho-p2-director-plugin defines these two goals.

  <build>
	<plugins>
	<plugin>
		<groupId>org.eclipse.tycho</groupId>
		<artifactId>tycho-p2-director-plugin</artifactId>
		<version>${tycho-version}</version>
		<executions>
			<execution>
				<id>materialize-products</id>
				<goals>
					<goal>materialize-products</goal>
				</goals>
			</execution>
			<execution>
				<id>archive-products</id>
				<goals>
					<goal>archive-products</goal>
				</goals>
			</execution>
		</executions>
	</plugin>
	</plugins>
</build>

Now here we are. I’v didn’t mentioned further eclipse artefacts like feature.xml or some.project, they stay as usual and musst work also whitout maven. You can start to buld your app by executing maven golas like mvn clean install or make this configuration in your CI.

Build automatisation with Jenkins CI

The showed configuration is ready for automation as it is. You can automate this e.g. very simple with a standard Jenkins maven job. Provide git chekout path, for all the projects and define e.g. clean install as maven goals for execution on parent project’s pom.xml in yout Jenkins Job.

However zipped standalone executables for Linux and Windows can be found under org.holbreich.lfgm.eclipse-repository/target/products/ in the project workspace after sucessfull build. Have fun and let me know if you missed something i this description.

Further questions

This post was supposed to give you first motivation to try tycho on your own project and of course not all the aspects of the tycho build are covered here. I think following aspects are good topics for a discussion and future articles:

  • Release configuration and management is e.g. a topic for itsself and is straght-forward maven relase.
  • Eclipse Test Plugin
  • Code qulity with maven: Ceckstyle, PMD, corbetrura & Co
  • Eclipse repository and update-side management
  • More maven best practices

Let me know if something of the abow topic is something of your interesst.
As well you are invited to comment your solutions and best practices.

Further Readings

Tank you for reading if you got here ;)

16 comments
Steffen D
Steffen D

Hey there,

 

thank you for this tutorial, it helped a lot for the beginning. I'm trying to build the application directly via shell, via Jenkins and via Hudson. The first two solutions wirked without problems, but Hudson is giving me a NPE. (see http://pastebin.com/3VQjBHuz ) The same configuration worked with Jenkins, but neither with Hudson 2.2.1 nor with Hudson 3.0.0-RC4.

I have no idea where this error comes from, but perhaps someone knows!?

 

Thanks in advance,

Steffen

shuron
shuron moderator

Hi, the exception beginns with: "ERROR: Processing failed due to a bug in the code. Please report this to dev@hudson.java.netjava.lang.NullPointerException        at hudson.FilePath.isAbsolute(FilePath.java:214)        at hudson.FilePath.<init>(FilePath.java:202)        at hudson.FilePath.child(FilePath.java:938)"

 

and it clearly say that it is a Hudson bug... I'm not sure how well is Hudson supported now. Why not using Jenkins?

@hudsonci

shuron
shuron

Nice to know. Seems that tycho has future ;)

Lars Vogel
Lars Vogel like.author.displayName 1 Like

Wrt. Athena the original creator of Athena has also switched to Tycho and this project is not maintained anymore.

shuron
shuron

Hi yogen, to you first question: have you defind the target file helios.target also? If yes, is it correct? to your second question: Why do you need to copy something (automaticaly on maven build?) to the product directory if it was not part of product or underlaying feature? Did i get your qustion right?

yogen
yogen

@Tostao you are getting this error bcz your anot having qualifier associated with your version info. your plugin or features' plugin.xml or mainfest file should have version like this "1.0.0.qualifier" not like this "1.0.0" or something.

yogen
yogen

Hi, How can I copy some folder from a outside folder to the product target folder. For example If I have created a product for windows my target in repository will look like this "eclipse-repository\target\products\com.gd.convego.assist.ace.product\win32\win32\x86" This the folder where I want to copy some folders from a directory which is outside the project folders say "C:/Mydata/folder1" "C:/Mydata/folder2" etc. How can I do this in given example of blog.?

yogen
yogen

Sub: swt implementation fragment bundle error Hi, I am using maven3 and eclipse helios 3.6. I have imported the sample projects into my workspace and change target for helios instead of "indigo" at parent pom org.holbreich.lfgm target-platform 1.0.0-SNAPSHOT helios and at target prject pom... helios.target target helios Thats all I have changes and execute mvn clean install..but I am getting "swt implementation fragment bundle" error. Please help me how to resolve this error. Please see error at console mentioned below. INFO: basic authentication scheme selected [ERROR] Internal error: java.lang.RuntimeException: Could not determine SWT implementation fragment bundle -> [Help 1] org.apache.maven.InternalErrorException: Internal error: java.lang.RuntimeException: Could not deter mine SWT implementation fragment bundle at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:168) at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537) at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196) at org.apache.maven.cli.MavenCli.main(MavenCli.java:141) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:623) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290) at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409) at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352) Caused by: java.lang.RuntimeException: Could not determine SWT implementation fragment bundle at org.eclipse.tycho.p2.impl.resolver.ProjectorResolutionStrategy.fixSWT(ProjectorResolution Strategy.java:151) at org.eclipse.tycho.p2.impl.resolver.ProjectorResolutionStrategy.resolve(ProjectorResolutio nStrategy.java:110) at org.eclipse.tycho.p2.impl.resolver.P2ResolverImpl.resolveProject(P2ResolverImpl.java:102) at org.eclipse.tycho.p2.impl.resolver.P2ResolverImpl.resolveProject(P2ResolverImpl.java:69) at org.eclipse.tycho.p2.resolver.P2TargetPlatformResolver.doResolvePlatform(P2TargetPlatform Resolver.java:342) at org.eclipse.tycho.p2.resolver.P2TargetPlatformResolver.resolvePlatform(P2TargetPlatformRe solver.java:162) at org.eclipse.tycho.core.resolver.DefaultTychoDependencyResolver.resolveProject(DefaultTych oDependencyResolver.java:85) at org.eclipse.tycho.core.maven.TychoMavenLifecycleParticipant.afterProjectsRead(TychoMavenL ifecycleParticipant.java:91) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:274) at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156) ... 11 more [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following arti cles: [ERROR] [Help 1] 

Fabian
Fabian

Hi, Thanks for tip. So I am trying the second "cleaner" method, but when I run "mvn clean install" I got an error : org.apache.maven.InternalErrorException: Internal error: java.lang.RuntimeException: "No solution found because the problem is unsatisfiable.": ["Unable to satisfy d ependency from org.home.hellofab 1.0.0.qualifier to bundle org.home.hellofab.libs.collections 1.0.0.", "No solution found because the problem is unsatisfiable."] Assuming that org.home.hellofab is my test project which uses org.apache.commons.collections that I have bundle using eclipse wizard in org.home.hellofab.libs.collections 1.0.0. Any idea of what is wrong in my config?

shuron
shuron

Thank you for this very good question. Merging the OSGi/eclipse world to whatever maven is tricky. Tycho defines OSGi plug-in dependency system as leading system for dependency resolving. So i would say you can't and should not define dependencies through maven. To use a library you have at least two ways. 1) The easies: you just include this library into the plug-in. In that case no additional configuration is needed outside of that plug-in. But this is not recommended way in sense of reusage of this lib and in a sense of clean code separation. 2) The "cleaner" way is to use apache-commons (or whatever) are bundle. You can create bundles of "normal" jars directly out of eclipse (New->Project->Plugin from existing jar). This creates new bundle (Plug-in) which can be reference from another plug-in. Just repeat the configuration like one in org.holbreich.flgm. P.S. We could use maven to resolve dependencies of such libraries and automatically creation of bundles (See apache Felix). However you have to define the dependencies between the components of your RCP app manually again. Hope this answers your question. Fill free to refine your problem.

Bob
Bob

I want add appache-commons to project, in which pom add dependency?I would like use it in org.holbreich.lfgm. Best regards ( org.apache.commons commons-lang3 3.1 )

shuron
shuron

tostao thank you for your feedback. So mvn eclipse:eclipse is wrong. It will not bring my app to work. Do the following: mvn clean install on org.holbreich.lfgm.parent project. it schould buld everything. This Could take log because target platform and maven artefact will be downloaded. If this fails somehow then try to build org.holbreich.lfgm.target first. However normaly there is no need to do it separatelly. Feel free to as further questions.

dupas
dupas

good post!! best regards

tostao
tostao

Hello Alexander, is's fantastic post,now i know much more howbuild RCP by maven. I checkouted Your game of life,when i execute mvn eclipse:elipse (to generate .project,.classpath) everything is ok, when i execute mvn eclipse:clean to delete files as above everything works fine, but when i try to generate this file one more time (mvn eclipse:eclipse) maven shows error: [INFO] Shuron's Life Game Maven Parent Project SUCCESS [1.419s] [INFO] org.holbreich.lfgm .............. FAILURE [0.374s] [INFO] target-platform ......................... SKIPPED [INFO] org.holbreich.lfgm.feature ............. SKIPPED [INFO] eclipse-repository ................... SKIPPED [INFO] ------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------- [INFO] Total time: 50.430s [INFO] Finished at: Thu Apr 19 15:37:05 CEST 2012 [INFO] Final Memory: 60M/143M [INFO] ------------------------------------------ [ERROR] Failed to execute goal org.eclipse.tycho:tycho-packaging-plugin:0.13.0:validate-version (default-validate-version) on project org.holbreich.lf gm: OSGi version 1.0.0.SNAPSHOT must have .qualifier qualifier for SNAPSHOT builds -> [Help 1] Could You take a look of this problem?I think its problem between manifest.mf:bundle-version and pom.xml version. If i fix it, I come back here :)

shuron
shuron

Thank you for this question. This is a question for addtional Post. Unfortunately my maven repository is not ready yet:( But in general tycho don't need more magic than normal release of maven artefacts. I'll try to post about it it in the next time. P.S. Maven Release Plugin is good place to start reading about "releasing of artefacts".

jaklumow
jaklumow

Thanks for posting. Is it possible to see the whole approach? I mean how it works toghether with a maven repository? how to release the artefacts? sorry i'm not familar with maven.

Trackbacks

  1. [...] definition in declarative approach. Next article will cover OSGi Blueprint DI container. Also look here for more complex tycho example. Why modulesBreaking a system in modules is a very important [...]