blob: 655c05b3068b166c4f4897646aa3d9871d2f91d7 [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2015 Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eric Poirier (Eclipse Foundation) - Initial implementation
*******************************************************************************/
?>
<h1 class="article-title"><?php echo $pageTitle; ?></h1>
<p>
Writing code is more effective if it can be built. The goal of the
Eclipse CBI initiative is to focus on a set of tools and
technologies that make the build <b>easy to perform</b>, <b>easy to
test</b>, and <b>easy to repeat</b>.
</p>
<p>The Eclipse CBI stack features Git (the SCM), Hudson (the CI
server), Nexus (Maven repository), Tycho and p2. While CBI at
Eclipse is not a new initiative (early work dates back to 2006),
recent technologies such as Tycho have greatly facilitated the
effort.</p>
<p>In this article, we'll explore the tools in the CBI stack as we
outline the steps required to migrate a typical project from PDE
build to CBI.</p>
<h3>Before you Begin</h3>
<p>You will need the following tools to begin exploring the CBI:</p>
<ul>
<li>Git (http://git-scm.com/downloads)</li>
<li>Maven (http://maven.apache.org/download.cgi)</li>
<li>Tycho (Maven will install Tycho automatically)</li>
</ul>
<h3>The Slideshow Examples Project</h3>
<p>We'll start with a simple project, Slideshow. It is a project in
the Examples repository, which can be found here:</p>
<p>
<a target="_blank"
href="http://github.com/zxiiro/org.eclipse.examples.slideshow">http://github.com/zxiiro/org.eclipse.examples.slideshow</a>
</p>
<p>Clone the repository:</p>
<pre class=“prettyprint”>
git clone https://github.com/zxiiro/org.eclipse.examples.slideshow.git
</pre>
<br />
<h3>Tycho and Maven</h3>
<p>Tycho is a Maven extension for building Eclipse artifacts. Maven
uses pom.xml files as metadata providing Maven with the information
it needs in order to build a project. Every bundle / feature /
product / etc... in your project will require its own separate
pom.xml file.</p>
<p>Tycho has a build goal (generate-poms) which will automatically
generate initial pom.xml files for us:</p>
<pre class=“prettyprint”>
mvn org.eclipse.tycho:tycho-pomgenerator-plugin:generate-poms
-DgroupId=org.eclipse.examples.slideshow
</pre>
<br />
<p>
The only parameter is the <b>-DgroupId</b> which tells Tycho what to
fill for the “GroupID” field in Maven. This is one of the 3
parameters needed by Maven to determine the coordinates for your
artifacts via the Maven GAV which we will discuss in more detail
later. Typically you will want to enter your project or subproject's
Eclipse Group here, in this case <b>org.eclipse.examples.slideshow</b>.
</p>
<p>
Note: Tycho automatic pom generation only searches 1 level deep. So
you might have to run this multiple times if your project's
structured with multiple sub-directories. Please see: <a
href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=409871">https://bugs.eclipse.org/bugs/show_bug.cgi?id=409871</a>
<p>Once mvn completes you should now have pom.xml files generated for
each of your bundles as well as a pom.xml in your root directory
that lists all your sub-directories it created pom.xml files for as
“&lt;modules&gt;”.</p>
<p>
You can try to build your project now using the command: <b>mvn
clean verify</b>
</p>
<p>This should fail and if you scroll through your logs you should see
something similar to this:</p>
<pre class=“prettyprint”>
[ERROR] Cannot resolve project dependencies:
[ERROR] Software being installed:
org.eclipse.examples.slideshow.feature.feature.group 0.2.0.qualifier
[ERROR] Missing requirement:
org.eclipse.examples.slideshow.feature.feature.group 0.2.0.qualifier requires
'org.eclipse.platform.feature.group [4.2.1,4.2.2)'
but it could not be found
</pre>
<br />
<p>This is expected since we have not yet told Tycho where to get
dependencies for your project.</p>
<h3>Maven Parent Pom</h3>
<p>Before we do anything let's take a look at what was generated for
us. Tycho should have generated a pom.xml in your root directory
which will be the parent pom for all of your modules. A parent
pom.xml usually provides all the build details in your project which
is then inherited by the modules that declare it as parent. This is
where you will set all the parameters and build details which are
globally used to build your project.</p>
<p>Maven also allows chaining parent poms as well, so a parent pom can
itself have its own parent pom from which it inherits some
configuration. Having multiple parents can be useful in large
projects where multiple repositories each require their own specific
settings. By defining their own parent they could inherit
configuration from the global parent and fine tune any settings
specific to their sub-project.</p>
<p>In the root directory your root pom.xml should look something like
this:</p>
<pre class=“prettyprint”>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;pom&lt;/packaging&gt;
&lt;modules>
&lt;module&gt;org.eclipse.examples.slideshow.core&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.feature&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.jdt&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.jdt.tests&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.runner&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.runner.tests&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.site&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.text&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.text.tests&lt;/module&gt;
&lt;module&gt;org.eclipse.examples.slideshow.ui&lt;/module&gt;
&lt;/modules&gt;
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId>org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId>tycho-maven-plugin&lt;/artifactId&gt;
&lt;version>0.18.1&lt;/version&gt;
&lt;extensions>true&lt;/extensions&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
&lt;/project&gt;
</pre>
<br />
<p>There are three important details here that Tycho was able to
generate automatically for us. The first section is the Maven
“Group, Artifact and Version”, or GAV. This is how Maven determines
an artifact's coordinates:</p>
<pre class=“prettyprint”>
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;pom&lt;/packaging&gt;
</pre>
<br />
<p>There is an additional declaration, &lt;packaging&gt;, which is
metadata to let Maven know what to do with the current pom.xml. In
this case the root pom is just Maven metadata and is not actually
building anything so the packaging type is just “pom”.</p>
<p>The next section, &lt;modules&gt;, tells Maven which directories
have pom.xml files which need to be built. This is where you will
list all of the artifacts to be built. In some larger projects some
modules defined here might list even more modules that need to be
built.</p>
<p>Finally the last section, &lt;build&gt;, defines allows you to
define any plugins for which you need the artifacts in your project.</p>
<pre class=“prettyprint”>
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;tycho-maven-plugin&lt;/artifactId&gt;
&lt;version&gt;0.18.1&lt;/version&gt;
&lt;extensions&gt;true&lt;/extensions&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
</pre>
<br />
<p>You will want to list Maven plugins that are globally used here as
they will be inherited to the specific modules when Maven determines
what plugins should be used to build your bundles. If only a single
bundle needs a specific Maven plugin you should define it in the
specific bundle's pom.xml file. So far we only have the
tycho-maven-plugin defined which is necessary to build Eclipse
projects. This plugin is what enables Maven to understand package
types such as eclipse-plugin, eclipse-feature, eclipse-repository,
etc...</p>
<h3>Packaging type eclipse-plugin</h3>
<p>Next let's take a look at an eclipse-plugin pom.xml that Tycho
generated for us. Open up
org.eclipse.examples.slideshow.core/pom.xml. You should see
something similar to this:</p>
<pre class=“prettyprint”>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;/parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow.core&lt;/artifactId&gt;
&lt;version&gt;0.2.0-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;eclipse-plugin&lt;/packaging&gt;
&lt;/project&gt;
</pre>
<br />
<p>This time we are seeing 2 GAVs. Once between &lt;parent&gt; and
again after the parent tags. The GAV defined between the
&lt;parent&gt; tags tell Maven where to find the parent of this
pom.xml in which it will inherit any configuration from. In this
case we are inheriting the tycho-maven-plugin settings from the
parent pom.xml if you recall from the earlier example.</p>
<p>In this example the Artifact ID and Version is derived from the
MANIFEST.MF file for this Eclipse bundle and the Group ID was what
we filled in by the parameter we passed to the pom-generator. Tycho
requires the Artifact ID and Version to match exactly what's in the
MANIFEST.MF otherwise building will fail.</p>
<p>Finally there is the new packaging type “eclipse-plugin” which is a
type that Tycho provides allowing us to build Eclipse plugins.</p>
<h3>Packaging type eclipse-test-plugin</h3>
<p>Next let's take a look at a eclipse test plugin. The file
org.eclipse.examples.slideshow.jdt.tests/pom.xml should look similar
to this:</p>
<pre class=“prettyprint”>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;/parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow.jdt.tests&lt;/artifactId&gt;
&lt;version&gt;0.2.0-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;eclipse-test-plugin&lt;/packaging&gt;
&lt;/project&gt;
</pre>
<br />
<p>
The only difference between this and the previous plugin is the
packaging type is now “eclipse-test-plugin”. This is another
packaging type Tycho provides for building test bundles. By default
it will try to detect your unit tests and run them during the build
by launching the <b>tycho-surefire-plugin</b>. This happens
automatically and you do not need to configure the <b>tycho-surefire-plugin</b>
unless you have additional configuration you require.
</p>
<p>This packaging type also uses your bundle's MANIFEST.MF file to
fill out the Artifact ID and Version. Again these values must be
identical to what's found in the MANIFEST.MF or Tycho will throw an
error when you run a build.</p>
<h3>Packaging type eclipse-feature</h3>
<p>Next let's take a look at an eclipse-feature. If you open
org.eclipse.examples.slideshow.feature/pom.xml you should see a
feature similar to this:</p>
<pre class=“prettyprint”>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;/parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow.feature&lt;/artifactId&gt;
&lt;version&gt;0.2.0-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;eclipse-feature&lt;/packaging&gt;
&lt;/project&gt;
</pre>
<br />
<p>Once again the only difference we see here the packaging type is
eclipse-feature which is another type provided by Tycho. Unlike
eclipse-plugin and eclipse-test-plugin however, the eclipse-feature
uses the file “feature.xml” to get any required metadata for the
build. Like the other types the Artifact ID and Version must match
what is defined in the feature.xml in this case.</p>
<h3>Packaging type eclipse-repository</h3>
<p>Finally there is one more packaging type that Tycho defined for us.
The file org.eclipse.examples.slideshow.site/pom.xml should look
like this:</p>
<pre class=“prettyprint”>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;/parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow.site&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;eclipse-update-site&lt;/packaging&gt;
&lt;/project&gt;
</pre>
<br />
<p>Again, the packaging type is the only thing that's different. In
this case Tycho generated an eclipse-update-site for us. This
packaging type is actually deprecated in favour of a new type:
eclipse-repository. So before we move on let's change it:</p>
<pre class=“prettyprint”>
&lt;packaging&gt;eclipse-repository&lt;/packaging&gt;
</pre>
<br />
<p>
This packaging type uses the category.xml file to build an eclipse
repository for you which is usually a p2 repository. With additional
configuration you can also have Tycho produce an eclipse product for
you too via a product file instead of a category.xml. More details
on this can be found on the wiki page here: <a
href="http://wiki.eclipse.org/Tycho/Packaging_Types#eclipse-repository">http://wiki.eclipse.org/Tycho/Packaging_Types#eclipse-repository</a>
</p>
<h3>Defining dependency repositories</h3>
<p>That was a quick overview of what the Tycho pom generator created
for us. Before we can actually perform a build there is additional
configuration we need to do. Our earlier error was due to missing
dependencies that Maven/Tycho was not able to calculate. By default
Maven looks for dependencies in Maven Central, which is a central
repository containing (in theory) all the Java artifacts you will
need to build anything. In practice though not all projects push
their artifacts there, so you will most likely need to define
additional repositories of where Maven should look.</p>
<p>In the Eclipse world most software repositories come in the form of
p2 repositories hosted on eclipse.org. Maven by itself does not work
with p2 repositories but Tycho adds this additional functionality to
Maven. Add the following section below to your root pom.xml. I added
it just before the “&lt;modules&gt;” section in my root pom.xml.</p>
<pre class="prettyprint">
&lt;repositories&gt;
&lt;repository&gt;
&lt;id&gt;eclipse-juno&lt;/id&gt;
&lt;url&gt;http://download.eclipse.org/releases/juno/&lt;/url&gt;
&lt;layout&gt;p2&lt;/layout&gt;
&lt;/repository&gt;
&lt;/repositories&gt;
</pre>
<br />
<p>For the purpose of this example we are using the Eclipse release
train p2 repository to retrieve all the dependencies required by our
project (the Slideshow project requires bundles from Eclipse Juno).
In a real project you will probably want to narrow down the specific
repositories that your project needs to build rather than including
the entire release train.</p>
<p>
With our repository now configured let's try to build a plugin. With
Maven/Tycho you do not need to build your entire project all at
once. If your plugin does not have any dependencies on other plugins
in your project you can actually build your plugin by itself. For a
quick test let's try doing that now by navigating to the <b>org.eclipse.examples.slideshow.core</b>
directory and running the build command:
</p>
<pre class=“prettyprint”>
mvn clean verify
</pre>
<br />
<p>
You should successfully build this eclipse-plugin and its output
will be available in the new “<b>target/</b>” sub-directory. You
should now see a file with the name <b>org.eclipse.examples.slideshow.core-0.2.0-SNAPSHOT.jar.</b>
This is the build output for our plugin. Don't mind the -SNAPSHOT in
the name for now. When an eclipse-repository is built later it will
replace this name with the build time stamp as you normally see in
eclipse bundles.
</p>
<p>Now that we've proven the new repository is working for finding
dependencies, let's try to build the whole project. Navigate back to
the root of the project and run the build command:</p>
<pre class=“prettyprint”>
mvn clean verify
</pre>
<br />
<p>This time a new error appears:</p>
<pre class=“prettyprint”>
[ERROR] Internal error: java.lang.RuntimeException: org.osgi.framework.BundleException:
Bundle org.eclipse.examples.slideshow.jdt cannot be resolved
[ERROR] Resolution errors:
[ERROR] Bundle org.eclipse.examples.slideshow.jdt - Missing Constraint:
Import-Package: org.eclipse.jface.text; version="0.0.0"
</pre>
<br />
<p>
Tycho is unable to resolve dependency <b>org.eclipse.jface.text</b>
from the bundle <b>org.eclipse.examples.slideshow.jdt</b> because
this bundle is a split package provided by two bundles
(org.eclipse.jface.text and org.eclipse.text). An explaination of
this issue can be found on the tycho-user mailing list here: <a
href="http://dev.eclipse.org/mhonarc/lists/cbi-dev/msg00335.html">http://dev.eclipse.org/mhonarc/lists/cbi-dev/msg00335.html</a>
</p>
<p>
We can help Tycho resolve this bundle by adding some additional
configuration. If you recall earlier, bundle-specific configuration
should go into the specific pom.xml for the bundle so that other
bundles do not inherit it. In this case the bundle that needs
additional configuration is the <b>org.eclipse.examples.slideshow.jdt</b>,
so open up the pom.xml for that bundle.
</p>
<p>
We can use the <b>tycho-platform-configuration</b> plugin to define
a build-time dependency for <b>org.eclipse.jface.text</b>. This will
help Tycho resolve this bundle during the build. Modify your pom.xml
to look similar to this (see highlighted area):
<pre class=“prettyprint”>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;/parent&gt;
&lt;groupId&gt;org.eclipse.examples.slideshow&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.examples.slideshow.jdt&lt;/artifactId&gt;
&lt;version&gt;0.2.0-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;eclipse-plugin&lt;/packaging&gt;
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;target-platform-configuration&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;dependency-resolution&gt;
&lt;extraRequirements&gt;
&lt;requirement&gt;
&lt;type&gt;eclipse-plugin&lt;/type&gt;
&lt;id&gt;org.eclipse.jface.text&lt;/id&gt;
&lt;versionRange&gt;0.0.0&lt;/versionRange&gt;
&lt;/requirement&gt;
&lt;/extraRequirements&gt;
&lt;/dependency-resolution&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
&lt;/project&gt;
</pre>
<br />
<p>
This adds a new &lt;build&gt; section to the pom.xml containing
plugin configuration for the <b>tycho-platform-configuration</b>
plugin. With this setting we are telling Tycho that we need it to
resolve an eclipse-plugin with the id org.eclipse.jface.text and
accept any version (0.0.0). Typically, defining 0.0.0 for the
version will retrieve the latest version available from whatever
repository I can find it in.
</p>
<p>It is possible to restrict the version with a range as well. For
example:</p>
<pre class=“prettyprint”>
&lt;versionRange&gt;[2.9,3.0)&lt;/versionRange&gt;
</pre>
<br />
<p>This will restrict the version to be any 2.9 version or greater but
less than 3.0. The the square braces [] is an inclusive denotation
and the parenthesis () denote an exclusive number.</p>
<p>Once you're ready, run the build from the root of the project
again. You should once again see a similar error:</p>
<pre class=“prettyprint”>
[ERROR] Internal error: java.lang.RuntimeException: org.osgi.framework.BundleException:
Bundle org.eclipse.examples.slideshow.runner cannot be resolved
[ERROR] Resolution errors:
[ERROR] Bundle org.eclipse.examples.slideshow.runner -
Missing Constraint: Import-Package: org.eclipse.core.runtime; version="0.0.0"
</pre>
<br />
<p>
This time the dependency org.eclipse.core.runtime is missing when
trying to build <b>org.eclipse.examples.slideshow.runner</b>. You
will need to modify the pom.xml for <b>org.eclipse.examples.slideshow.runner</b>
similar to what was done above. Fix this and run the build again.
</p>
<pre class=“prettyprint”>
mvn clean verify
</pre>
<br />
<p>This time a new error appears:</p>
<pre class=“prettyprint”>
[ERROR] Failed to execute goal
org.eclipse.tycho:tycho-packaging-plugin:0.18.1:package-plugin
(default-package-plugin) on project org.eclipse.examples.slideshow.jdt:
Error assembling JAR:
/buildroot/org.eclipse.examples.slideshow/org.
eclipse.examples.slideshow.jdt/build.properties:
bin.includes value(s) [plugin.xml] do not match any files. -> [Help 1]
</pre>
<br />
<p>
In some cases Tycho helps us find issues with our build. In this
case the build.properties for org.eclipse.examples.slideshow.jdt
wants to include a file “plugin.xml” that does not exist. Either we
need to create this file or remove it from the build.properties. In
this example we'll just remove it. Open <b>org.eclipse.examples.slideshow.jdt/build.properties</b>
and remove the “plugin.xml” from bin.includes.
</p>
<p>Once that's done run the build once more:</p>
<pre class=“prettyprint”>
mvn clean verify
</pre>
<br />
<p>We will now get a new error:</p>
<pre class=“prettyprint”>
[ERROR] Failed to execute goal
org.eclipse.tycho:tycho-packaging-plugin:0.18.1:package-feature
(default-package-feature) on project org.eclipse.examples.slideshow.feature:
Error creating feature package: license feature must include build.properties
file -> [Help 1]
</pre>
<br />
<p>This is due to the Juno version of org.eclipse.license missinging a
build.properties. Tycho requires this file in order to determine
which license files need to be included in your feature.</p>
<p>
Since we have no control over this, lets remove the license
requirement for now. Modify <b>org.eclipse.examples.slideshow.feature/feature.xml</b>
and remove the license feature as follows:
</p>
<pre class=“prettyprint”>
&lt;feature
id="org.eclipse.examples.slideshow.feature"
label="Eclipse Slideshow Feature"
- version="0.2.0.qualifier"
- license-feature="org.eclipse.platform"
- license-feature-version="4.2.1.qualifier"&gt;
+ version="0.2.0.qualifier"&gt;
</pre>
<br />
<p>Once the license issue is resolved we'll want to run the build
again. Using the usual build command:</p>
<pre class=“prettyprint”>
mvn clean verify
</pre>
<br />
<p>Hopefully you've become quite familiar with this command by now...</p>
<h3>Building Tests</h3>
<p>
This time we make it a little further and run into a new error
against <b>org.eclipse.examples.slideshow.jdt.tests</b>:
</p>
<pre class=“prettyprint”>
[ERROR] Failed to execute goal org.eclipse.tycho:tycho-surefire-plugin:0.18.1:test
(default-test) on project org.eclipse.examples.slideshow.jdt.tests:
An unexpected error occured (return code 13). See log for details. -> [Help 1]
</pre>
<br />
<p>This error is extremely vague, so we'll run the build command with
full debugging enabled by passing the parameter “-X” to Maven. This
will output quite a bit of text so I would recommend piping it to a
file or a pager so you can browse it more easily.</p>
<pre class=“prettyprint”>
mvn clean verify -X > log
</pre>
<br />
<p>Usually I jump to the bottom of the log and read backwards looking
for anything that looks interesting. In this case I found a couple
of lines below that mention some unresolvable constraints.</p>
<pre class=“prettyprint”>
!ENTRY org.eclipse.osgi 2 0 2013-08-12 14:45:52.118
!MESSAGE One or more bundles are not resolved because
the following root constraints are not resolved:
!SUBENTRY 1 org.eclipse.osgi 2 0 2013-08-12 14:45:52.118
!MESSAGE Bundle initial@reference:file:../../../org.eclipse.examples.slideshow.
jdt/target/org.eclipse.examples.slideshow.jdt-0.2.0-SNAPSHOT.jar was not resolved.
!SUBENTRY 2 org.eclipse.examples.slideshow.jdt 2 0 2013-08-12 14:45:52.119
!MESSAGE Missing imported package org.eclipse.jface.text_0.0.0.
</pre>
<br />
<p>It's an issue with the bundle org.eclipse.jface.text again. You
will want to help Tycho find this bundle by copying what we did with
org.eclipse.examples.slideshow.jdt previously into the pom.xml for
org.eclipse.examples.slideshow.jdt.tests. For convenience, here is
the section:</p>
<pre class=“prettyprint”>
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;target-platform-configuration&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;dependency-resolution&gt;
&lt;extraRequirements&gt;
&lt;requirement&gt;
&lt;type&gt;eclipse-plugin&lt;/type&gt;
&lt;id&gt;org.eclipse.jface.text&lt;/id&gt;
&lt;versionRange&gt;0.0.0&lt;/versionRange&gt;
&lt;/requirement&gt;
&lt;/extraRequirements&gt;
&lt;/dependency-resolution&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
</pre>
<br />
<p>Once done run the build again:</p>
<pre class=“prettyprint”>
mvn clean verify
</pre>
<br />
<p>This time a different error occurs:</p>
<pre class=“prettyprint”>
[ERROR] Failed to execute goal org.eclipse.tycho:tycho-surefire-plugin:0.18.1:test
(default-test) on project org.eclipse.examples.slideshow.jdt.tests: No tests found.
-> [Help 1]
</pre>
<br />
<p>
No tests found. This is because the test for this bundle is in a
name format that Tycho does not detect by default. The test in this
bundle, found in <b>src/org/eclipse/examples/slideshow/jdt</b>, is
named <b>URLHandlingTests.java</b>.
</p>
<p>
According to the tycho-surefire-plugin documentation
(http://www.eclipse.org/tycho/sitedocs/tycho-surefire/tycho-surefire-plugin/test-mojo.html)
the default search patterns are: <b>**/Test*.java **/*Test.java
**/*TestCase.java</b>
</p>
<p>Since our test file doesn't match any of the patterns, we will need
to modify our pom to tell tycho-surefire-plugin to match our file.
Open up org.eclipse.examples.slideshow.jdt.tests/pom.xml and add the
following section:</p>
<pre class=“prettyprint”>
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;tycho-surefire-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;includes&gt;
&lt;include&gt;**/*Tests.java&lt;/include&gt;
&lt;/includes&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
</pre>
<br />
<p>
I added this immediately after the plugin section we added
previously for the <b>tycho-platform-configuration</b>.
</p>
<p>
Once added try running the build again: <b>mvn clean verify</b>
</p>
<p>It will fail again saying that some tests failed to execute. If you
scroll the output up a little bit, just before the reactor summary
you will see the following message:</p>
<pre class=“prettyprint”>
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.eclipse.examples.slideshow.jdt.URLHandlingTests
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.394 sec&lt;&lt;&lt; FAILURE!
Results :
Tests in error:
testParseJavaURLWithMethod(org.eclipse.examples.slideshow.jdt.URLHandlingTests):
Type "org.eclipse.tests.Junk" not found!
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0
</pre>
<br />
<p>The good news is Tycho's successfully finding and executing our
tests. The problem is the tests are failing. Looking through the
source code for this specific test it looks like there's a TODO item
stating that the tests are not working so I guess this is expected.
In order to move forward we will need to tell Tycho to ignore these
failing tests instead of failing the build. According to the
tycho-surefire-plugin documentation there is a configuration for
skipping the tests which we can use in this case.</p>
<pre class=“prettyprint”>
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;tycho-surefire-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;skipTests&gt;true&lt;/skipTests&gt;
&lt;includes&gt;
&lt;include&gt;**/*Tests.java&lt;/include&gt;
&lt;/includes&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
</pre>
<br />
<p>The &lt;skipTests&gt; section when set to true will skip the tests
during the build. It will still build the bundle -- it just won't
run the tests.</p>
<p>If you run the build again you will see a familiar error:</p>
<pre class=“prettyprint”>
[ERROR] Failed to execute goal org.eclipse.tycho:tycho-surefire-plugin:0.18.1:test
(default-test) on project org.eclipse.examples.slideshow.runner.tests:
No tests found. -> [Help 1]
</pre>
<br />
<p>
Again no tests were found, this time for <b>org.eclipse.examples.slideshow.runner.tests</b>.
In this case however when I look in the src directory I did not see
anything that resembled a test. So instead here we will want to
ignore this bundle. The tycho-surefire-plugin has a configuration to
not fail when no tests are found by setting &lt;failIfNoTests&gt; to
false. Add this section to the runner tests pom.xml file:
</p>
<pre class=“prettyprint”>
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;tycho-surefire-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;failIfNoTests&gt;false&lt;/failIfNoTests&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
</pre>
<br />
<p>
Once added try running the build again to see how much further we
get. This time you will fail on the last and final bundle, <b>org.eclipse.examples.slideshow.text.tests</b>
with a familiar error message:
</p>
<pre class=“prettyprint”>
[ERROR] Failed to execute goal org.eclipse.tycho:tycho-surefire-plugin:0.18.1:test
(default-test) on project org.eclipse.examples.slideshow.text.tests:
No tests found. -> [Help 1]
</pre>
<br />
<p>This is exactly the same issue we saw previously, where the tests
had a name that was not in Tycho's default search parameters. We
simply need to add a config section to the pom.xml to help Tycho
find the test.</p>
<pre class=“prettyprint”>
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;tycho-surefire-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;includes&gt;
&lt;include&gt;**/*Tests.java&lt;/include&gt;
&lt;/includes&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
</pre>
<br />
<p>Unfortunately, after fixing this there will be tests errors again:</p>
<pre class=“prettyprint”>
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.eclipse.examples.slideshow.text.WikiTextParserTests
Tests run: 8, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.083 sec &lt;&lt;&lt; FAILURE!
Results :
Failed tests:
testParseImageTagParts(org.eclipse.examples.slideshow.text.WikiTextParserTests):
expected:&lt;30&gt; but was:&lt;-1&gt;
Tests run: 8, Failures: 1, Errors: 0, Skipped: 0
</pre>
<br />
<p>I just went ahead and used the &lt;skipTests&gt; setting to work
around this issue like we did previously.</p>
<h3>Final build results</h3>
<p>
If you've made it this far, your example slideshow should now
successfully build using Maven/Tycho. You can retrieve your final
build results from the site bundle by looking in <b>org.eclipse.examples.slideshow.site/target/repository</b>.
</p>
<p>This produced a p2 repository containing all the build artifacts
that were defined in the category.xml for the site bundle.</p>
<h3>(Bonus) Signing your jars using the eclipse-jarsigner-plugin</h3>
<p>
The CBI project provides a convenient plugin for signing jar files
using Eclipse Infrastructure via the <b>eclipse-jarsigner-plugin</b>.
Jar signing is only available while on the Eclipse internal network
such as on <b>build.eclipse.org</b> or using the <b>Hudson CI</b>.
Since you must be on the Eclipse Network in order to sign jars you
will want to enable signing in such a way that it's only activated
on request, that way people can continue to build your project even
if they are not in the Eclipse Network. This can be achieved in
Maven using <b>Profiles</b>. For example adding the code block below
to your root pom.xml (parent pom) will add a profile “<b>eclipse-sign</b>
(I added this at the bottom of my pom.xml just before the final &lt;<b>/project</b>&gt;
tag).
</p>
<pre class=“prettyprint”>
&lt;profiles&gt;
&lt;profile&gt;
&lt;id&gt;eclipse-sign&lt;/id&gt;
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.cbi.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;eclipse-jarsigner-plugin&lt;/artifactId&gt;
&lt;version&gt;1.0.4&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;sign&lt;/id&gt;
&lt;goals&gt;
&lt;goal&gt;sign&lt;/goal&gt;
&lt;/goals&gt;
&lt;phase&gt;verify&lt;/phase&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
&lt;/profile&gt;
&lt;/profiles&gt;
</pre>
<br />
<p>When activated, this profile will make your project sign all its
artifacts using the Eclipse signing infrastructure, and the produced
jars will be signed. Note that this will only work on the Eclipse
network such as on build.eclipse.org. To activate this profile you
will need to run the build using this command:</p>
<pre class=“prettyprint”>
mvn clean verify -P eclipse-sign
</pre>
<br />
<p>
Unfortunately this is not all that needs to be done in order to use
the plugin. We still need to inform Maven of where to get the <b>eclipse-jarsigner-plugin</b>.
Since eclipse-jarsigner-plugin is a Maven plugin we will need to add
the following section to your parent pom (I added this immediately
after the &lt;/repositories&gt; section):
</p>
<pre class=“prettyprint”>
&lt;pluginRepositories&gt;
&lt;pluginRepository&gt;
&lt;id&gt;cbi&lt;/id&gt;
&lt;url&gt;https://repo.eclipse.org/content/repositories/cbi-releases/&lt;/url&gt;
&lt;releases&gt;
&lt;enabled&gt;true&lt;/enabled&gt;
&lt;/releases&gt;
&lt;snapshots&gt;
&lt;enabled&gt;false&lt;/enabled&gt;
&lt;/snapshots&gt;
&lt;/pluginRepository&gt;
&lt;/pluginRepositories&gt;
</pre>
<br />
<p>
The <b>eclipse-jarsigner-plugin</b> is a CBI plugin available in the
CBI releases repo on <a href="https://repo.eclipse.org/index.html">repo.eclipse.org</a>,
a Maven repository where Eclipse projects can publish Maven
artifacts.
</p>
<p>You should now be able to run a build and have it signed on
build.eclipse.org. If successful you will see messages such as this
go by:</p>
<pre class=“prettyprint”>
[INFO] --- eclipse-jarsigner-plugin:1.0.4:sign (sign) @
org.eclipse.examples.slideshow.feature ---
[INFO] Signed org.eclipse.examples.slideshow:org.eclipse.examples.slideshow.feature:
eclipse-feature:0.2.0-SNAPSHOT in 1 seconds.
</pre>
<br />
<p>
Your jars will also contain the files <b>ECLIPSE_.SF</b> and <b>ECLIPSE_.RSA</b>
when they are signed.
</p>
<p>One thing that should be noted: if your project uses pack200, the
pack200 tool will break signing unless you use some additional Tycho
configuration. In this case you will need to wrap the
eclipse-jarsigner-plugin between the Tycho pack200 plugins as
follows:</p>
<pre class=“prettyprint”>
&lt;profiles&gt;
&lt;profile&gt;
&lt;id&gt;eclipse-sign&lt;/id&gt;
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;target-platform-configuration&lt;/artifactId&gt;
&lt;version&gt;0.18.1&lt;/version&gt;
&lt;configuration&gt;
&lt;includePackedArtifacts&gt;false&lt;/includePackedArtifacts&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho.extras&lt;/groupId&gt;
&lt;artifactId&gt;tycho-pack200a-plugin&lt;/artifactId&gt;
&lt;version&gt;0.18.1&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;pack200-normalize&lt;/id&gt;
&lt;goals&gt;
&lt;goal&gt;normalize&lt;/goal&gt;
&lt;/goals&gt;
&lt;phase&gt;verify&lt;/phase&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.cbi.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;eclipse-jarsigner-plugin&lt;/artifactId&gt;
&lt;version&gt;1.0.4&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;sign&lt;/id&gt;
&lt;goals&gt;
&lt;goal&gt;sign&lt;/goal&gt;
&lt;/goals&gt;
&lt;phase&gt;verify&lt;/phase&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho.extras&lt;/groupId&gt;
&lt;artifactId&gt;tycho-pack200b-plugin&lt;/artifactId&gt;
&lt;version&gt;0.18.1&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;pack200-pack&lt;/id&gt;
&lt;goals&gt;
&lt;goal&gt;pack&lt;/goal&gt;
&lt;/goals&gt;
&lt;phase&gt;verify&lt;/phase&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.tycho&lt;/groupId&gt;
&lt;artifactId&gt;tycho-p2-plugin&lt;/artifactId&gt;
&lt;version&gt;0.18.1&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;p2-metadata&lt;/id&gt;
&lt;goals&gt;
&lt;goal&gt;p2-metadata&lt;/goal&gt;
&lt;/goals&gt;
&lt;phase&gt;verify&lt;/phase&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;configuration&gt;
&lt;defaultP2Metadata&gt;false&lt;/defaultP2Metadata&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
&lt;/profile&gt;
&lt;/profiles&gt;
</pre>
<br />
<p>
CBI also provides plugins for signing Windows and Mac binaries via
the <b>eclipse-winsigner-plugin</b> and <b>eclipse-macsigner-plugin</b>.
Further details on these plugins can be found in the README for the
cbi-plugins repository: <a
href="http://git.eclipse.org/c/cbi/org.eclipse.cbi.maven.plugins.git/tree/README">http://git.eclipse.org/c/cbi/org.eclipse.cbi.maven.plugins.git/tree/README</a>
</p>
<h3>On to Hudson</h3>
<p>Once your project is building successfully from the command line,
it can be moved into a new Hudson job, where it can be built
periodically based on a pre-determined schedule. A build can also be
triggered by a Git commit or from a Gerrit verification job.</p>
<h3>Further Reading</h3>
<ul>
<li>Additional information on Tycho can be found in the Tycho
Documentation: <a
href="http://eclipse.org/tycho/documentation.php">http://eclipse.org/tycho/documentation.php</a>
</li>
<li>Questions regarding Tycho can be asked on the tycho-user mailing
list: <a
href="https://dev.eclipse.org/mailman/listinfo/tycho-user">https://dev.eclipse.org/mailman/listinfo/tycho-user</a>
</li>
<li>Additional details on CBI can be found on the CBI wiki page:<br>
<a href="http://wiki.eclipse.org/CBI">http://wiki.eclipse.org/CBI</a></li>
<li>Questions regarding CBI can be asked on the cbi-dev mailing
list: <a href="https://dev.eclipse.org/mailman/listinfo/cbi-dev">https://dev.eclipse.org/mailman/listinfo/cbi-dev</a>
</li>
</ul>
<script
src="http://www.eclipse.org/xtend/google-code-prettify/prettify.js"
type="text/javascript"></script>
<script
src="http://www.eclipse.org/xtend/google-code-prettify/lang-xtend.js"
type="text/javascript"></script>
<script type="text/javascript">
prettyPrint();
</script>
<div class="bottomitem">
<h3>About the Authors</h3>
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-8">
<img class="author-picture"
src="/community/eclipse_newsletter/2013/august/images/thanh75.jpg"
alt="Thanh Ha" />
</div>
<div class="col-sm-16">
<p class="author-name">
Thanh Ha <br />
<a target="_blank" href="http://eclipse.org/">Eclipse Foundation</a>
</p>
<ul class="author-link">
<li><a target="_blank" href="http://zxiiro.wordpress.com/">Blog</a></li>
<li><a target="_blank" href="https://twitter.com/zxiiro">Twitter</a></li>
<li><a target="_blank"
href="https://plus.google.com/u/0/107854830702276814626/posts">Google
+</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-34967275-3', 'eclipse.org');
ga('send', 'pageview');
</script>