Maven Tycho
General Remarks
This page is meant to collect pointers to Maven Tycho. Please note that projects such as Palladio or Vitruvius provide parent POMs that already integrate the best practices and tips below and provide sensible defaults for many open choices. Refer to the documentation of these projects to comply with their build standards.
If you are not contributing to one of these projects, you might still want to use the build instructions of MDSD.tools because they provide a good starting point for independent projects as well. Obviously, you have to care by yourself your the continuous integration system and execution of your build.
It is unlikely that this page will be up to date with the latest recommendations. Therefore, consider referring to publicly available and continuously maintained tutorials (see Pointers).
Pointers
- Vogella Tutorial
- Tycho FAQ
- slides of teaching group (most likely outdated when reading this)
- slides of teaching group regarding build pitfalls (most likely outdated when reading this)
Most Common Approach
In addition to your existing Eclipse extension, you have to provide the following items
- Parent POM that defines commonly used Maven plugins
- Aggregator POM that references all separate projects
- Main POM in the project root that is called to build the complete extension
- POM file for every project
The first three POM files can be merged into the main POM in the root folder for simple projects. If you create builds for an existing project like Palladio or Vitruvius, a parent POM usually already exists.
Parent POM
The parent POM defines commonly used plugins and properties. All other POMs reference it and reuse the definitions. The group ID and the version can be omitted in depending POMs.
In order to use tycho, you have to include the tycho-maven-plugin
and the target-platform-configuration
plugins into your build process. The former enables Tycho. The latter defines the target platform for the build process. In order to ensure properly working plugins on various platforms, you should add them to the configured environments. The dependencies are resolved by the P2 repositories given in the repositories
section or by an Eclipse target platform file. The former is easier to use but the latter gives you more control regarding the used feature versions.
Additionally, it is beneficial to include the maven-compiler-plugin
plugin and specify the targeted Java version. Thereby, build errors related to wrong Java versions can be detected easily.
<?xml version="1.0" encoding="UTF-8"?>
<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>de.cooperateproject.plantumlpp</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<tycho.version>0.24.0</tycho.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<repositories>
<repository>
<id>eclipse</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/mars</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho.version}</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho.version}</version>
<configuration>
<environments>
<environment>
<os>linux</os>
<ws>gtk</ws>
<arch>x86</arch>
</environment>
<environment>
<os>linux</os>
<ws>gtk</ws>
<arch>x86_64</arch>
</environment>
<environment>
<os>win32</os>
<ws>win32</ws>
<arch>x86</arch>
</environment>
<environment>
<os>win32</os>
<ws>win32</ws>
<arch>x86_64</arch>
</environment>
<environment>
<os>macosx</os>
<ws>cocoa</ws>
<arch>x86_64</arch>
</environment>
</environments>
</configuration>
</plugin>
</plugins>
</build>
</project>
Aggregator POM
The aggregator POM references all other artifacts in the modules
section except for the parent POM. The parent POM is referenced in the parent
section instead. The aggregator is necessary to resolve dependencies to artifacts that are not available at a P2 repository because they are under development.
<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>
<parent>
<groupId>de.cooperateproject.plantumlpp</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../de.cooperateproject.plantumlpp.parent</relativePath>
</parent>
<artifactId>de.cooperateproject.plantumlpp.aggregator</artifactId>
<packaging>pom</packaging>
<modules>
<module>../../features/de.cooperateproject.plantumlpp.feature</module>
<module>../../bundles/de.cooperateproject.plantumlpp.notation2plant</module>
<module>../../tests/de.cooperateproject.plantumlpp.notation2plant.tests</module>
<module>../../bundles/de.cooperateproject.plantumlpp.notation2plant.generator</module>
<module>../../tests/de.cooperateproject.plantumlpp.notation2plant.generator.tests</module>
<module>../../bundles/edu.kit.ipd.sdq.commons.ecore2txt</module>
<module>../../bundles/edu.kit.ipd.sdq.vitruvius.framework.util</module>
<module>../../bundles/de.cooperateproject.plantumlpp.notation2plant.viewer</module>
</modules>
</project>
Main POM
The main POM is located in the document root of the Eclipse extension and references the aggregator and the update site, as well as the parent. If this POM is called with a specific goal, all transitively referenced POMs are called with a specific goal. The build order is automatically derived by Maven.
<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>
<parent>
<groupId>de.cooperateproject.plantumlpp</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>releng/de.cooperateproject.plantumlpp.parent</relativePath>
</parent>
<artifactId>de.cooperateproject.plantumlpp.main</artifactId>
<packaging>pom</packaging>
<modules>
<module>releng/de.cooperateproject.plantumlpp.aggregator</module>
<module>releng/de.cooperateproject.plantumlpp.updatesite</module>
</modules>
</project>
Individual Artifact POM Files
The POM files for invidivual artifacts can be kept pretty simple. The only thing you need is the reference to the parent POM, the artifact id and the packaging type. In our context, the following packaging types are relevant:
eclipse-plugin
eclipse-test-plugin
eclipse-feature
eclipse-repository
<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>
<parent>
<groupId>de.cooperateproject.plantumlpp</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../de.cooperateproject.plantumlpp.parent</relativePath>
</parent>
<artifactId>de.cooperateproject.plantumlpp.updatesite</artifactId>
<packaging>eclipse-repository</packaging>
</project>
Please note that you can omit these individual POM files by telling tycho to create these files on demand. In order to do this, you have to create a .mvn
folder in the root of your project with a file extensions.xml
containing the following instructions (please use the same tycho version as in your POM files):
<?xml version="1.0" encoding="UTF-8"?>
<extensions>
<extension>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-pomless</artifactId>
<version>0.24.0</version>
</extension>
</extensions>
Special Tasks
Compiling Xtend Source Files
Xtend files can be compiled easily by adding the following snipped to your parent POM. The xtend files are translated to java files and compiled together with the remaining source files later. Please note that the dependency section has to match the xtex.version
variable. The dependencies are only required because of a bug in the xtend-maven-plugin, which might be fixed in future versions.
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
<version>${xtext.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<outputDirectory>xtend-gen</outputDirectory>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.core</artifactId>
<version>3.12.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.platform</groupId>
<artifactId>org.eclipse.core.runtime</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.platform</groupId>
<artifactId>org.eclipse.equinox.common</artifactId>
<version>3.8.0</version>
</dependency>
</dependencies>
</plugin>
Deploying Source Files
To deploy the source files of plugins, it is necessary to use Maven plugins for creating source jars of the Eclipse plugins and the Eclipse features, as well as for handling source features by p2 updatesite generators. The general process is described here and the example code can be found on GitHub.
The tycho-source-plugin is necessary for automatically creating source-jars of the Eclipse plugins:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho.version}</version>
<executions>
<execution>
<id>plugin-source</id>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
The tycho-source-features-plugin is necessary for automatically creating source-jars of the Eclipse features:
<plugin>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-source-feature-plugin</artifactId>
<version>${tycho.version}</version>
<executions>
<execution>
<id>source-feature</id>
<phase>package</phase>
<goals>
<goal>source-feature</goal>
</goals>
</execution>
</executions>
</plugin>
The tycho-p2-plugin is necessary to correctly integreate sources into p2 updatesites:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-plugin</artifactId>
<version>${tycho.version}</version>
<executions>
<execution>
<id>attached-p2-metadata</id>
<phase>package</phase>
<goals>
<goal>p2-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
To integrate the sources-features into a p2 updatesite, they have to be referenced in the category.xml of the updatesite project. They must not be referenced with a url but by the original feature id with the suffix .source. For example, having a feature edu.kit.ipd.sdq.test.feature, the sources can be deployed on the updatesite by adding a feature with the id edu.kit.ipd.sdq.test.feature.source.
Local Building of Dependency Trees
Tycho can resolve dependencies via Maven or via Eclipse Update Sites. In Eclipse projects, dependencies are often only available via update sites. However, this makes testing a dependency tree quite complex: assume you have a project on which two other projects depend. If you locally change the first project, you can easily build it via Maven but the other two projects refer to the update site of the first project, which has not been updated yet. Therefore, you have to inject these new artifacts into your local build. The most obvious approach is to fire up a local webserver and replace the URLs of the update sites by hand. This works but does not scale for a whole dependency tree (i.e. projects that transitively depend on your changed project). In the following, we describe an approach that scales better:
For every project that yields new artifacts that have to be injected in the build process, do the following:
- build the project locally using maven
- navigate to the updatesite result directory (usually the folder
target/repository
- start a local webserver (see [1] for a list of one-line web servers) on a free port (e.g. 8080)
- merge the following section into your maven settings file (
~/.m2/settings.xml
) and replace the example URLs of the PCM project with the matching values for your case
<settings>
<mirrors>
<mirror>
<id>local-pcm-core</id>
<name>Local PCM-Core Mirror</name>
<url>http://localhost:8080/</url>
<layout>p2</layout>
<mirrorOf>https://updatesite.palladio-simulator.com/palladio-core-pcm/nightly/</mirrorOf>
<mirrorOfLayouts>p2</mirrorOfLayouts>
</mirror>
</mirrors>
</settings>
The mirror setting intercepts the HTTP connection to the update site and redirects request to your local HTTP server. Please note that the mirror setting distinguishes HTTP and HTTPS connections. So, if you have HTTP and HTTPS connections to the same update site, you have to add two mirror settings for the respective URLs. Obviously, you have to build the projects in the appropriate order to make this approach work. For instance, you cannot expect to build a project that depends on a changed project before a mirror for the dependency exists.