////
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at

     https://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
////

= Building an Eclipse plugin

[NOTE]
====
Note that this feature is considered as *experimental*.

It should work with a simple configuration but may not with complex ones. If you have any issue with that feature, you are welcomed to come discuss your use case on the link:https://ant.apache.org/ivy/mailing-lists.html[ivy-user] mailing list, or discuss about implementation issues or improvement you may have found, on link:https://ant.apache.org/ivy/mailing-lists.html[ant-dev].
====


This page describes how to build an Eclipse(TM) plugin with Apache Ivy(TM) and its OSGi(TM) capabilities.


== Quick setup


In a few steps, we will set up a build to compile and package an Eclipse plugin.

    * download this link:../samples/eclipse-plugin/ivy.xml[ivy.xml], this link:../samples/eclipse-plugin/ivysettings.xml[ivysettings.xml], this link:../samples/eclipse-plugin/ivysettings.properties[ivysettings.properties], this link:../samples/eclipse-plugin/build.xml[build.xml], and put them into your plugin folder

    * in the `ivysettings.properties`, specify the location of the plugins folder of your Eclipse target

    * in the `ivy.xml`, change the symbolic name declared in the extends element

    * (*__optional__*) by default the `build.xml` is expecting the sources to be in the `src` folder. You may want to edit it if it is not the case

    * (*__optional__*) if Ivy is not in Ant's classpath, link:https://ant.apache.org/ivy/download.cgi[download the Ivy jar] and edit the `build.xml` accordingly (see the comments at the beginning of the file)


And that's it ! Now let's use it.

First, Ivy needs to aggregate the OSGi metadata of the target platform. To do so just launch:

[source]
----
ant buildobr
----

You need to run that command only once. Or each time your target platform get modified.

Then to resolve and build, just run:

[source]
----
ant build
----


=== Eclipse setup


You probably have already configured your project in Eclipse via the PDE. Let's see how to change that and use link:https://ant.apache.org/ivy/ivyde/[Apache IvyDE]:

    * First remove from your project's classpath the PDE dependencies container

    * then right click on the `ivy.xml` you just added and select "Add Ivy library"

    * in the configuration panel of the `IvyDE` classpath container, as the settings file put `${workspace_loc:mypluginproject/ivysettings.xml}`

    * click finish and your Eclipse project should build now.


NOTE: For resolution to work correctly, Ivy relies on the aggregated metadata of your target platform. Even if you want to only build with Eclipse, you will have to run the command `ant obrindex` at least one time.


== Details on the setup



=== The repository


When building an Eclipse plugin, we are relying on a "target platform", the Eclipse installation we want our plugin to be eventually installed into. For Ivy, this will represent the repository of artifacts.

Ivy needs an aggregation of the OSGi metadata in order to resolve a such repository. The Ant task link:../use/buildobr{outfilesuffix}[buildobr] builds a OBR (OSGi Bundle Repository) descriptor file from a set of OSGi bundles. So here we are using this Ant task to gather OSGi metadata from the Eclipse plugins in the "target platform". In the above example, the file is built in `target/repo-eclipse.xml`.

The plugin to be built has a `ivy.xml` file describing its dependencies to be used by Ivy. Since the actual dependencies are in the `MANIFEST.MF` file, in the `ivy.xml` file we specify that it extends `META-INF/MANIFEST.MF`. So there are few dependencies specified in the `ivy.xml`. But as Ivy doesn't support the `Bundle-Fragment` OSGi feature, the `ivy.xml` can help specify the missing dependencies.

Having this setup, it is then a standard Ant+Ivy build. Ivy computes the classpath to be used by the `javac` tasks. Note that `javac` is not aware of the OSGi metadata and is then incapable of failing to compile if private packages are accessed.
