{"id":18011673,"url":"https://github.com/renatoathaydes/osgi-run","last_synced_at":"2025-03-26T16:30:45.459Z","repository":{"id":18475813,"uuid":"21670982","full_name":"renatoathaydes/osgi-run","owner":"renatoathaydes","description":"Osgi-Run - A Gradle plugin to make the development of modular applications using OSGi completely painless","archived":false,"fork":false,"pushed_at":"2022-02-13T17:31:47.000Z","size":660,"stargazers_count":52,"open_issues_count":10,"forks_count":13,"subscribers_count":10,"default_branch":"master","last_synced_at":"2023-05-25T04:52:37.928Z","etag":null,"topics":["gradle-plugin","java","osgi","osgi-environment"],"latest_commit_sha":null,"homepage":null,"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/renatoathaydes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-09T22:18:50.000Z","updated_at":"2023-05-04T15:47:26.000Z","dependencies_parsed_at":"2022-09-11T20:30:23.402Z","dependency_job_id":null,"html_url":"https://github.com/renatoathaydes/osgi-run","commit_stats":null,"previous_names":[],"tags_count":17,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fosgi-run","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fosgi-run/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fosgi-run/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fosgi-run/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renatoathaydes","download_url":"https://codeload.github.com/renatoathaydes/osgi-run/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222155951,"owners_count":16940424,"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":["gradle-plugin","java","osgi","osgi-environment"],"created_at":"2024-10-30T03:12:24.000Z","updated_at":"2024-10-30T03:12:24.614Z","avatar_url":"https://github.com/renatoathaydes.png","language":"Groovy","funding_links":[],"categories":[],"sub_categories":[],"readme":"osgi-run\n========\n\n[![Maven Central](https://img.shields.io/maven-central/v/com.athaydes.gradle.osgi/osgi-run-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.athaydes.gradle.osgi%22%20AND%20a:%22osgi-run-core%22)\n\nOsgi-Run - A Gradle plugin to make the development of modular applications using OSGi completely painless.\n\n### Features\n\n* Create and run an OSGi environment using any container.\n* Deploy the Gradle project's or sub-projects' bundles to the container easily. \n* Fetch dependencies using the standard Gradle way, from any\n  [repository](https://docs.gradle.org/current/userguide/dependency_management.html#sec:repositories)\n  supported by Gradle.\n* Wrap into bundles any non-OSGi-ready dependencies automatically\u003csup\u003e[1](#footnote-1)\u003c/sup\u003e.\n* Use dependencies as system libs, ie. let them live in the system classpath\u003csup\u003e[2](#footnote-2)\u003c/sup\u003e.\n\n### What can I use osgi-run for?\n\nBasically, to get your Gradle project (and sub-projects) bundles into an OSGi container\nas part of the Gradle build, or just run existing bundles sourced from Gradle-compatible repositories.\n\nHere's how it works:\n\n#### If you already have your bundle(s) in a Gradle-compatible repository:\n\n1. create a `build.gradle` file and apply the `osgi-run` plugin.\n2. add your bundles to the project dependencies with the `osgiRuntime` type.\n3. run `gradle createOsgi`.\n4. Find your OSGi environment ready to run in the `build/osgi` directory.\n   Start the OSGi container with `run.sh` or `run.bat`.\n\n#### If you want to start a Gradle project from scratch:\n\n1. create a Java [Gradle build](https://gradle.org/getting-started-gradle-java/).\n2. specify `compile` dependencies (plain Java or OSGi libs) as usual,\n   plus some `osgiRuntime` deps if you need some OSGi bundles at runtime.\n3. add a Gradle plugin such as\n   [biz.aQute.bnd.builder](https://github.com/bndtools/bnd/tree/master/gradle-plugins) to turn your\n   jar into a bundle.\n4. add the `osgi-run` plugin to your build.\n5. run `gradle createOsgi`.\n6. Find your OSGi environment ready to run in the `build/osgi` directory.\n   Start the OSGi container with `run.sh` or `run.bat`.\n\n\u003csub\u003e\n\u003ca name=\"footnote-1\"\u003e1\u003c/a\u003e: osgi-run uses [Bnd](http://www.aqute.biz/Bnd/Bnd) to wrap Gradle dependencies as\nbundles if necessary before adding them to the OSGi runtime, including transitive dependencies, so using normal\nflat jars becomes as easy as possible.\n\u003c/sub\u003e\n\n\u003csub\u003e\n\u003ca name=\"footnote-2\"\u003e2\u003c/a\u003e: If some of your dependencies assume a flat classpath like in regular Java and won't work any other way\n(eg. loads classes at runtime, scans the classpath, uses JVM internals),\nyou can use still them as **system libs**, which are just jars added to the system classpath and visible from all bundles\n(see the system libs section below).\n\u003c/sub\u003e\n\n## osgi-run Tutorial and learning resources\n\nTo get started quickly, see the [Quick Start](#quick-start) section further below.\n\nFor a more advanced guide, check the [osgi-run tutorial](https://sites.google.com/a/athaydes.com/renato-athaydes/posts/osgi-runtutorial-runyourjavakotlinfregecodeinosgi).\n\nPlenty of examples are available in the [osgi-run-test](osgi-run-test/) directory.\n\n## Applying the osgi-run plugin\n\n```groovy\nplugins {\n    id \"com.athaydes.osgi-run\" version \"2.0\" // check top of the page for latest version\n}\n```\n\n### Use Maven Central to resolve plugin\n\nIf you have trouble with the Gradle Plugins Repository, use Maven Central instead:\n\n```groovy\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n    dependencies {\n        classpath \"com.athaydes.gradle.osgi:osgi-run-core:2.0\"\n    }\n}\n\napply plugin: 'com.athaydes.osgi-run'\n```\n\n## Quick Start\n\nGiven a Gradle project whose sub-projects are OSGi bundles, create an OSGi environment\ncontaining the sub-projects' bundles, running it with Apache Felix and the default bundles:\n\n*build.gradle*\n```groovy\nrunOsgi {\n  bundles += subprojects\n}\n```\n\nOr if your OSGi environment consists of the Gradle project itself,\nits compile-time dependencies, plus some existing bundle such as the\n[Felix implementation](http://felix.apache.org/documentation/subprojects/apache-felix-config-admin.html) \nof the OSGi Config Admin Service:\n\n```groovy\ndependencies {\n    compile group: 'org.osgi', name: 'org.osgi.enterprise', version: '5.0.0'\n    osgiRuntime group: 'org.apache.felix', name: 'org.apache.felix.configadmin', version: '1.9.22'\n}\n\nrunOsgi {\n    javaArgs = \"-Dexample.configFile=${file( 'config-example.properties' ).absolutePath}\"\n    bundles += project\n}\n```\n\nFrom the project's root directory, type:\n\n```\ngradle runOsgi\n```\n\nThis will create and run the OSGi environment during the Gradle build.\n\nAlternatively, you can just create the OSGi environment, then run it later using the run scripts created by osgi-run:\n\n```\ngradle createOsgiRuntime\n```\n\nThis will create an OSGi environment in the output directory, which by default is `build/osgi`.\n\nTo run it:\n\n```\ncd build/osgi\nchmod +x run.sh  # may be necessary in Linux/Mac\n./run.sh # In Windows, use 'run.bat' instead\n```\n\nOnce the framework starts, type ``lb`` to see all bundles installed and running.\nTo see a list of commands available, type ``help``.\nStop the OSGi framework by typing ``exit``, ``stop 0`` (stops the system bundle) or pressing `Ctrl+C`.\n\nNotice that you can include any artifact, such as Maven dependencies, in your bundle environment.\n\nThe default OSGi container is Apache Felix, but you can easily use Equinox and Knopflerfish as well.\n\nFor complete examples, continue reading the next sections or go straight to the samples in [osgi-run-test](osgi-run-test/).\n\n### Declarative Services Plugin\n\nIf you use OSGi Declarative Services, you should have a look at the `osgi-ds` plugin, which is part of the\n`osgi-run` core distribution.\n\nHere's an example of how you can use it:\n\n```groovy\napply plugin: 'com.athaydes.osgi-ds'\n\ndeclarativeServices {\n    declarations {\n        component( name: 'classTrieMessageBus' ) {\n            implementation( 'class': 'com.athaydes.osgi.ds.ClassTrieMessageBus' )\n            service {\n                provide( 'interface': 'com.athaydes.osgi.messaging.MessageBus' )\n            }\n        }\n    }\n}\n```\n\nFor more information, have a look at the [DS Plugin Demo](osgi-run-test/declarative-services-demo).\n\n### Handling start levels\n\nIf your OSGi bundles for any reason need to start in a defined order you can benefit from Start Levels\ndefined by OSGi Core specification. Currently, the implementation works for Equinox and Felix only.\n\nThere are 2 ways to define specific start levels for your bundles:\n\n#### Start level for a dependency\n\nInside the `dependencies` block, you can use the `osgi` method as follows\n\n```groovy\ndependencies {\n    osgiRuntime osgi(group: \"some.group.id\", name: \"some-artifact-id\", version: \"version\", startLevel: 3)\n    \n    // or using the shorter notation\n    osgiRuntime osgi('some.group.id:some-artifact-id:version:3')\n}\n```\n\n#### Start level for a bundle\n\nIf you specify your bundles using the `runOsgi.budles` property, you can use the following syntax:\n\n```groovy\nrunOsgi {\n    bundles = [\n        [dependency: 'group:artifact:version', startLevel: 3],\n        \n        // or using the shorter notation\n        [dependency: 'group:artifact:version:3'],\n    ]\n}\n```\n\n## Tasks\n\n  * ``createBundlesDir``: create the bundles directory with all the configured bundles.\n    This task depends on the ``jar`` task of the project and its sub-projects.\n  * ``createOsgiRuntime``: create the OSGi runtime based on configuration provided (or the defaults).\n    **This task depends on ``createBundlesDir`` and is the main task of this plugin.**  \n  * ``runOsgi``: starts the OSGi runtime (depends on ``createOsgiRuntime``). Useful for debugging purposes.\n  * ``cleanOsgiRuntime``: deletes the `outputDir` directory.\n  \nNotice that Gradle lets you write the shortest unambiguous task name possible, so instead of using the full name of\na task, say `createOsgiRuntime`, you can just do `gradle crOsgi` and Gradle will get it.\n\nThe `cleanOsgiRuntime` task will make any existing `clean` task (normally added by the Java plugin)\ndepend on itself, so you just need to type `gradle clean` to obliterate the OSGi runtime.\n\n## Configuring osgi-run\n\n`osgi-run` accepts the following configuration:\n\n  * ``runOsgi``: allows configuration of the OSGi runtime.\n    It contains the following settable properties (all properties are optional):\n    \n    * ``configSettings``: String, one of ``['equinox', 'felix', 'knopflerfish', 'none']`` (default ``\"felix\"``).\n        This is used to generate a default config file for the OSGi container selected and affects the\n        defaults used for most other properties. **Always make this the first property you declare** otherwise\n        it will overwrite other properties with the default values for the container selected.\n        Set to ``none`` if you want to provide your own config file.  \n        You can configure several environments and select which to use by passing a Gradle property, e.g. `gradle runOsgi -Pequinox`.\n        See the [build-with-subprojects](osgi-run-test/build-with-subprojects) example.\n    * ``outDir``: output directory (default: ``\"osgi\"``).\n        Can be a String (relative to the project ``buildDir``) or a File (used as-is).\n    * ``bundles``: Bundles to include in the OSGi environment \n        (defaults: in Felix and Equinox: ``runOsgi.FELIX_GOGO_BUNDLES``, in Knopflerfish: ``[]``).\n        Each item can be anything accepted by ``Project.files(Object... paths)``.\n    * ``osgiMain``: Main OSGi run-time \n        (default: ``FELIX``, set to ``EQUINOX``, or ``KNOPFLERFISH`` depending on `configSettings`).\n        Accepts anything accepted by ``Project.files(Object... paths)`` or a `URI` pointing to the framework jar.\n    * ``javaArgs``: String with arguments to be passed to the java process (default: ``\"\"``).\n    * ``programArgs``: String with arguments to be passed to the main Java class (main args).\n    * ``bundlesPath``: String with path where the bundles should be copied to \n      (default for Felix: ``\"bundle\"``, Equinox: ``\"plugins\"``, Knopflerfish: ``\"jars\"\"``).\n    * ``config``: Map of properties that should be added to the container's config file.\n        This property is ignored if `configSettings` is set to 'none'.\n    * ``wrapInstructions``: instructions for wrapping non-bundles. See the relevant section below.\n    * ``excludedBundles``: List of regular expressions to match against bundle file names\n        which must not be added to the OSGi runtime. Defaults to `[ 'osgi\\\\..*', 'org\\\\.osgi\\\\..*' ]`.\n    * ``copyManifestTo``: Copies the bundle's Manifest to the given location.\n        This is useful to keep an up-to-date, auto-generated version of the Manifest in a location\n        where the IDE can use it to provide OSGi support.\n\nThe default `config` for Felix is:\n\n\u003e If a `startLevel` is defined for any bundle, then the config file will\n  list all bundles in the environment specifying the start-level as applicable, similarly to the Equinox config file.\n     \n```groovy\n'felix.auto.deploy.action'  : 'install,start',\n'felix.log.level'           : 1,\n'org.osgi.service.http.port': 8080,\n'obr.repository.url'        : 'http://felix.apache.org/obr/releases.xml'\n```\n\nThe default `config` for Equinox is (notice `osgi.bundles` is set dynamically based on the `bundles` property:\n\n```groovy\neclipse.ignoreApp : true,\nosgi.noShutdown   : true,\nosgi.bundles      : [bundle1-location@start,bundle2-location@start,...]\n```\n\nThe default `config` for Knopflerfish is (notice `bundle-1` and `fragment-1` are actually derived from\nthe `bundles` property):\n\n```groovy\n-Dorg.knopflerfish.framework.main.verbosity  =  0\n-Forg.knopflerfish.framework.debug.resolver  =  false\n-Forg.knopflerfish.framework.debug.errors  =  true\n-Forg.knopflerfish.framework.debug.classloader  =  false\n-Forg.osgi.framework.system.packages.extra  =  \n-Forg.knopflerfish.startlevel.use  =  true\n-init   \n-launch   \n\n-istart $bundle-1\n-install $fragment-1\n```\n\n\u003e Notice that to use Knopflerfish, you need to add its Maven Repository to your build file.\n\u003e See the [Knopflerfish Demo](osgi-run-test/using-knopflerfish) for a working example.\n    \nThe following constants can be used to provide values for the above properties:\n    \n* ``FELIX``: the Apache Felix main jar. Can be used to set ``osgiMain``.\n* ``FELIX_GOGO_BUNDLES``: the Felix Gogo bundles. Can be used with ``bundles``.\n* ``EQUINOX``: The Eclipse Equinox main jar. Can be used to set ``osgiMain``.\n* ``KNOPFLERFISH``: The Knopflerfish Framework jar. Can be used to set ``osgiMain``.\n\nHere's an example setting most properties (notice that normally you won't need to set nearly as many):\n\n```groovy\nrunOsgi {\n    configSettings = 'equinox'            // use Equinox's config file instead of Felix's\n    osgiMain = 'org.eclipse.osgi:org.eclipse.osgi:3.7.1' // use a specific version of Equinox\n    javaArgs = '-DmyProp=someValue'       // pass some args to the Java process\n    programArgs = '-console'              // pass some arguments to the Equinox starter\n    bundles += allprojects.toList() + 'my:custom-bundle:1.0' // bundles are: this project + subprojects + custom bundle\n    config += [ 'osgi.clean': true ]      // add properties to the Equinox config\n    outDir = 'runtime'                    // the environment will be built at \"${project.buildDir}/runtime\"\n    copyManifestTo file( 'auto-generated/MANIFEST.MF' ) // make the manifest visible to the IDE for OSGi support\n}\n```\n\n### The syntax of the `bundles` property\n\nThe `bundles` property takes a List with items having the following formats:\n\n* a `String` with the format of any Gradle dependency declaration.\n* a `Project` as in `bundles = [project]` or `bundles = subProjects`.\n* a `Map` with the following entries:\n    * `dependency` (mandatory): String or Map dependency declaration.\n    * `transitive` (optional, defaults to `true`): whether or not to include transitive dependencies.\n    * `exclusions` (optional): transitive dependencies to exclude, specified as Map: `[group: 'xxx', module: 'xxx']`. \n    * `startLevel` (optional): start level for the bundle.\n\n## Gradle configurations additions\n\n`osgi-run` adds the following Gradle configurations to the project:\n\n  * ``osgiMain``: same as the ``runOsgi.osgiMain`` property, but declaring this configuration in a project's\n      ``dependencies`` overrides that property. \n      It is preferrable to use that property over this configuration.\n  * ``osgiRuntime``: has the same purpose as the ``runOsgi.bundles`` property.\n      Both the property and the configuration are applied.\n      Notice that properties and configurations, by default, consider all transitive dependencies of the bundles/jars.\n      Non-bundles (simple jar) are wrapped into OSGi bundles automatically by default.\n      If you do not want any transitive dependency of an artifact to be included in the OSGi runtime, you can do:\n  * ``systemLib``: system libs which should be added to the runtime not as bundles, but as simple jars in the system\n      classpath. All system libs are excluded automatically from the bundle directory and export all their packages\n      as system packages (using the `org.osgi.framework.system.packages.extra` config property).\n      \n```groovy\ndependencies {\n    // all your usual dependencies\n    ...\n    \n    osgiRuntime( \"your:dependency:1.0\" ) {\n        transitive = false // transitive dependencies not included in OSGi runtime\n    }\n}\n```\n\n### Wrapping non-bundles (flat jars)\n\nIf any of the artifacts you include in the OSGi environment are not OSGi bundles\n(ie. they are flat jars which do not contain OSGi meta-data), they will be automatically\nwrapped by `osgi-run` into OSGi bundles which export all of their contents.\n\nThis allows you to use any Java artifact whatsoever, so you are not limited to only OSGi bundles.\n\nThe actual wrapping is done by [Bnd](http://www.aqute.biz/Bnd/Bnd).\n\nIf you want to provide extra meta-data for ``Bnd`` to improve the wrapping results, you can use\n`wrapInstructions` as follows:\n\n```groovy\nrunOsgi {\n    bundles += project\n\n    wrapInstructions {\n        // use regex to match file name of dependency\n        manifest( \"c3p0.*\" ) {\n            // import everything except the log4j package - should not be needed\n            instruction 'Import-Package', '!org.apache.log4j', '*'\n            instruction 'Bundle-Description', 'c3p0 is an easy-to-use library for making traditional ' +\n                    'JDBC drivers \"enterprise-ready\" by augmenting them with functionality defined by ' +\n                    'the jdbc3 spec and the optional extensions to jdbc2.'\n        }\n    }\n}\n```\n\nThe example above is used in the [quartz-sample](osgi-run-test/quartz-sample) \nto provide extra meta-data for wrapping the `c3p0` jar, which is required by the `Quartz` bundle.\n\n### System Libs\n\nIf the library you want to use cannot work within the OSGi environment even as a wrapped bundle (as discussed above),\nthen you have only one option: add your jar to the system classpath by making it a system lib.\n\nIn short, system libs allow you to run some parts of your application in a regular Java environment (single classpath),\nwhile others run inside the OSGi container, allowing you to benefit from both worlds.\n\nYou get the modular design and awesome features of OSGi where you want it, but can still benefit from any JVM component\nwhatsoever.\n\nFor example, if you want to add [Frege](https://github.com/Frege/frege) (Haskell in the JVM) scripting to your OSGi \napplication, you'll find that [it's basically impossible](https://github.com/Frege/frege-interpreter/issues/31) \nbecause it uses its own complex classloader to load modules.\n\nHowever, by turning the Frege REPL into a system lib, it will start just as if it were in a regular Java application:\n\n```groovy\ndependencies {\n    systemLib 'org.frege-lang:frege-repl-core:1.2'\n}\n```\n\nAll your bundles will be able to import and use the packages provided by Frege's regular jars. \n\nSee the [frege-as-system-lib](osgi-run-test/frege-as-system-lib) sample for a working example.\n\n## More usage examples\n\nThe best way to understand how you can configure your OSGi runtime is through examples.\n\nLet's have a look at some common use-cases:\n\n#### Use your Gradle project itself as a bundle\n\n```groovy\nrunOsgi {\n  bundles += project\n}\n```\n\nAs ``FELIX_GOGO_BUNDLES`` is the default value of ``bundles``, the above is equivalent to:\n\n```groovy\nrunOsgi {\n  bundles = FELIX_GOGO_BUNDLES + project\n}\n```\n\nIf you don't want the default bundles installed, just use:\n\n```groovy\nrunOsgi {\n  bundles = [ project ]\n}\n```\n\n#### Use Gradle sub-projects as bundles\n\n```groovy\nrunOsgi {\n  bundles += subprojects\n}\n```\n\n#### Use Maven artifacts as runtime bundles\n\n```groovy\ndependencies {\n  // add all the Apache Felix Gogo bundles to the OSGi runtime\n  osgiRuntime 'org.apache.felix:org.apache.felix.gogo.runtime:1.1.4'\n  osgiRuntime 'org.apache.felix:org.apache.felix.gogo.jline:1.1.8'\n  osgiRuntime 'org.apache.felix:org.apache.felix.gogo.command:1.1.2'\n}\n```\n\n##### Solving *unresolved constraint* errors\n\n###### Including Apache Commons Logging 1.1.1 into your OSGi environment\n\nAs another example, suppose you want to run the  [PDF Box library](http://pdfbox.apache.org) in an OSGi environment.\nThat seems pretty easy, as PDF Box jars are already OSGi bundles!\nSo you might expect that it should just work if you declare a dependency to it:\n\n```groovy\ndependencies {\n    compile 'org.apache.pdfbox:pdfbox:1.8.6' // won't work\n}\n```\n\nHowever, when you do ``gradle clean runOsgi``, you will find out it requires Apache Commons Logging at run-time\n(which will be automatically wrapped as a bundle by `run-osgi`), but this jar itself requires other things:\n\n```\n(org.osgi.framework.BundleException: Unresolved constraint in bundle org.apache.pdfbox.fontbox [2]: \n  Unable to resolve 2.0: missing requirement [2.0] osgi.wiring.package; \n  (osgi.wiring.package=org.apache.commons.logging) \n  [caused by: Unable to resolve 1.0: missing requirement [1.0] osgi.wiring.package;\n  (osgi.wiring.package=javax.servlet)])\n```\n\nTo understand why `osgi-run` could not figure out we needed not only commons-logging, but also some bundle to\nprovide `javax.servlet`, let's ask Gradle to show us the dependencies of our module:\n\n```\ncompile - Compile classpath for source set 'main'.\n+--- org.osgi:org.osgi.core:4.3.1\n\\--- org.apache.pdfbox:pdfbox:1.8.6\n     +--- org.apache.pdfbox:fontbox:1.8.6\n     |    \\--- commons-logging:commons-logging:1.1.1\n     +--- org.apache.pdfbox:jempbox:1.8.6\n     \\--- commons-logging:commons-logging:1.1.1\n```\n\nAs you can see, it looks as if the commons-logging dependency had no dependencies at all. So `osgi-run`\nhas no way of knowing there are other needs for commons-logging to work.\n\nInspecting the POM file of commons-logging reveals what's going on... it declares several optional dependencies:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003elog4j\u003c/groupId\u003e\n  \u003cartifactId\u003elog4j\u003c/artifactId\u003e\n  \u003cversion\u003e1.2.12\u003c/version\u003e\n  \u003coptional\u003etrue\u003c/optional\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003elogkit\u003c/groupId\u003e\n  \u003cartifactId\u003elogkit\u003c/artifactId\u003e\n  \u003cversion\u003e1.0.1\u003c/version\u003e\n  \u003coptional\u003etrue\u003c/optional\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003eavalon-framework\u003c/groupId\u003e\n  \u003cartifactId\u003eavalon-framework\u003c/artifactId\u003e\n  \u003cversion\u003e4.1.3\u003c/version\u003e\n  \u003coptional\u003etrue\u003c/optional\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003ejavax.servlet\u003c/groupId\u003e\n  \u003cartifactId\u003eservlet-api\u003c/artifactId\u003e\n  \u003cversion\u003e2.3\u003c/version\u003e\n  \u003cscope\u003eprovided\u003c/scope\u003e\n  \u003coptional\u003etrue\u003c/optional\u003e\n\u003c/dependency\u003e\n```\n\nSo this is one case where we need to add a little meta-data by hand.\n\nBut that's easy, knowing that we probably won't be needing servlets or the Avalon Framework and the other Apache\ndependencies, we can simply tell `osgi-run` that these packages should not be imported at all:\n\n```groovy\nrunOsgi {\n    bundles += project\n\n    wrapInstructions {\n        manifest( /commons-logging.*/ ) {\n            instruction 'Import-Package', '!javax.servlet,!org.apache.*,*'\n        }\n    }\n}\n```\n\nThe wrap instruction tells `run-osgi` that the commons-logging bundle should not import the packages \n`javax.servlet` and `org.apache.*` (notice that you may use wildcards), but should import everything else that is\n required when wrapped into an OSGi bundle. \n\nA working project demonstrating this can be found in the [Installing non-bundles demo](osgi-run-test/installing-non-bundles)).\n\n###### Using Groovy's SwingBuilder inside an OSGi environment\n\nFor yet another example, let's consider a bundle which uses Groovy to create a Swing UI.\nUsing Groovy's `SwingBuilder`, writing UIs is pretty easy! However, if you try to start your bundle, you will be greeted by\na really horrible error at runtime:\n\n```\n... 42 more    (too long to show the rest)\nCaused by: java.lang.ClassNotFoundException: sun.reflect.ConstructorAccessorImpl\n not found by groovy-all [6]\n        at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDele\ngation(BundleWiringImpl.java:1550)\n        at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringIm\npl.java:77)\n...\n```\n\nNothing is more annoying than these runtime ClassNotFoundException's you get in OSGi, especially when\nthe offending class is clearly part of the JRE!\n\nFor cases like this, there's an easy fix... Just add the package of the class that cannot be found to OSGi's\n**extra system packages**:\n\n```groovy\nrunOsgi {\n    config += [ 'org.osgi.framework.system.packages.extra': 'sun.reflect' ]\n}\n```\n\nTODO rewrite `IPojo-DOSGi Demo` without IPojo as IPojo has not been maintained for many years.\n\nDone! Now you can use the `SwingBuilder` without any concern.\nAnd you can see an actual working demo in the [IPojo-DOSGi Demo](osgi-run-test/ipojo-dosgi), which includes a\n`SwingBuilder`-created UI in bundle `code-runner-ui`.\n\n#### Using Equinox as the OSGi container\n\nSimplest possible Equinox setup:\n\n```groovy\nrunOsgi {\n  configSettings = 'equinox'\n}\n```\n\nNotice that this will only start the Equinox Framework with the default bundles deployed.\nYou can install bundles manually using the [Gogo Shell](https://felix.apache.org/documentation/subprojects/apache-felix-gogo.html)\n(which is currently used by both Felix and Equinox).\n\nBut if you want to **deploy some bundles automatically** (your subprojects, for example) to your OSGi environment,\ntry something like this:\n\n```groovy\nrunOsgi {\n  configSettings = 'equinox'\n  bundles = subprojects\n}\n```\n\nThis will deploy and start all your bundles (subprojects) when you run ``gradle runOsgi``.\nThis is done through the ``configuration/config.ini`` file which is generated automatically by ``osgi-run``.\nIf you do not wish to use this behavior, just set ``configSettings`` to ``\"none\"`` and copy your own config file\nto ``\"${runOsgi.outDir}/\u003cconfigFileLocation\u003e\"``.\n\n#### Using a different version of Felix/Equinox or another OSGi container\n\nIf you want to declare exactly which version of Felix or Equinox (or you want to use some other OSGi container) you want\nto use, you can set ``runOsgi.osgiMain`` to the artifact coordinates of the container.\n\n##### Using an older/newer version of Apache Felix\n\n```groovy\ndef felixVersion = '7.0.3' // or some other version\n\nrunOsgi {\n  osgiMain = \"org.apache.felix:org.apache.felix.main:$felixVersion\"\n}\n```\n\n##### Using an older/newer version of Equinox\n\n```groovy\n// find the URI of the latest Equinox jar at https://download.eclipse.org/releases/\ndef equinoxJar = URI.create( 'https://download.eclipse.org/releases/2021-12/202112081000/plugins/org.eclipse.osgi_3.17.100.v20211104-1730.jar' )\n\nrunOsgi {\n  configSettings = 'equinox'\n  programArgs = '-console'\n  osgiMain = equinoxJar\n  bundles = [] // do not use the default bundles, older Equinox has its own console\n}\n```\n\n##### Using another OSGi framework implementation\n\nJust point to a runnable artifact which can start up your framework of choice, Knopflerfish, for example:\n\n```groovy\nrepositories {\n  maven {\n    url 'https://www.knopflerfish.org/releases/6.1.4/maven2/'\n  }\n}\n\nrunOsgi {\n  configSettings = 'none'\n  osgiMain = \"org.knopflerfish.kf6:framework:8.0.11\"\n  bundles = subprojects // your bundles \n}\n```\n\n### External Links\n\n* [Apache Felix](https://felix.apache.org/)\n* [Felix Gogo](https://felix.apache.org/documentation/subprojects/apache-felix-gogo.html)\n* [Equinox Framework](https://www.eclipse.org/equinox/)\n* [Equinox Quickstart](https://www.eclipse.org/equinox/documents/quickstart-framework.php)\n* [Equinox runtime options](https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html)\n* [Knopflerfish](https://www.knopflerfish.org/)\n* [D-OSGi Demo Walkthrough](https://cxf.apache.org/distributed-osgi-greeter-demo-walkthrough.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenatoathaydes%2Fosgi-run","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenatoathaydes%2Fosgi-run","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenatoathaydes%2Fosgi-run/lists"}