{"id":17993498,"url":"https://github.com/stempler/bnd-platform","last_synced_at":"2025-04-05T17:08:02.644Z","repository":{"id":14177647,"uuid":"16883821","full_name":"stempler/bnd-platform","owner":"stempler","description":"Build OSGi bundles and Eclipse Update Sites from existing JARs, e.g. from Maven repositories (Plugin for Gradle)","archived":false,"fork":false,"pushed_at":"2025-03-28T10:24:08.000Z","size":6462,"stargazers_count":82,"open_issues_count":5,"forks_count":28,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-29T16:09:06.178Z","etag":null,"topics":["bnd","dependency-management","eclipse","gradle","gradle-plugin","osgi","osgi-bundle","p2"],"latest_commit_sha":null,"homepage":"","language":"Groovy","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stempler.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-02-16T11:55:14.000Z","updated_at":"2025-03-28T10:23:41.000Z","dependencies_parsed_at":"2024-03-24T01:37:30.504Z","dependency_job_id":"caa498d8-d865-4fb8-ac24-70ab567606e9","html_url":"https://github.com/stempler/bnd-platform","commit_stats":{"total_commits":342,"total_committers":16,"mean_commits":21.375,"dds":0.3421052631578947,"last_synced_commit":"90469a2b4faca92128bba533d6ce9e7aa46e16fc"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stempler%2Fbnd-platform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stempler%2Fbnd-platform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stempler%2Fbnd-platform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stempler%2Fbnd-platform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stempler","download_url":"https://codeload.github.com/stempler/bnd-platform/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369952,"owners_count":20927928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bnd","dependency-management","eclipse","gradle","gradle-plugin","osgi","osgi-bundle","p2"],"created_at":"2024-10-29T20:11:42.895Z","updated_at":"2025-04-05T17:08:02.616Z","avatar_url":"https://github.com/stempler.png","language":"Groovy","readme":"bnd-platform\n============\n\nUsing OSGi and having trouble to get all the dependencies as proper OSGi bundles?\nEven worse, sometimes you need to adapt bundles due to class loading issues or make an annoying dependency optional?\n\n*bnd-platform* can help you solve that problem - it builds OSGi bundles and even Eclipse Update Sites from existing JARs, for instance retrieved from Maven repositories together with transitive dependencies. If needed you can adapt the creation of bundles via general or individual configuration options.\n*bnd-platform* is a [Gradle](http://www.gradle.org/) plugin and uses [bnd](http://www.aqute.biz/Bnd/Bnd) to create bundles and [Eclipse](http://www.eclipse.org/) for the creation of p2 repositories.\n\nFor a quick start, check out the (outdated) [sample project on GitHub](https://github.com/stempler/bnd-platform-sample) or use [this minimal example](https://github.com/stempler/bnd-platform-minimal) as a template for your build.\n\n**What *bnd-platform* can do:**\n* Create bundles for any JARs that can be defined as dependencies using Gradle (e.g. local JARs, JARs from Maven repositories) and their transitive dependencies\n* Download dependency sources and create source bundles (with *Eclipse-SourceBundle* manifest header)\n* Add *Bundle-License* and *Bundle-Vendor* headers based on information from associated POM files\n* Merge multiple JARs/dependencies into one bundle, e.g. where needed due to duplicate packages or classloader issues\n* Adapt the configuration for wrapping JARs or adapting existing bundles, e.g. to influence the imported packages\n* Create an Eclipse Update Site / p2 repository from the created bundles\n* Automatically associate version numbers to imported packages (experimental)\n\n\nUsage\n-----\n\nThe simplest way to apply the plugin to your Gradle build is using the latest release on the [Gradle Plugin Portal](https://plugins.gradle.org/plugin/org.standardout.bnd-platform).\n\nThe plugin is also hosted on Maven Central:\n\n```groovy\nbuildscript {\n\trepositories {\n\t\tmavenCentral()\n\t}\n\tdependencies {\n\t\tclasspath 'org.standardout:bnd-platform:\u003cversion\u003e'\n\t}\n}\n\napply plugin: 'org.standardout.bnd-platform'\n```\n\nYou can look up the latest release version in the [GitHub releases](https://github.com/stempler/bnd-platform/releases).\n\nAlternatives are including the repository content in the **buildSrc** folder as done in the [sample project](https://github.com/stempler/bnd-platform-sample) or by installing the plugin to your local Maven repository using `gradlew install` and adding it as dependency to your build script via `mavenLocal()` repository.\n\nSnapshot versions are available in the related sonatype repository:\n\n```groovy\nbuildscript {\n    repositories {\n        mavenCentral()\n        maven {\n            url 'https://oss.sonatype.org/content/repositories/snapshots/'\n        }\n    }\n    dependencies {\n        classpath 'org.standardout:bnd-platform:\u003cversion\u003e'\n    }\n}\n\napply plugin: 'org.standardout.bnd-platform'\n```\n\nThe latest snapshot version can be found in the [Sonatype repository](https://oss.sonatype.org/content/repositories/snapshots/org/standardout/bnd-platform/).\n\nIf changes were made after the last release, the snapshot version is the last release version with the minor version number increased by one and the qualifier set to `-SNAPSHOT`.\nFor example, for the 3.1.0 release the snapshot version would be 3.2.0-SNAPSHOT.\n\n\n### Tasks\n\nThe **platform** plugin comes with several Gradle tasks - the following are the main tasks and build upon each other:\n\n* ***bundles*** - create bundles and write them to **build/plugins**\n* ***potentialOptionalImports*** Creates a potentialOptionalImports.txt file of imported packages of all generated bundles with the optionalImport instruction (See \"Optional Dependencies\" section below)\n* ***updateSite*** - create a p2 repository from the bundles and write it to **build/updatesite** (default)\n* ***updateSiteZip*** - create a ZIP archive from the p2 repository and write it to **build/updatesite.zip** (default)\n\nIn addition, the ***clean*** task deletes all previously created bundles or update site artifacts. Usually you will want to clean the created bundles when building an update site, e.g. `gradle clean updateSite`.\n\nBe aware that for building the p2 repository Eclipse is used. If no path to a local Eclipse installation is configured (see the settings section later on) the plugin will by default download Eclipse Indigo and use it for that purpose.\n\n### Adding dependencies\n\n*bnd-platform* adds a configuration named **bndplatform** to a Gradle build.\nPrior to version 3 the configuration was named **platform**, but this clashes with a [platform method](https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/dsl/DependencyHandler.html#platform-java.lang.Object-) that was introduced in Gradle 5.\n\nYou can add dependencies to the **bndplatform** configuration and configure them like you would with any other Gradle build - for example:\n\n```groovy\n// add Maven Central so the dependency can be resolved\nrepositories {\n\tmavenCentral()\n}\n\ndependencies {\n    // add pegdown as dependency to the platform configuration\n    bndplatform 'org.pegdown:pegdown:1.4.2'\n}\n```\n\nThat's it - if you combine the previous code snippet with this one you have your first *bnd-platform* build script. A call `gradle updateSite` would create a p2 repository containing bundles for the [pegdown](https://github.com/sirthias/pegdown) library and its dependencies.\n\nPlease see the Gradle documentation on [basic](http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html) and [advanced](http://www.gradle.org/docs/current/userguide/dependency_management.html) dependency management for more details on the dependency configration and advanced issues like resolving version conflicts or dealing with transitive dependencies.\n\nAs an alternative to the conventional dependency declaration you can use the *platform* extension to add a dependency using the **bundle** keyword:\n\n```groovy\nplatform {\n    // add pegdown as dependency to the platform configuration\n    bundle 'org.pegdown:pegdown:1.4.2'\n}\n```\n\nBoth notations support adapting the dependency configuration as supported by Gradle, e.g. excluding specific transitive dependencies. However, adapting the OSGi bundle creation is only possible with the second notation, as it supports an additional **bnd** configuration.\n\n### Bundle configuration\n\nThe *bnd* library is used as a tool to create OSGi bundles from JARs. *bnd* analyzes the class files in a JAR to determine packages to import and export. *bnd* also allows to configure its behavior through a set of header instructions that resemble the OSGi manifest headers (see the [bnd website](http://www.aqute.biz/Bnd/Format) for a detailed description).\n\nThe bundle configuration can be applied when adding a dependency:\n\n```groovy\nplatform {\n    bundle(group: 'net.sf.ehcache', name: 'ehcache-core', version:'2.6.6') {\n    \tbnd {\n\t\t\t// make hibernate packages optional\n\t\t\toptionalImport 'org.hibernate', 'org.hibernate.*'\n\t\t}\n\t}\n}\n```\n\nOr independently - just registering the configuration without adding a dependency. The configuration is only applied if the dependency is either added directly or as a transitive dependency at another point in the script.\n\n```groovy\nplatform {\n    bnd(group: 'net.sf.ehcache', name: 'ehcache-core') {\n\t\t// make hibernate packages optional\n\t\toptionalImport 'org.hibernate', 'org.hibernate.*'\n\t}\n}\n```\n\nNote that in the example above the version was omitted - the configuration applies to any dependency matching the group and name, regardless of its version.\n\nThe configuration options inside the **bnd** call are sketched below:\n\n```groovy\nplatform {\n    bnd(\u003cDependencyNotation\u003e) {\n        // override/set the symbolic name\n        symbolicName = \u003cSymbolicNameString\u003e\n        // override/set the bundle name\n        bundleName = \u003cBundleNameString\u003e\n        // override/set bundle version\n        version = \u003cVersionString\u003e\n        // generic bnd header instruction\n        instruction \u003cHeader\u003e, \u003cInstruction\u003e\n        // adapt the Import-Package instruction to import the given packages optionally\n        optionalImport \u003cPackage1\u003e, \u003cPackage2\u003e, ...\n        // adapt the Import-Package instruction to add the given package instruction\n        prependImport  \u003cPackageInstruction1\u003e, \u003cPackageInstruction2\u003e, ...\n\n        // override the default behavior, if a (generated) qualifier should be added to\n        // the version of wrapped bundles (see plugin settings)\n        addQualifier = true | false\n    }\n}\n```\n\n### Automatic package import versioning (experimental)\n\nYou can enable auto-determining versions for package imports by enabling the `determineImportVersions` plugin setting. For each bundle to be created from a JAR retrieved via Maven/Ivy, their direct dependencies are analysed in turn and package imports are determined by the packages present there and the version of the dependency modules. This works for most cases, but is not as good as if the information would be determined based on the packages exported by the dependencies. What comes as a bonus is that for packages that are not found in the direct dependencies the imports are made optional automatically.\n\nA default strategy defines how the versions are represented for the **Import-Package** instructions, i.e. what lower and upper bounds are allowed for an imported package. Pre-defined strategies that can be used are:\n* **MINIMUM** - the module version is the minimum version for the package import, there is no upper boundary\n* **MAJOR** - like MINIMUM, but with the next major version (excluded) as upper boundary  (default)\n* **MINOR** - like MINIMUM, but with the next minor version (excluded) as upper boundary\n* **NONE** - no version constraint for package imports\n\nSet the version strategy for the whole platform like this:\n\n```groovy\nplatform {\n    determineImportVersions = true\n    importVersionStrategy = MINIMUM\n}\n```\n\nYou can also adapt the configuration for specific dependencies, or define a custom version strategy using a Closure. See the definitions of the pre-defined strategies in the sources for `PlatformPluginExtension` for more information on how this can be done. The following example demonstrates both:\n\n```groovy\nplatform {\n    imports(group: 'com.google.inject', name: 'guice') {\n        versionStrategy = {\n            // guice uses a strange versioning scheme for its package exports\n            // e.g. version 2.0 of exports packages with version 1.2, version 3.0 with 1.3 etc.\n            \"[1.${it.major},1.${it.major + 1})\"\n        }\n    }\n}\n```\n\nThe above example influences the package imports for the packages provided by *guice* for all bundles that have *guice* as their dependency. This is needed in this case as *guice* already is provided as OSGi bundle with the exported package versions differing from the module version - and because *bnd-platform* currently only uses the information of the module version and applies it to all imports instead of using available package export information. This might be improved in the future if there is need.\n\n### Default configuration\n\n*bnd-platform* will by default leave JARs that are recognized as bundles (meaning they have a *Bundle-SymbolicName* header already defined) as they are, except to eventually added *Bundle-License* and *Bundle-Vendor* headers if not yet present. If an existing bundle is wrapped because a bundle configuration applies to it, the configration from the bundle manifest applies as default configuration.\n\nTo other JARs the global default configuration applies, which exports packages with the dependency's version number and imports any identified packages as mandatory import. You can override or extend the global default configuration by adding a **bnd** configuration without giving a dependency notation, for example:\n\n```groovy\nplatform {\n    bnd {\n        // make the package junit.framework an optional import\n        // for all JARs that were not bundles already\n        optionalImport 'junit.framework'\n    }\n}\n```\n\nBut be careful what you put into the default configuration - setting the *symbolicName* or *version* here will not be seen as error, but does not make any sense and may lead to unpredicatable behavior (as there can't be two bundles with the same symbolic name and version).\n\n### Configuration priority\n\nA bundle configuration that is more concrete will always override/extend a more general configuration. A configuration applied to a dependency group takes precedence over the default configuration, while a configuration specified for a combination of group and name in turn takes precedence over a group configuration.\nIf configurations are defined on the same level, the configuration that is defined later in the script will override/extend a previous one.\n\nPlease note that in addition, in the combined configurations for a bundle, all assignments (e.g. `version = '1.0.0'`) take precedence over the method calls like `instruction` and `optionalImport`. This allows for instance to both override the version of a bundle in a concrete configuration and making use of it in a more general configuration:\n\n```groovy\nplatform {\n    bnd(group: 'org.standardout') {\n        // packages with version number (uses the version provided further below)\n        instruction 'Export-Package', \"org.*;version=$version\"\n    }\n    bnd(group: 'org.standardout', name: 'bnd-platform', version: '0.1') {\n        // override the version\n        version = '0.1.0.RELEASE'\n    }\n}\n```\n\n### Override any configuration\n\nStarting with version 0.3 it is possible to override all bundle configurations at once. This also applies to dependencies that already are an OSGi bundle. You can use any instructions you would use inside **bnd** to apply them to all dependencies in a call to **override**:\n\n```groovy\nplatform {\n    override {\n        // JUnit optional everywhere - so we can exclude it from products\n        optionalImport 'junit.framework.*', 'org.junit.*'\n    }\n}\n```\n\n### Optional Dependencies\n\nMany third party libraries have optional dependencies being specified by using `\u003coptional\u003etrue\u003c/optional\u003e` in a pom.xml file.\n\nFor example the [Retrofit](https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit/2.4.0 \"Retrofit 2.4.0 on Maven Central\") library has android as optional dependency:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.google.android\u003c/groupId\u003e\n  \u003cartifactId\u003eandroid\u003c/artifactId\u003e\n  \u003coptional\u003etrue\u003c/optional\u003e\n\u003c/dependency\u003e\n```\nSince it is unlikely to happen that you want an android dependency in your OSGi application it can be marked as optional:\n\n```groovy\nplugin('com.squareup.retrofit2:retrofit:2.4.0'){\n\tbnd {\n\t\toptionalImport 'android.os'\n\t\toptionalImport 'android.net'\n    \t}\n}\n```\nUnfortunately the information about the `\u003coptional\u003etrue\u003c/optional\u003e` instruction is lost during a Gradle build because Gradle's dependency management does not support it yet. (FYI https://docs.gradle.org/4.6/release-notes.html#support-for-optional-dependencies-in-pom-consumption)\nSo the bnd-platform plug-in cannot add the optionalImport instructions automatically, yet.\n\nFor the [Retrofit](https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit/2.4.0 \"Retrofit 2.4.0 on Maven Central\") library it is fairly easy to write the optionalImport instructions like above, but there are other libraries, which have plenty of these `\u003coptional\u003etrue\u003c/optional\u003e` instruction.\n\nIn order to generate the list of potential optional imports a _potentialOptionalImports_ task has been created. This task  creates a _potentialOptionalImports.txt_ file, which lists potential optional imports of each and every bundle, which is created during a build.\n\n### Sharing configurations\n\nEven though setting up an extensive platform of OSGi bundles can be done quite fast using *bnd-platform*, in many cases additional configuration is necessary. It comes naturally that it should be possible to reuse and share those configurations.\n\nWith Gradle you can use `apply from: 'someScript.gradle'` to include other build scripts. In those you can define dependencies, bnd configuration or remote repositories like you would do in the main build script.\n\nAn alternative is using the [gradle-include-plugin](https://github.com/stempler/gradle-include-plugin) which allows you to include specific methods from an external script and thus provide parameters to the include. In context of *bnd-platform* it often makes sense to provide a version number as parameter. See the [sample project](https://github.com/stempler/bnd-platform-sample) for some nice examples, e.g. the [logging](https://github.com/stempler/bnd-platform-sample/blob/master/modules/logging.groovy) or [geotools](https://github.com/stempler/bnd-platform-sample/blob/master/modules/geotools.groovy) platform modules defined there. Using the *include* plugin these modules are applied to the sample build like this:\n\n```groovy\ninclude {\n\tfrom('modules/logging.groovy') {\n\t\tslf4jAndLogback '1.7.2', '1.0.10' // slf4j and logback with given versions\n\t}\n\n\tfrom('modules/geotools.groovy') {\n\t\tgeotools() // include geotools with default modules and version\n\t}\n}\n```\n\nWe have created a repository on GitHub to collect the platform modules and configurations we use for our projects and you are welcome to fork and contribute: [shared-platform](https://github.com/igd-geo/shared-platform). The repository is designed to be used with the [gradle-include-plugin](https://github.com/stempler/gradle-include-plugin) and to enable the sharing of configurations without imposing them on you - just include the configuration that makes sense for you and augment it with your own.\n\n### Defining features *(since 1.1)*\n\nYou can combine dependencies to an Eclipse feature. The feature will contain the dependencies, as well as their transitive dependencies. You can use the features for more fine-grained control in you target platform or in a feature based Eclipse product. The platform feature contains all features you define. If fetching sources is enabled, a matching source feature will be created for each feature.\n\nA feature includes all plugins (bundles) defined in its context, here an example:\n\n```groovy\nplatform {\n\t// define a feature\n\tfeature(id: 'platform.restclient', name: 'REST client dependencies', version: '1.0.0') {\n\t\t// define what's in the feature\n\n\t\tplugin 'org.codehaus.groovy.modules.http-builder:http-builder:0.6', {\n\t\t\t// exclude this transitive dependency\n\t\t\texclude group: 'net.sourceforge.nekohtml', module: 'nekohtml'\n\t\t}\n\t\tplugin 'commons-io:commons-io:2.4'\n\n\t\t// include a feature that is defined elsewhere given its ID\n\t\tincludes \u003c\u003c 'platform.geotools'\n\t}\n}\n```\n\nProviding  a feature ID is mandatory, but *name* and *version* may be omitted (the version defaults to the platform feature version). `plugin` and `bundle` can be used synonymously inside the `feature` block, but when using `bundle` you may experience problems when used in inner closures.\n\nThe feature may include also other required features. See an example below how to define such dependencies:\n\n```groovy\n platform {\n    // define a feature\n    feature(id: 'platform.restclient', name: 'REST client dependencies', version: '1.0.0') {\n\n        requires (\n            featureName: \"required.feature.name\",\n            version: \"1.0.0\",\n            match: \"greaterOrEqual\"\n        )\n\n        //... the rest of the feature definition\n\n    }\n}\n```\n\n### Local dependencies\n\nYou can easily add local JARs to the platform. **If the JAR is not an OSGi bundle yet**, you have add it on its own and at least provide **symbolicName** and **version**:\n\n```groovy\nplatform {\n\tbundle file('someLibrary.jar'), {\n\t\tbnd {\n\t\t\tversion = '1.0.0' // mandatory\n\t\t\tsymbolicName = 'com.example.library.some' // mandatory\n\t\t\tbundleName = 'Some Library'\n\t\t\tinstruction 'Export-Package', \"com.example.library.some.*;version=$version\"\n\t\t}\n\t}\n\n\t// depends on groovy\n\tbundle 'org.codehaus.groovy:groovy:1.8.5'\n}\n```\n\nAs in the example above, you should make sure to add additional dependencies that might be needed by the JAR. Please note that for a JAR `filename.jar` sources provided in a `filename-sources.jar` will be wrapped automatically in a corresponding source bundle.\n\n**JARs that are already OSGi bundles** you can include en masse, and without the need for additional configuration, for example:\n\n```groovy\nplatform {\n\t// all bundles in a directory\n\tbundle fileTree(dir: 'lib') {\n\t\tinclude '*.jar'\n\t}\n\n\t// specific bundles\n\tbundle files('someBundle.jar', 'someOtherBundle.jar')\n}\n```\n\n### Multiple versions of a bundle/dependency\n\nWhen resolving the **platform** configuration with **bnd-platform**, **Gradle** will only include one version for each dependency. This is intentional as even though OSGi is designed to deal with issues such as multiple versions of a bundle, often it will lead to problems - namely package uses conflicts (please note that you can get package uses conflicts even with only one version of each bundle, as some may conflict with packages provided by the system bundle).\n\nHowever, if there is the need to have multiple versions of a bundle, these are your options:\n* use multiple **bnd-platform** builds, each will resolve its dependencies independent of the others\n* add dependencies to the **platformaux** configuration - they will be added in addition to the resolved platform configuration (but w/o their transitive dependencies)\n* add the additional versions as local dependencies\n\nFollowing is an example using the **platformaux** configuration:\n\n```groovy\ndependencies {\n    // need old version (pre 4) of asm for some bundles\n    platformaux 'asm:asm:3.3.1'\n}\n```\n\n### Merged bundles\n\nSometimes it is necessary to create a bundle out of multiple JARs, most often due to class loading issues. The [Geotools](http://www.geotools.org/) library is a famous example of that. It uses [Java SPI](http://docs.oracle.com/javase/tutorial/sound/SPI-intro.html) as extension mechanism, which does only recognize extensions from the same class loader. One way [suggested to cope with this](http://docs.geotools.org/stable/userguide/welcome/application.html#osgi) is creating a monolithic bundle that includes all the needed geotools modules (which I prefer because with Geotools otherwise you have different bundles partly exporting the same packages). Doing this with *bnd-platform* is quite easy:\n\n```groovy\nplatform {\n\tdef geotoolsVersion = '10.4'\n\n\t// define the merged bundle\n\tmerge {\n\t\t// the match closure is applied to all dependencies/artifacts encountered\n\t\t// if true, an artifact is included in the bundle\n\t\tmatch {\n\t\t\t// merge all artifacts in org.geotools group, but not gt-opengis\n\t\t\tit.group == 'org.geotools' \u0026\u0026 it.name != 'gt-opengis'\n\t\t}\n\n\t\tbnd {\n\t\t\tsymbolicName = 'org.geotools'\n\t\t\tbundleName = 'Geotools'\n\t\t\tversion = geotoolsVersion\n\t\t\tinstruction 'Export-Package', \"org.geotools.*;version=$version\"\n\t\t\tinstruction 'Private-Package', '*'\n\t\t}\n\t}\n\n\t// add geotools modules as dependencies\n\tbundle \"org.geotools:gt-shapefile:$geotoolsVersion\"\n\t// etc.\n}\n```\n\nProviding the **symbolicName** and **version** as part of the *bnd* configuration is mandatory for merged bundles, as the information from the original JARs' manifests is discarded.\nPlease note that the example above misses the Maven repositories needed to actually retrieve those artifacts, see the sample project for a [more complete example](https://github.com/stempler/bnd-platform-sample/blob/master/modules/geotools.groovy).\n\nIf you use `match { ... }` to merge bundles, it is called for each artifact. The artifact can be accessed via the variable **it**. An artifact has the following properties that can be useful to check against in a *match*:\n\n* **group** - the group name of the artifact, e.g. *'org.geotools'*\n* **name** - the name (artifact ID) of the artifact, e.g. *'gt-shapefile'*\n* **version** - the version of the artifact\n* **file** - the local or downloaded file of the artifact, as File object\n\nAs alternative to **match** or in combination with it you can add bundles to merge via **bundle** or **include**. The syntax is the same as when adding dependencies. However, using **include** you just specify an artifact to be included if it is a dependency defined somewhere else, it does not add it as dependency.\n\n```groovy\nplatform {\n\tmerge {\n\t\tbundle 'someGroup:someArtifact:1.0.0' // also added as dependency\n\t\tinclude group: 'someGroup', name: 'someOtherArtifact' // not added as dependency\n\n\t\tbnd {\n\t\t\t...\n\t\t}\n\t}\n}\n\n```\n\n#### Merge settings\n\nYou can supply parameters to **merge**, currently those are:\n\n* **failOnDuplicate** - fail if the same file occurs in more than one JAR (not taking into account the manifest)  (default: **true**)\n* **collectServices** - combines files in `META-INF/services` defining extensions via SPI (default: **true**)\n\nYou can specify them as named parameters, e.g.:\n\n```groovy\nplatform {\n\tmerge(failOnDuplicate: false, collectServices: true) {\n\t\t...\n\t}\n}\n```\n\nPlugin settings\n---------------\n\nVia the platform extension there are several settings you can provide:\n\n* **fetchSources** - if sources for external dependencies should be fetched and source bundles created (default: **true**)\n* **updateSiteDir** - the directory the generated p2 repository is written to (default: `new File(buildDir, 'updatesite')`)\n* **updateSiteZipFile** - the target file for the zipped p2 repository (default: `new File(buildDir, 'updatesite.zip')`)\n* **appendUpdateSite** - if any the generated p2 repository should be appended to the one that already exists in **updateSiteDir** (default: `false`)\n* **createFeatureVersionFiles** - if for the created update site, a version file should be created per feature, e.g. `\u003cfeature-id\u003e_versions.json`, that includes information on the versions of the feature available in the p2 repository (default: `false`)\n* **eclipseHome** - File object pointing to the directory of a local Eclipse installation to be used for generating the p2 repository (default: `null`)\n* **eclipseMirror** - Eclipse download URLs to be used when no local installation is provided via *eclipseHome*. Since version 3 uses an Eclipse 2023-09 mirror by default.\n* **downloadsDir** -  the directory to store the downloaded Eclipse installation on local, this works if *eclipseHome* is not specified. (default: `new File(buildDir, 'eclipse-downloads')`)\n* **generatePlatformFeature** - States if a general feature should be created. In case custom features are generated you might not want to have an additional \"generated platform feature\" besides your own features. (default: **true**)\n* **featureId** - the identifier of the feature including the platform bundles that will be available in the created update site (default: **'platform.feature'**)\n* **featureName** - the name of the feature including the platform bundles that will be available in the created update site (default: **'Generated platform feature'**)\n* **featureVersion** - the version number for the feature including the platform bundles that will be available in the created update site (defaults to the project version)\n* **featureProvider** - the provider name to be used for features (default: **'Generated with bnd-platform'**)\n* **categoryId** - the identifier of the feature's category (default: **'platform'**)\n* **categoryName** - the name of the feature's category (default: **'Target platform'**)\n* **determineImportVersions** - automatically determine package import versions (default: `false`)\n* **importVersionStrategy** = global strategy for import versions (default: `MAJOR`)\n* **importIgnorePackages** - set of packages to ignore when analyzing packages of dependencies to determine package import versions\n* **defaultQualifier** - the default version qualifier to use for wrapped bundles. If a qualifier is already\n\t * present the default will be appended, separated by a dash. Does by default not apply to file based dependencies (default: **'autowrapped'**)\n* **useBndHashQualifiers** - if a hash calculated from the bnd configuration should be used as version qualifier for wrapped bundles. It replaces the default qualifier where applicable (default: `true`)\n* **useFeatureHashQualifiers** - if a hash based on the feature content should be appended as qualifier to feature versions (default: `true`)\n* **hashCalculator** - hash calculator for determining the hash qualifier from a bundle's bnd configuration, can be replaced by a custom closure (default: `ADLER32`)\n* **hashQualifierMap** - for bundles/features that would have hash based qualifiers, map those to qualifiers that ensure a specific behavior. The default qualifier map is based on version history persisted to a file and date based qualifiers to ensure increasing version qualifiers (can be important for update mechanisms). To use the default qualifier map, simply provide a file or file path for the version history to be stored in (will be stored as Json).\n* **defaultQualifierMap.prefix** - the prefix to use for version qualifiers provided via the default qualifier map (default: `'i'`)\n* **defaultQualifierMap.baseDate** - configures the base level for time based qualifiers generated by the default qualifier map. Valid values are `YEAR`, `MONTH`, `DAY`, `MINUTE`, `SECOND`, `MILLISECOND` (default: `MONTH`)\n* **auxVersionedSymbolicNames** - states if the symbolic names for bundles created via the platformaux configuration should be adapted to include the version number. This is useful when dealing with systems that have problems when there actually are bundles with the same name but different versions. An example is Eclipse RCP plugin-based products - they can include only one version of a bundle with the same name. (default: `false`)\n* **removeSignaturesFromWrappedBundles** - if signatures should be removed from signed jars that are wrapped using bnd (default: `true`)\n* **addBndPlatformManifestHeaders** - if *bnd-platform* specific manifest headers should be added. Adds information to the manifest that allows reconstructing the original Maven artifact identifiers (default: `false`)\n* **extractPomInformation** - if additional configuration information from POM is desired (default: `true`)\n\n\u003c!--- * **defaultQualifierMap.fixedDatePattern** - a fixed pattern for formatting the current date for use as part of the qualifier. Provide the pattern in a form suitable for SimpleDataFormat that ensures that the order of those dates as String is the same as the date order (e.g. `'yyyyMMddHHmm'`) --\u003e\n\nFor example:\n\n```groovy\nplatform {\n\tfetchSources = false\n\tfeatureVersion = '3.1.0'\n\teclipseHome = new File('/opt/eclipse')\n\teclipseMirror = 'http://myeclipsedownload.com/eclipse.tar.gz'\n}\n```\n\nLicense\n-------\n\nThis software is licensed under the\n[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstempler%2Fbnd-platform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstempler%2Fbnd-platform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstempler%2Fbnd-platform/lists"}