Home Tutorials Training Consulting Books Company Contact us


Get more...

This tutorial describes the usage of the Maven Tycho plug-in to build plug-ins, bundles and Eclipse applications. It uses Tycho version 4.0.10.

It starts with a general overview and gives a details example for building Eclipse components.

1. Using Maven Tycho to build Eclipse components

A process of generating an executable application from your source code is termed building your application. A headless build builds your application via the command line or via a build server, typically without user interaction. The outcome, packaged as a zip file, can then be delivered to end users.

Tycho[https://github.com/eclipse-tycho/tycho] is a collection of Maven plugins dedicated to building Eclipse plug-ins, features, products, and OSGi bundles. A Tycho build is configured via one or multiple pom.xml files.

At minimum, one pom file is necessary to configure the Tycho build process. Each module can define its own pom file or utilize Tycho’s functionality to derive this information from existing metadata.

To see the generated pom files, use mvn clean verify -Dpolyglot.dump.pom=pom-for-review.xml, the pom-for-review.xml was used to avoid that the generated pom files are used by the build.

2. Exercise: Setting up a Maven build for an Eclipse application

In this exercise, you configure a command line build using Maven Tycho for your Eclipse components. The description assumes that all artifacts are placed in the same top-level directory.

2.1. Enable the Tycho build extension

Create a configuration file in the main directory in which all your Eclipse artifacts are stored.

To do this, create a a new directory called .mvn in the main directory. In this .mvn folder create a new file extensions.xml.

This is difficult to do from the Eclipse IDE, this the top-folder is not inside a projects. Use your file explorer and a regular text editor to create this file (this editor must allow to save the content as regular text).

The content of the .mvn/extensions.xml must look like the following:

<extensions>
  <extension>
    <groupId>org.eclipse.tycho</groupId>
    <artifactId>tycho-build</artifactId>
    <version>4.0.10</version>
  </extension>
</extensions>

2.2. Create a top-level pom file

Create the following pom.xml file in the top-level directory of your projects.

This is difficult to do from the Eclipse IDE, this the top-folder is not inside a projects. Use your file explorer and a regular text editor to create this file (this editor must allow to save the content as regular text).

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.vogella.tycho</groupId>
 <artifactId>releng</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>

 <properties>
  <tycho.version>4.0.10</tycho.version>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <build>
   <pluginManagement>
     <plugins>
       <plugin>
         <groupId>org.eclipse.tycho</groupId>
         <artifactId>tycho-p2-director-plugin</artifactId>
         <version>${tycho.version}</version>
       </plugin>
     </plugins>
   </pluginManagement>

  <plugins>
   <plugin>
    <groupId>org.eclipse.tycho</groupId>
    <artifactId>tycho-maven-plugin</artifactId>
    <version>${tycho.version}</version>
    <extensions>true</extensions>
   </plugin>
   <!--Enable the replacement of the SNAPSHOT version in the final product configuration-->
   <plugin>
        <groupId>org.eclipse.tycho</groupId>
            <artifactId>tycho-packaging-plugin</artifactId>
             <version>${tycho.version}</version>
             <executions>
              <execution>
                <phase>package</phase>
                <id>package-feature</id>
                    <configuration>
                        <finalName>${project.artifactId}_${unqualifiedVersion}.${buildQualifier}</finalName>
                    </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
    <groupId>org.eclipse.tycho</groupId>
    <artifactId>target-platform-configuration</artifactId>
    <version>${tycho.version}</version>
    <configuration>
     <!-- Optional set the Java version you are using-->
      <!--   <executionEnvironment>JavaSE-17</executionEnvironment>-->
     <environments>
      <environment>
       <os>linux</os>
       <ws>gtk</ws>
       <arch>x86_64</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>
  <modules>
   <!--TODO ADD YOUR MODULES HERE-->
 </modules>
</project>

2.3. Validate build setup

Run the build via mvn clean verify, this build should be successful. No build artifact is created. The output should be similar to the following:

[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.vogella.tycho:releng >----------------------
[INFO] Building releng 1.0.0-SNAPSHOT
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ releng ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.984 s
[INFO] Finished at: 2020-09-07T09:36:03+02:00
[INFO] ------------------------------------------------------------------------

3. Exercise: Using a target platform for the build

You could now build Eclipse components which have only dependencies to Java runtime classes. To make additional libraries available you configure the build to use your target definition file. This target definition file specifies the available libraries for the build and should also be used for development to ensure you compile against the same libraries.

You could add the target platform project to the build: * By pointing directly to the target file * Or by definining a Maven project for the target project

We use the first approach in this exercise, as it is easier.

See below for a full listing of the top-level pom file.

Adjust the target-platform-configuration to use your target file. This code assumes that you have one project named target-platform with your target definition file named target-platform.target.

<!-- this part already exists......-->
<plugin>
    <groupId>org.eclipse.tycho</groupId>
    <artifactId>target-platform-configuration</artifactId>
    <version>${tycho.version}</version>
    <configuration>
<!-- THIS PART IS NEW-->
     <target>
      <file>../target-platform/target-platform.target</file>
    </target>

Here is complete top-level pom file.

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.vogella.tycho</groupId>
 <artifactId>releng</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>

 <properties>
  <tycho.version>4.0.10</tycho.version>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <build>
  <pluginManagement>
     <plugins>
       <plugin>
         <groupId>org.eclipse.tycho</groupId>
         <artifactId>tycho-p2-director-plugin</artifactId>
         <version>${tycho.version}</version>
       </plugin>
     </plugins>
   </pluginManagement>
  <plugins>
   <plugin>
    <groupId>org.eclipse.tycho</groupId>
    <artifactId>tycho-maven-plugin</artifactId>
    <version>${tycho.version}</version>
    <extensions>true</extensions>
   </plugin>
   <!--Enable the replacement of the SNAPSHOT version in the final product configuration-->
   <plugin>
        <groupId>org.eclipse.tycho</groupId>
            <artifactId>tycho-packaging-plugin</artifactId>
             <version>${tycho.version}</version>
             <executions>
              <execution>
                <phase>package</phase>
                <id>package-feature</id>
                    <configuration>
                        <finalName>${project.artifactId}_${unqualifiedVersion}.${buildQualifier}</finalName>
                    </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
    <groupId>org.eclipse.tycho</groupId>
    <artifactId>target-platform-configuration</artifactId>
    <version>${tycho.version}</version>
    <configuration>
     <!-- Optional set the Java version you are using-->
    <executionEnvironment>JavaSE-17</executionEnvironment>-->
     <target>
      <file>../target-platform/target-platform.target</file>
    </target>
     <environments>
      <environment>
       <os>linux</os>
       <ws>gtk</ws>
       <arch>x86_64</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>

 <modules>
     <!--<module>your modules will be defined here</module>-->

 </modules>
</project>

In the above listing the p2 repository is removed and the target-platform-configuration contains now a reference to the target definition in its configuration block.

3.1. Validate your build

Re-run your build and ensure that is still runs successfully.

3.2. Potential error resolution with the usage Java version

In the past Tycho used the Java version from the first artifact in build, if you have mixed Java requirements for your build, you may have to specify the Java version to build against.

In the above build file, the following line is used for that purpose.

    <executionEnvironment>JavaSE-17</executionEnvironment>

4. Exercise: Configure your modules

To add your Eclipse components to the build, you have to add it as module to the top-level pom file. A minimal setup contains only one plug-in which has no dependency to any other module.

In general all your plug-ins, features and products should be part of the build. All libraries will be provided by the target platform.

You may have create more plug-ins than listed below during the optional exercises, ensure that they are also part of your build.

5. Exercise: Validate the build

5.1. Run the build

Run the build from the main directory via the following command:

mvn clean verify

This should result in a success message, similar to the following.

[INFO] Reactor Summary:
[INFO]
[INFO] releng 1.0.0-SNAPSHOT .............................. SUCCESS [  0.114 s]
[INFO] [bundle] First 1.0.0-SNAPSHOT ...................... SUCCESS [  0.803 s]
[INFO] [feature] Feature 1.0.0-SNAPSHOT ................... SUCCESS [  0.283 s]
[INFO] [product] Custom IDE 1.0.0 ......................... SUCCESS [  4.311 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  17.499 s
[INFO] Finished at: 2020-09-07T16:16:15+02:00
[INFO] ------------------------------------------------------------------------

Press F5 in the Eclipse IDE on your feature project to refresh it. You should find a new target folder in your project which contains the JAR file for your feature. Also this JAR file still has the SNAPSHOT suffix. This suffix is replaced with the build time stamp once you build a product or an update site with the eclipse-repository packaging type.

5.2. Error resolution

If Tycho can not find a required plug-in or feature it gives an error message. The following is an example for a feature that requires a bundle but this bundle is not part of the build.

[ERROR] Missing requirement:
 com.vogella.tycho.feature.feature.group 1.0.0.qualifier
 requires 'com.vogella.tycho.plugin1 0.0.0' but it could not be found

If an independent build of the feature is required, you need to make the plug-in available via a repository. This can for example be done by building and installing the plug-in into the local Maven repository with the mvn clean install command.

In this case you need to either add the required module to the build or if you consume it in binary form, add it to the target platform.

6. Exercise: Tycho build for update sites

This exercise shows how to create Eclipse p2 update sites using Maven Tycho.

The Tycho build creates similar content for the product in the target\repository folder. The distinction between an update site created based on a category file and the target/repository folder generated for a product build primarily revolves around their intended use cases and content organization.

  • An update site created with Tycho based on a category file is specifically designed for distributing Eclipse plug-ins, features, and other components to Eclipse users. The category file (category.xml) serves as a manifest that defines how components are organized into categories, making it easier for users to discover and install them through the Eclipse Update Manager. This update site:

  • The target/repository folder generated during a product build with Tycho is a part of the build output that contains the assembled product, including all its required plug-ins, features, and configuration files. While it can also serve as an update site for the product, its primary purpose is to package the product build. It includes similar metadata files that describe the product’s contents, which allows it to be used to update or install the product.

6.1. Create a new project

Create a new project called updatesite in a project of type general.

6.2. Creating a Category Definition File for the Update Site

Right-click the project, navigate to New > Other…​ > Plug-in Development > Category Definition, and name the file category.xml. Create a new category by clicking the New Category button with:

  • com.vogella.tasks.update ID

  • Task management update site name.

Category creation

Click Add Feature…​ to add your feature project to the category.

Adding a feature to a category

6.3. Updating the Root POM

Include the new module in your root pom file.

 <modules>
    <!-- all modules as before -->
  <module>updatesite</module> (1)
 </modules>
1 Adds the updatesite project to the aggregator build

6.4. Running the Aggregator Build and Validating the Update Site

Execute the build from the main directory, ensuring it successfully completes and builds all components, including the update site.

Refresh your update site project in Eclipse IDE by pressing F5. A new target folder containing a repository folder, which holds the update site, should appear.

Build result

Ensure the SNAPSHOT suffix in the repository directory’s JAR files is replaced with the build qualifier.

6.5. Creating a self-contained p2 repository

Most Tycho components have options which can be configured. The following configuration will instruct Tycho to not build a zip file of the updatesite and to include all dependencies of the JAR files which are packed into the update site.

<plugin>
 <groupId>org.eclipse.tycho</groupId>
 <artifactId>tycho-p2-repository-plugin</artifactId>
 <version>${tycho.version}</version>
  <configuration>
    <skipArchive>true</skipArchive>
    <includeAllDependencies>true</includeAllDependencies>
  </configuration>
</plugin>

Run the build again and verify that all required libraries are part of the /target/repository/plugins folder.

7. Executing plug-in unit tests with Tycho

For the development of Eclipse components, it is common practice to have a separate test plug-in or fragment project for your tests.

Tycho supports pomless builds for plug-ins which contain tests. The test execution is done via the Tycho Surefire plug-in which is aware of plug-in dependencies.

The runtime behavior of the Maven Tycho Surefire plug-in is a little different to the Maven Surefire plug-in. Tycho Surefire tests run in the integration-test phase while regular Maven Surefire tests run in the test phase. The integration-test phase occurs between the package and install phases.

If you need to configure the tests, e.g. exclude some tests or specify parameters you can still can provide your pom file for the test plug-in.

The Tycho Surefire plug-in supports the execution of non-UI based and UI-based tests. If you want to run UI tests, you have to enable that explicitly via the useUIHarness parameter which is demonstrated by the following listing.

<project>
    <modelVersion>4.0.0</modelVersion>

    <!--parent pom... -->

    <artifactId>com.vogella.tycho.rcp.tests</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>eclipse-test-plugin</packaging>

    <build>
        <plugins>
         <plugin>
            <groupId>org.eclipse.tycho</groupId>
            <artifactId>tycho-surefire-plugin</artifactId>
            <version>${tycho.version}</version>
            <configuration>
                <useUIHarness>true</useUIHarness>
            </configuration>
         </plugin>
        </plugins>
    </build>

</project>

The tests are executed in a test runtime (based on OSGi), using the dependencies defined in the MANIFEST.MF file of the test plug-in. You can also include more dependencies in features ("eclipse-feature"), plug-ins or fragments ("eclipse-plugin") or installable units ("p2-installable-unit"). If you define a dependency you need to include their transitive dependencies in the test runtime, too.

<project>
 <modelVersion>4.0.0</modelVersion>

 <!--parent pom... -->

 <artifactId>com.vogella.tycho.rcp.tests</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>eclipse-test-plugin</packaging>

 <build>
  <plugins>
   <plugin>
    <groupId>org.eclipse.tycho</groupId>
    <artifactId>tycho-surefire-plugin</artifactId>
    <version>${tycho.version}</version>
    <configuration>
     <useUIHarness>true</useUIHarness>
     <dependencies>
      <dependency>
       <type>eclipse-feature</type>
       <artifactId>com.vogella.feature1</artifactId>
       <!-- This is the minimum required version -->
       <version>1.0.0</version>
      </dependency>
     </dependencies>
    </configuration>
   </plugin>
  </plugins>
 </build>


</project>

7.1. Selection of tests

Similar to the Maven Surefire plug-in, Tycho Surefire executes, by default, all test classes matching the following pattern:

  • **/Test*.java

  • **/*Test.java

  • **/*TestCase.java

  • _**/*Tests.java

This included tests can be configured via the includes parameter.

<project>
    <modelVersion>4.0.0</modelVersion>

    <!--parent pom... -->

    <artifactId>com.vogella.tycho.rcp.tests</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>eclipse-test-plugin</packaging>

    <!-- Define to include all classes in the test run -->
    <build>
     <plugins>
      <plugin>
        <groupId>org.eclipse.tycho</groupId>
        <artifactId>tycho-surefire-plugin</artifactId>
        <version>${tycho.version}</version>
         <configuration>
          <includes>
            <include>**/*.class</include>
          </includes>
         </configuration>
       </plugin>
     </plugins>
    </build>
</project>

You can also exclude tests from the run.

<project>
    <modelVersion>4.0.0</modelVersion>

    <!--parent pom...  -->

    <artifactId>com.vogella.tycho.rcp.tests</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>eclipse-test-plugin</packaging>

    <build>
        <plugins>

        <plugin>
         <groupId>org.eclipse.tycho</groupId>
         <artifactId>tycho-surefire-plugin</artifactId>
         <version>${tycho.version}</version>
            <configuration>
                <excludes>
                    <!-- Tests fails currently in the command line build-->
                    <exclude>ThisShouldNotRunViaTychoTests</exclude>
                </excludes>
            </configuration>
        </plugin>
        </plugins>
    </build>
</project>

You can also specify a specific test or test suite to be executed.

This requires setting the TestSuite to the Bundle-Symbolic-Name of the plug-in and the testClass parameter to the fully qualified class.

<!-- snippet -->
<build>
 <plugins>
  <plugin>
    <groupId>org.eclipse.tycho</groupId>
     <artifactId>tycho-surefire-plugin</artifactId>
     <version>${tycho.version}</version>
     <configuration>
        <testSuite>org.eclipse.e4.ui.tests.css.swt</testSuite>
        <testClass>org.eclipse.e4.ui.tests.css.swt.CssSwtTestSuite</testClass>
     </configuration>
    </plugin>
 </plugins>
</build>

7.2. Using the correct JRE for the test execution

The JDT compiler can be configured to use the compiler source/target level according to MANIFEST.MF settings. So it is possible to compile a Java 17 bundle using Java 17, even if the build process was started with a Java 21 JVM.

This does not work for running the tests. The tests are running with the build JVM by default, so if your tests required for example Java 21 you need to start the build process with a Java 21 runtime.

8. Exercise: Tycho build for test plug-ins

The following exercise demonstrates how to run unit tests with Tycho.

8.1. Adding the test dependencies

For testing usually JUnit is used, but also libraries like Hamcrest and Mockito are possible.

Therefore they are added to the target platform by using the Orbit repository. Please note that URL above is not a p2 update site, can can browse this website to find update sites.

The Orbit repository URLs might change over time.
In case this is not valid any more go to Orbit and look for the latest Orbit repository URL.

For test purposes the target definition could look like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
<target name="target-platform">
    <locations>
        <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
            <repository location="https://download.eclipse.org/releases/2020-03"/>
            <unit id="org.eclipse.equinox.sdk.feature.group" version="0.0.0"/>
            <unit id="org.eclipse.platform.sdk" version="0.0.0"/>
        </location>
        <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="    true" type="InstallableUnit">
            <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200224183213/repository"/>
            <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
            <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
            <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
            <unit id="org.junit" version="4.13.0.v20200204-1500"/>
        </location>
    </locations>
</target>

8.2. Create a new plug-in for the tests

The tests of the implementation belong into a separate plug-in or fragment project called com.vogella.tasks.ui.tests.

Create a new plug-in fragment project called com.vogella.tasks.ui.tests.

Define a dependency on org.junit in its MANIFEST.MF file.

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Tests
Bundle-SymbolicName: com.vogella.tasks.ui.tests
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: VOGELLA
Automatic-Module-Name: com.vogella.tasks.ui.tests
Bundle-RequiredExecutionEnvironment: JavaSE-21
Fragment-Host: com.vogella.tasks.ui
Require-Bundle: org.junit;bundle-version="4.13.0"

The defaults are sufficient for this test plug-in, hence we need do not need a separate pom for the test plug-in.

8.3. Create a unit test

Create the following unit test, as an example. Of course this test does not test anything real. It is only used to demonstrate how Tycho runs the tests.

package com.vogella.tasks.ui.tests;

import static org.junit.Assert.*;

import org.junit.Test;

public class ExampleTest {

    @Test
    public void test() {
        // just an example
        assertTrue(true);
    }

}

8.4. Run the build with the tests

Run the build from the main directory. This should work fine.

If you want to skip the test execution use mvn clean verify -DskipTests=true

8.5. Create test report

Run the following command to create test reports:

mvn clean verify surefire-report:report

You find the report in {basedir}/target/site/surefire-report.html.

8.6. Debug Maven Tycho tests via Eclipse

To debug Maven Tycho tests, add the -DdebugPort=8000 parameter to your Maven build command. Maven will pause during execution and you can create a Remote Java Application debug configuration to connect to the test.

9. Exercise: Adding a JRE to your application

9.1. Description

It is possible to add a JRE to your application so that no additional Java installation is required.

To make the Java runtime available add it to your target platform.

<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
    <repository location="https://download.eclipse.org/justj/jres/21/updates/release/latest/"/>
    <unit id="org.eclipse.justj.openjdk.hotspot.jre.minimal.feature.group" version="0.0.0"/>
</location>

Afterwards add the org.eclipse.justj.openjdk.hotspot.jre.minimal feature to your product.

Run the Tycho build, your generated product should now also contain a JRE and an additional entry in your *.ini file should point to this JRE.

9.2. Solution

The product now should have an ADDITIONAL entry for the JRE feature similar to the following.

The other plug-ins and features are not listed so you can not simply copy and paste this file onto your file.
<?xml version="1.0" encoding="UTF-8"?>
<?pde version="3.5"?>

<product name="taskmanagement" uid="tasksmanagement" id="com.vogella.tasks.ui.product" application="org.eclipse.e4.ui.workbench.swt.E4Application" type="mixed" includeLaunchers="true" autoIncludeRequirements="true">

   <configIni use="default">
   </configIni>

   <launcherArgs>
      <programArgs>-clearPersistedState
      </programArgs>
      <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts
      </vmArgsMac>
   </launcherArgs>

   <launcher>
      <win useIco="false">
         <bmp/>
      </win>
   </launcher>

   <vm>
   </vm>

   <plugins>
    <!-- YOUR PLUG-INS INCLUDED IN YOUR PRODUCT-->
   </plugins>


<features>
    <!-- YOUR FEATURES INCLUDED IN YOUR PRODUCT-->
    <feature id="org.eclipse.justj.openjdk.hotspot.jre.minimal.feature.group" installMode="root"/>
   </features>

   <configurations>
      <plugin id="org.apache.felix.scr" autoStart="true" startLevel="0" />
      <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="0" />
      <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
      <plugin id="org.eclipse.equinox.event" autoStart="true" startLevel="2" />
      <plugin id="org.eclipse.equinox.simpleconfigurator" autoStart="true" startLevel="1" />
   </configurations>
   <features>

</product>

The master pom should look the same, no additional changes are required.

10. Exercise: Tycho build for SWTBot tests

The following exercise demonstrates how to run SWTBot tests with Tycho. It assumes that you already created some SWTBot tests in a plug-in named com.example.e4.swtbottests.

10.1. Pom file for SWTBot tests

For SWTBot tests the Tycho Surefire plug-in has to be configured, so that the SWTBot test can run properly.

<?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>
    <parent>
        <groupId>com.vogella.tycho</groupId>
        <artifactId>com.vogella.tycho.tests</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>com.vogella.tycho.rcp.it.tests</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>eclipse-test-plugin</packaging>

    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>tycho-surefire-plugin</artifactId>
                <version>${tycho.version}</version>
                <configuration>
                    <useUIHarness>true</useUIHarness>
                    <useUIThread>false</useUIThread>
                    <product>com.vogella.tycho.rcp.product</product>
                    <application>org.eclipse.e4.ui.workbench.swt.E4Application</application>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

10.2. Adding org.eclipse.equinox.event as extra requirement

In most of the cases the org.eclipse.equinox.event plug-in is used in an Eclipse RCP application. Unfortunately it sometimes is not loaded properly for an integration test, even though it is part of the target platform of the product and mentioned in the start level configuration. Due to this it needs to be specified in the configuration of the target-platform-configuration plugin.

<project>

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

            <configuration>
                <!-- This defines the target definition file -->
                <target>
                    <artifact>
                        <groupId>com.vogella.tychoexample</groupId>
                        <artifactId>com.vogella.build.targetdefinition</artifactId>
                        <version>1.0.0-SNAPSHOT</version>
                    </artifact>
                </target>

                <dependency-resolution>(1)
                    <extraRequirements>
                        <requirement>
                            <type>eclipse-plugin</type>
                            <id>org.eclipse.equinox.event</id>
                            <versionRange>0.0.0</versionRange>
                        </requirement>
                    </extraRequirements>
                </dependency-resolution>

                <environments>
                    <environment>
                        <os>linux</os>
                        <ws>gtk</ws>
                        <arch>x86_64</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>
1 Add the org.eclipse.equinox.event plug-in as extra requirement in the dependency resolution.

10.3. Add the SWTBot test to the build

The com.vogella.tycho.rcp.it.tests plug-in has to be added to the pom.xml of the tests folder to take part in the overall build.

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vogella.tycho</groupId>
    <artifactId>com.vogella.tycho.tests</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <parent>
        <groupId>com.vogella.tycho</groupId>
        <artifactId>com.vogella.tycho.root</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <modules>
        <module>com.vogella.tycho.rcp.tests</module>
        <module>com.vogella.tycho.rcp.it.tests</module>
    </modules>
</project>

10.4. Run the build with the tests

Run the build from the main directory. This should work fine.

11. More Tycho settings

11.1. Using root level features

A root level feature is a feature which can be updated or uninstalled independently of the product.

To define that a feature is a root level feature, add installMode="root" behind the feature in the product definition file. You need to use a text editor for this at the moment, the product configuration editor does currently not expose that in its user interface.

11.2. Enable the generation of default pom files for Eclipse components

To enable the automatic determination of build information for your Eclipse components, add a .mvn/extensions.xml descriptor to the root of your directory. This requires at least Apache Maven 3.3 and Maven Tycho 0.24.0, but we recommend to use the latest versions.

The contents of the .mvn/extensions.xml must look like this:

<extensions>
  <extension>
    <groupId>org.eclipse.tycho.extras</groupId>
    <artifactId>tycho-pomless</artifactId>
    <version>4.0.10</version>
  </extension>
</extensions>

The following rules are used for the automatic pom generation. First of all .qualifier from the Eclipse components is automatically mapped to -SNAPSHOT for the Maven build.

Table 1. Pom Properties Mapping
Property Mapping

packaging

eclipse-plugin if MANIFEST.MF is found

eclipse-feature if feature.xml is found

eclipse-test-plugin if Bundle-SymbolicName ends with .tests

groupId

same as in the parent pom

arifactId

eclipse-plugin: Bundle-SymbolicName from MANIFEST.MF

eclipse-feature: feature id from feature.xml

version

Bundle-Version from MANIFEST.MF or

Feature version from feature.xml

11.3. Defining a specialized pom file for an Eclipse component

If you define a pom file for an Eclipse component, you need to specify the packaging attribute in the pom file.

The build requires that the version numbers of each single Maven artifacts and its Eclipse plug-ins are in sync. Sometimes (this is rare these days) developers forget to update the Maven version numbers. In this case the build complains about a version mismatch. Run the following command to correct existing inconsistencies.

mvn -Dtycho.mode=maven org.eclipse.tycho:tycho-versions-plugin:update-pom

This attribute defines what kind of Eclipse component you are building. For example, a plug-in must set this attribute to eclipse-plugin.

Table 2. Package attributes for Eclipse components
Package Attribute Description

eclipse-plugin

Used for plug-ins

eclipse-test-plugin

Used for test plug-ins or fragments

eclipse-feature

Used for features

eclipse-repository

Used for p2 update sites and Eclipse products

eclipse-target-definition

Target definition used for the Tycho build

In addition to packaging attribute, the pom of an Eclipse component must also specify the name and the version of the component. The artifact ID and version in the pom file must match the Bundle-Symbolic-Name and the Bundle-Version from the MANIFEST.MF file. Eclipse components typical use qualifier as a suffix in the Bundle-Version to indicate that this should be replaced by the build system with a build qualifier. Maven uses "SNAPSHOT" for this, but Tycho maps these values correctly. Each module has again a pom.xml configuration file which defines attributes specifically to the corresponding Eclipse component, e.g., the package attribute.

It must also contain a link to the main or the configuration pom so that the build can determine the configuration.

The following listing contains an example pom file for a plug-in.

<project>
    <modelVersion>4.0.0</modelVersion>

    <!-- Link to the parent pom -->
    <parent>
        <artifactId>com.example.todo.build.parent</artifactId>
        <groupId>com.example.e4.rcp</groupId>
        <version>0.1.0-SNAPSHOT</version>
        <relativePath>../com.example.todo.build.parent</relativePath>
    </parent>

    <groupId>com.example.e4.rcp</groupId>
    <artifactId>com.vogella.imageloader.services</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>eclipse-plugin</packaging>
</project>

11.4. Source Encoding

You can set the source code encoding via the project.build.sourceEncoding parameter.

<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

If you do not set this encoding property the maven build throws warnings similar to the following:  [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!

For further information see Maven FAQ for encoding warning (http://maven.apache.org/general.html#encoding-warning).

11.5. Building source features

Tycho allows to generates source features which allows users to browse your code once installed in your IDE.

<!-- enable source feature generation -->
<build>
    <plugins>
      <!-- more entries -->

      <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>
          <execution>
            <id>feature-source</id>
            <goals>
              <goal>feature-source</goal>
            </goals>
            <configuration>
              <excludes>
                <!-- provide plug-ins not containing any source code -->
                <plugin id="com.vogella.tycho.product" />
                <plugin id="com.vogella.tycho.target" />
                <plugin id="com.vogella.tycho.update" />
                <!-- also possible to exclude feature-->
              </excludes>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

You can add the generated source features to your existing updates side. For this, open the category file and add the features and plug-ins to one of your categories with the .sources suffix.

<?xml version="1.0" encoding="UTF-8"?>
<site>
   <feature id="com.vogella.tycho.feature" version="0.0.0">
      <category name="tychoexample"/>
   </feature>
   <feature id="com.vogella.tycho.feature.source" version="0.0.0">
      <category name="tychoexample-source"/>
   </feature>

   <category-def name="tychoexample" label="Tycho example"/>
   <category-def name="tychoexample-source" label="Tycho example source bundles"/>
</site>

11.6. Mirroring a p2 update site with Maven Tycho

Tycho allows to mirror a p2 update site. This reduces the dependency to the remote side as you can use your local copy for building the Eclipse application.

The following is an example for such a mirror task which mirrors two features from the latest Eclipse release

<?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>
    <name>Mirror Update Site</name>

    <prerequisites>
        <maven>3.0</maven>
    </prerequisites>



    <groupId>com.vogella.p2.mirror</groupId>
    <artifactId>mirror</artifactId>
    <version>3.5.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <properties>
        <tycho.version>2.3.0</tycho.version>
        <tycho-extras.version>2.3.0</tycho-extras.version>
    </properties>


    <build>
    <plugins>
        <plugin>
            <groupId>org.eclipse.tycho.extras</groupId>
            <artifactId>tycho-p2-extras-plugin</artifactId>
            <version>${tycho.version}</version>
            <executions>
                <execution>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>mirror</goal>
                    </goals>
                </execution>
            </executions>

            <configuration>
                <source>
                    <!-- source repositories to mirror from -->
                    <repository>
                        <url>https://download.eclipse.org/releases/latest/</url>
                        <layout>p2</layout>
                        <!-- supported layouts are "p2-metadata", "p2-artifacts", and "p2" (for joint repositories; default) -->
                    </repository>

                </source>

                <!-- starting from here all configuration parameters are optional -->
                <!-- they are only shown here with default values for documentation purpose -->

                <!-- List of IUs to mirror. If omitted, allIUs will be mirrored. -->
                <!-- Omitted IU version element means latest version of the IU -->

                <ius>
                   <!--
                    <iu>
                        <query>
                            <expression>id == $0 &amp;&amp; version == $1</expression>
                            <parameters>org.eclipse.platform.sdk,4.19.0.I20210303-1800</parameters>
                        </query>
                    </iu>
                    -->

                    <iu>
                        <id>org.eclipse.equinox.sdk.feature.group</id>
                    </iu>

                    <iu>
                        <id>org.eclipse.e4.rcp.feature.group</id>
                    </iu>
                </ius>


                <!-- The destination directory to mirror to. -->

                <destination>${project.build.directory}/repository</destination>
                <!-- Whether only strict dependencies should be followed. -->
                <!-- "strict" means perfect version match -->

                <followStrictOnly>false</followStrictOnly>
                <!-- Whether or not to follow optional requirements. -->
                <includeOptional>true</includeOptional>
                <!-- Whether or not to follow non-greedy requirements. -->
                <includeNonGreedy>true</includeNonGreedy>

                <!-- Filter properties. E.g. filter only one platform -->

                <filter>
                    <osgi.os>linux</osgi.os>
                    <osgi.ws>gtk</osgi.ws>
                    <osgi.arch>x86_64</osgi.arch>
                </filter>

                <!-- Whether to filter the resulting set of IUs to only -->
                <!-- include the latest version of each IU -->

                <latestVersionOnly>false</latestVersionOnly>
                <!-- don't mirror artifacts, only metadata -->
                <mirrorMetadataOnly>false</mirrorMetadataOnly>

                <!-- whether to compress the content.xml/artifacts.xml -->

                <compress>true</compress>
                <!-- whether to append to the target repository content -->
                <append>true</append>

            </configuration>
        </plugin>
    </plugins>
</build>
</project>

You would execute this task independently of your build and use the newly created local folder in your normal build.

To use your mirror, configure Maven to use it via the settings.xml file in your home folder. Alternatively you can adjust your target definition file to point to the mirror.

<settings>
 <mirrors>
  <mirror>
   <id>Mars_mirror</id>
   <mirrorOf>Mars</mirrorOf>
   <name>Local mirror of Mars repository</name>
   <url>file://home/vogella/Marsclone</url>
   <layout>p2</layout>
   <mirrorOfLayouts>p2</mirrorOfLayouts>
  </mirror>
 </mirrors>
</settings>

11.7. Removing compiler warning messages from the build

You can remove compiler warnings from the Maven build by configuring the tycho-compiler-plugin. This is demonstrated with the following snippet.

<build>
    <plugins>
      <plugin>
        <groupId>org.eclipse.tycho</groupId>
        <artifactId>tycho-compiler-plugin</artifactId>
        <version>${tycho.version}</version>
        <configuration>
          <compilerArgs>
            <arg>-warn:-raw,unchecked</arg>
          </compilerArgs>
        </configuration>
      </plugin>
    </plugins>
 </build>

11.8. Using the last Git commit as build qualifier special build settings

You can configure the tycho-packaging-plugin to use the last Git commit as build qualifier instead of the build time. The following pom file shows how to do this. This allows building reproducible results if no change happened in the Git repository. This only works if the project is in a Git repository.

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.vogella.tycho.jgit.plugin</groupId>
 <artifactId>com.vogella.tycho.jgit.plugin</artifactId>
 <version>1.0.0-SNAPSHOT</version>

 <packaging>eclipse-plugin</packaging>

 <properties>
  <tycho.version>1.2.0</tycho.version>
  <tycho-extras.version>1.2.0</tycho-extras.version>
  <repo.url>https://download.eclipse.org/releases/2018-12</repo.url>
 </properties>

 <repositories>
  <repository>
   <id>eclipse-repo</id>
   <url>${repo.url}</url>
   <layout>p2</layout>
  </repository>

 </repositories>

 <build>
  <plugins>
   <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>
   </plugin>
  </plugins>
  <pluginManagement>
   <plugins>
    <plugin>
     <groupId>org.eclipse.tycho</groupId>
     <artifactId>tycho-packaging-plugin</artifactId>
     <version>${tycho.version}</version>
     <dependencies>
      <dependency>
       <groupId>org.eclipse.tycho.extras</groupId>
       <artifactId>tycho-buildtimestamp-jgit</artifactId>
       <version>${tycho-extras.version}</version>
      </dependency>
     </dependencies>
     <configuration>
      <timestampProvider>jgit</timestampProvider>
      <jgit.ignore>
       pom.xml
      </jgit.ignore>
      <jgit.dirtyWorkingTree>ignore</jgit.dirtyWorkingTree>
     </configuration>
    </plugin>
   </plugins>
  </pluginManagement>
 </build>

</project>

11.9. Generating and updating POM files for Eclipse components

11.9.1. Generating POM files

Tycho supports the generation of POM files via its tycho-pomgenerator-plugin:generate-poms goal. This goals search from the existing directory for Eclipse components which do not yet have a pom files and generates them.

You can use the following command to generate the pom files. The -DgroupId allows you to specify the group ID for the pom files.

# group ID is set to com.vogella.tychoexample
mvn org.eclipse.tycho:tycho-pomgenerator-plugin:generate-poms \
    -DgroupId=com.vogella.tychoexample

This command generates pom files for all Eclipse components below the current directory and a parent pom in the current directory which includes all Eclipse components as modules.

For identifying test bundles the generator assumes that those bundles have .test as suffix.  By using -DtestSuffix=.mytestBundleSuffix as additional parameter you can override this default.

If you try to execute this generated pom file, the build fail because you have not yet configured your dependencies.

If you want to include Eclipse components which are not in the current directory you can point Tycho to these directories via the -DextraDirs parameter and define from which directory it should start.

mvn org.eclipse.tycho:tycho-pomgenerator-plugin:generate-poms \
 -DgroupId=com.vogella.tycho.build -DbaseDir=features -DextraDirs="../../another_plugin_dir

11.10. Update the Maven artifact versiond in the pom files based on the MANIFEST.MF

If you are using individual pom files, you can update their numbers based on the versions in the `MANIFEST.MF`file. To do this, run the following commands.

# update pom files
mvn org.eclipse.tycho:tycho-versions-plugin:update-pom
    -Dtycho.mode=maven

11.11. Setting version numbers

After releasing an application or several plug-ins, the version number should be increased. If you do not use pomless builds, there are two locations where version numbers are defined. On the one hand the pom.xml file and on the other hand the MANIFEST.MF file.

This can be done easily by using the Tycho Versions Plugin.

# setting the version in pom.xml and MANIFEST.MF files
mvn org.eclipse.tycho:tycho-versions-plugin:set-version -DnewVersion=X.Y.Z
    -Dtycho.mode=maven

Eclipse usually uses semantic versioning for plug-ins, so a version number like {major}.{minor}.{patch} is used. See Semantic versioning for more information.

The tycho.mode=maven property disables the target platform calculation and dependency resolution, which is usually done by Tycho. This results in better performance, since those features are not necessary for updating the version.

More information about versioning with Tycho can be found in the Tycho version wiki.

11.12. Unpack built plug-ins

In case a plug-in contains native code, e.g., dll files or others, which do not work from inside a JAR file, the plug-in itself should be unpacked.

To archive that the plug-in’s MANIFEST.MF must consist of the following property.

Eclipse-BundleShape: dir

With this property in the MANIFEST.MF file the plug-in won’t be packed as JAR file, but just be available as directory in the plugins directory of a product.

11.13. Signing plug-ins

If the user installs plug-ins which are not signed, the user received a warning that the plug-in is not signed.

The Tycho build system allows to sign plug-ins and executables. You can purchase a certificate from a certification authority or create your own signature and use this for signing. If you use a custom generated certificate the user receives a warning that the certificate is not official.

For testing a self-generated certificate is sufficient. You can generate such a certificate on the command line with the keytool from the Java Development Kit. This requires that the corresponding directory is in your current execution path.

# the following goes in one line

keytool -genkey -alias   -keystore eclipse-signing.keystore \
-storepass PASSWORD -validity 4360

# this command triggers a set of questions

What is your first and last name?
  [Unknown]:  Jim Knopf
What is the name of your organizational unit?
  [Unknown]:  IT
What is the name of your organization?
  [Unknown]:  test Company
What is the name of your City or Locality?
  [Unknown]:  Hamburg
What is the name of your State or Province?
  [Unknown]:  Germany
What is the two-letter country code for this unit?
  [Unknown]:  DE
Is CN=Jim Knopf, OU=IT, O=test Company, L=Hamburg, ST=Germany, C=DE correct?
  [no]:  y

Enter key password for <selfsigned>
    (RETURN if same as keystore password):

To sign the plug-ins add the configuration for the maven-jarsigner-plugin

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jarsigner-plugin</artifactId>
    <version>1.2</version>
        <configuration>
            <keystore>file:///home/vogella/eclipse-signing.keystore</keystore>
                <storepass>voclipse</storepass>
                    <alias>selfsigned</alias>
                      <keypass>PASSWORD</keypass>
        </configuration>
        <executions>
            <execution>
                <id>sign</id>
                <goals>
                    <goal>sign</goal>
                </goals>
            </execution>
         </executions>
</plugin>

11.14. Building platform specific fragments or bundles

As of Bug 567782 you can use pomless builds for platform specific fragments. It is also possible to specify it in the pom of the element in case you do not use pomless builds.

More infos on pom for platform specific artifacts

When building a fragment for a certain operating system, you can override the <environments> configuration from your parent POM. This requires a pom file in fragment or bundle.

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vogella.tycho</groupId>
    <artifactId>com.vogella.tycho.example.linux.x86_64</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <parent>
        <groupId>com.vogella.tycho</groupId>
        <artifactId>org.eclipse.tycho.parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <build>
        <plugins>
            <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_64</arch>
                        </environment>
                    </environments>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

The following entries are possible:

  • Linux

<configuration>
                    <environments>
                        <environment>
                            <os>linux</os>
                            <ws>gtk</ws>
                            <arch>x86_64</arch>
                        </environment>
                    </environments>
                </configuration>
  • Mac

<configuration>
                    <environments>
                        <environment>
                            <os>macosx</os>
                            <ws>cocoa</ws>
                            <arch>x86_64</arch>
                        </environment>
                    </environments>
                </configuration>
  • Windows

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

11.15. Shell script for generating pom files

Sometimes it is useful to generate the pom files automatically. Here is an example shell script which creates a module entry for each directory in the current directory.

#!/bin/bash

cd $(dirname $0)

BASEDIR=`basename pwd`
echo "Creating pom.xml for $BASEDIR"

cat > pom.xml <<- EOM
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vogella.tycho</groupId>
    <artifactId>$BASEDIR</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <parent>
        <groupId>com.vogella.tycho</groupId>
        <artifactId>com.vogella.tycho.parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <modules>
EOM

modules=`ls -l|  grep '^d'  | awk '{ print "<module>"$9"</module>" }'`

echo "$modules" >> pom.xml


cat >> pom.xml <<- EOM
    </modules>
</project>
EOM

cat pom.xml

11.16. Building native components

Building native components, for example based on C or C++ code, is typically done via antrunner calling the native build system like make.

See the following commit for an example:

12. Deploying to a file based Maven repository

You can deploy directly the build result to a file based Maven repository (which could be used in your target platform as reference).

mvn deploy -DaltDeploymentRepository=snapshot-repo::default::file:/path-to-your-repo/test-repo

13. Automatic deployment of a p2 update site with Maven

You can use the Maven Wagon plug-in to deploy your artifacts, e.g., to an ftp server.

To define the credentials to login to the server you can add an entry for the user credentials to your local ~/m2/settings.xml file.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository/>
  <interactiveMode/>
  <usePluginRegistry/>
  <offline/>
  <pluginGroups/>
  <servers>
    <server>
      <id>ftp-repository</id>
      <username>youruser</username>
      <password>yourpassword</password>
    </server>
  </servers>
  <mirrors/>
  <proxies/>
  <profiles/>
  <activeProfiles/>
</settings>

You can then configure your pom file to use the wagon plug-in of Maven.

<project>
  <distributionManagement>
    <repository>
      <id>ftp-repository</id>
      <url>ftp://repository.mycompany.com/repository</url>
    </repository>
  </distributionManagement>

  <build>
    <extensions>
      <!-- Enabling the use of FTP -->
      <extension>
        <groupId>org.apache.maven.wagon</groupId>
         <artifactId>wagon-ftp</artifactId>
         <version>1.0-beta-6</version>
      </extension>
    </extensions>
  </build>
</project>

The following command will now deploy your artifacts to your ftp site.

mvn deploy

If you only want to upload your p2 update site, you can configure the org.apache.maven.wagon plug-in.

<project>
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <relativePath>../com.vogella.tycho.master/pom.xml</relativePath>
    <groupId>com.vogella</groupId>
    <artifactId>parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>

  <artifactId>com.vogella.tycho.p2updatesite</artifactId>
  <packaging>eclipse-repository</packaging>

  <name>Tycho Test Build</name>

 <build>
  <extensions>
   <!-- Enabling the use of FTP -->
   <extension>
    <groupId>org.apache.maven.wagon</groupId>
    <artifactId>wagon-ftp</artifactId>
    <version>1.0-beta-6</version>
   </extension>
  </extensions>
 </build>

 <profiles>
  <!-- This profile is used to upload the repo -->
  <profile>
   <id>uploadRepo</id>
   <properties>
    <!-- Properties relative to the 
    distant host where to upload the repo -->
    <ftp.url>ftp://your.server.com</ftp.url>
    <ftp.toDir>/yourpath</ftp.toDir>
    <!-- Relative path to the repo being uploaded -->
    <repo.path>${project.build.directory}/repository/</repo.path>
   </properties>

   <build>
    <plugins>
     <!-- Upload the repo to the server -->
     <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>wagon-maven-plugin</artifactId>
      <version>1.0-beta-4</version>
      <executions>
       <execution>
        <id>upload-repo</id>
        <phase>install</phase>
        <goals>
         <goal>upload</goal>
        </goals>
        <configuration>
         <fromDir>${repo.path}</fromDir>
         <includes>**</includes>
         <toDir>${ftp.toDir}</toDir>
         <url>${ftp.url}</url>
         <serverId>p2Repo</serverId>
         <!-- Points to your settings.xml 
         where the connection settings are 
          stored as shown below -->
         <!-- <server> -->
         <!-- <id>p2Repo</id> -->
         <!-- <username>username</username> -->
         <!-- <password>password</password> -->
         <!-- </server> -->
        </configuration>
       </execution>
      </executions>
     </plugin>
    </plugins>
   </build>
  </profile>
 </profiles>

</project>

You can now upload your p2 update site with the following command.

mvn install -P uploadRepo

14. Deploy p2 updatesite to Nexus

14.1. Setup Distribution Management

When a Nexus is installed on localhost, the following Distribution Management will likely be used:

<project>
 <distributionManagement>
  <repository>
   <id>nexus</id>
   <name>Internal Releases</name>
   <url>http://localhost:8081/nexus/content/repositories/releases/</url>
  </repository>
  <snapshotRepository>
   <id>nexus</id>
   <name>Internal Snapshots</name>
   <url>http://localhost:8081/nexus/content/repositories/snapshots/
   </url>
  </snapshotRepository>
 </distributionManagement>
</project>

14.2. Credentials for the Nexus repository manager

To define the credentials to login to the Nexus Server you can add an entry for the user credentials to your local ~/m2/settings.xml file.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository/>
  <interactiveMode/>
  <usePluginRegistry/>
  <offline/>
  <pluginGroups/>
  <servers>
    <server>
      <id>nexus</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
  </servers>
  <mirrors/>
  <proxies/>
  <profiles/>
  <activeProfiles/>
</settings>

The id in the setting file must fit to the id of the repository in the Distribution Management. Both are named nexus in this example.

14.3. Only deploy the p2 update site

When using mvn clean deploy usually all build artifacts of all modules are deployed to the Nexus. In the context of Tycho build, you usually want to deploy only the p2 update site, since its content is used by the target definitions or for application updates.

In order to archive this the deploy phase can be skipped by using maven.deploy.skip property in the root parent pom.

<properties>
    <tycho.version>1.2.0</tycho.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- Skip the deployment here, submodules can override this property -->
    <maven.deploy.skip>true</maven.deploy.skip>
</properties>

This property will be derived by all child modules so that they are not deployed unless a child module overrides this property. And this is supposed to be done in the p2 update site module.

So this property should be false for all p2 update site modules.

<properties>
    <!-- Do not skip the deployment here since we want this module to be deployed -->
    <maven.deploy.skip>false</maven.deploy.skip>
</properties>

15. Appendix: Tycho snippets

This section lists various snippets which can be used to modify your Tycho build.

15.1. Using p2 update sites in the target file

Install of a target file you can also use p2 update sites in your build configuration. Prefer the usage of target platform files to ensure you are developing against the same set of plug-ins as your command line build.

 <properties>
  <!-- more properties -->
  <eclipse-repo.url>https://download.eclipse.org/releases/latest</eclipse-repo.url>
 </properties>


 <repositories>
  <repository>
   <id>eclipse-release</id>
   <url>${eclipse-repo.url}</url>
   <layout>p2</layout>
  </repository>
 </repositories>

 <!-- the rest of the configuration... -->

If you want to add the JRE to your build using update sites:

 <repository>
      <id>justj</id>
      <url>https://download.eclipse.org/justj/jres/17/updates/release/latest/</url>
      <layout>p2</layout>
 </repository>

15.2. Pom files for target definition files

Sometimes pomless build fails or your want to configure something directly. Therefore, this section lists individual poms.

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.vogella.tycho</groupId>
        <artifactId>releng</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <groupId>com.vogella.tycho</groupId>
    <artifactId>target-platform</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>eclipse-target-definition</packaging>

</project>

15.3. Using additional p2 update sites in your build

For example the following snippet would make the components from the last release available for your build.

 <repositories>
    <repository>
      <id>eclipse-latest</id>
      <url>https://download.eclipse.org/releases/latest</url>
      <layout>p2</layout>
    </repository>
  </repositories>

15.4. Setting the Java version

The target configuration allows to set the Java version. This is sometimes required, for example sometimes Tycho calculates the wrong Java version for a feature.

For example, the following ensures that you are using Java 21 for your build.

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

 <configuration>
 <executionEnvironment>JavaSE-21</executionEnvironment>
   <!-- more settings -->
 </configuration>
</plugin>

15.5. Debugging a Tycho build

Use

 mvnDebug clean verify

to allow to connect to a Tycho build, via a remote debug session.

15.6. Show the generated pom files

To see the generated pom files, use mvn clean verify -Dpolyglot.dump.pom=pom-for-review.xml, the pom-for-review.xml was used to avoid that the generated pom files are used by the build.

15.7. Configuring SonarCube

Add to your main pom file your SonarCube configuration.

<properties>
    <!-- SonarQube properties -->
    <sonar.projectKey>yourProjectKey</sonar.projectKey>
    <sonar.host.url>http://yourSonarServer:9000</sonar.host.url>
    <!-- Optional: if authentication is required -->
    <sonar.login>yourAuthenticationToken</sonar.login>
    <sonar.sources>src</sonar.sources>
</properties>

Run mvn clean verify sonar:sonar

15.8. Adding modules based on the profile

The listing of modules is additive, e.g., you can define profiles with additional modules and in this case, the modules defined in the profile will be added to the build if the profile is active.

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vogella.tycho</groupId>
    <artifactId>releng</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <tycho.version>4.0.5</tycho.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>


    <profiles>
        <profile>
            <id>deploy</id>
            <modules>
                <module>updatesite</module>
            </modules>
        </profile>
        <profile>
            <id>exclude-deploy</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
    </profile>
</profiles>

    <build>

        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.eclipse.tycho</groupId>
                    <artifactId>tycho-p2-director-plugin</artifactId>
                    <version>${tycho.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>tycho-maven-plugin</artifactId>
                <version>${tycho.version}</version>
                <extensions>true</extensions>
            </plugin>
            <!--Enable
            the replacement of the SNAPSHOT version in the final product configuration-->
            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>tycho-packaging-plugin</artifactId>
                <version>${tycho.version}</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <id>package-feature</id>
                        <configuration>
                            <finalName>${project.artifactId}_${unqualifiedVersion}.${buildQualifier}</finalName>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>target-platform-configuration</artifactId>
                <version>${tycho.version}</version>
                <configuration>
                    <target>
                        <file>../target-platform/target-platform.target</file>
                    </target>
                    <resolveWithExecutionEnvironmentConstraints>false</resolveWithExecutionEnvironmentConstraints>

                    <environments>
                        <environment>
                            <os>linux</os>
                            <ws>gtk</ws>
                            <arch>x86_64</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>


    <modules>
        <module>com.example.e4.rcp</module>
        <module>com.example.e4.feature</module>
        <module>com.example.e4.product</module>
        <!--
    <module>com.example.e4.swtbottests</module>
-->
        <module>com.vogella.swt.widgets</module>
        <module>com.vogella.tasks.ui</module>
        <module>com.example.e4.renderer.swt</module>
        <module>com.vogella.tasks.feature</module>
        <module>com.vogella.tasks.product</module>
        <module>com.vogella.tasks.model</module>
        <module>com.vogella.tasks.services</module>
        <!--
    <module>com.vogella.tasks.services.tests</module>
    -->
        <module>com.vogella.service.imageloader</module>
        <module>com.vogella.tasks.events</module>
        <module>com.vogella.contribute.parts</module>
        <module>com.vogella.tasks.ui.contribute</module>
        <module>com.vogella.tasks.update</module>
        <module>com.vogella.eclipse.css</module>
        <module>com.vogella.osgi.taskconsumer</module>

    </modules>
</project>

16. Eclipse Tycho resources