Maven Tycho

Aus SDQ-Wiki
Wechseln zu: Navigation, Suche

Script and Explanations

If you want to build Eclipse plug-ins with maven tycho you can

Introduction

Maven Tycho [1] is an extension to the Maven build management that allows building Eclipse plugins, features, update sites, and products. Eclipse-related projects often use Tycho in their continuous integration lifecycle. Tycho can be configured to be fully compatible with the Eclipse way of developoing plugins, especially with the usual folder structure. Dependency resolution uses P2 repositories and artifacts from Maven repositories.

There are two different approaches for defining a build with Maven Tycho: The POM-first and the manifest-first approach. The following sections describe the manifest-first approach, its application in a real world project, the advantages, and drawbacks. We assume that the reader is familar with the basic concepts of Maven [2], esepcially with POM files and the life-cycle.

Best practices

Eclipse Plugins

We assume several usage pattern for developing Eclipse plugins.

  • Tests are stored in separate Plugin Test Projects
  • Source code is stored in a folder called test (restriction does not exist for Palladio projects)
  • Generated source code is stored in a folder called src-gen
  • Generated source code from Xtend is stored in a folder called xtend-gen

These assumptions intentionally violate the prescribed project structure of Maven to better match commonly used Eclipse structures.

Folder structure

The folder structure for your whole project (consisting of many plugins, features, ...) should adhere to the structure suggested by Dirk Fauth [3] in order to make life easier later. The suggested structure is as follows:

  • Project Root
    • bundles (contains all plugin projects)
    • tests (contains all test projects)
    • features (contains all feature projects)
    • releng (contains helper projects and the update site project)

Tutorial (Manifest-First)

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.