manifest first OSGi build with gradle - migrating from ant to Gradle
Asked Answered
T

2

27

Is there manifest first http://wiki.osgi.org/wiki/Tooling_Approaches gradle plugin for OSGi? Or how to do it with gradle?

There's big old project for OSGi container with many project having complicated relation declared in MANIFEST.MF. The build is long. Now we want to simplify things and adopt Gradle. But first without breaking things and keeping ant and gradle builds in parallel for some time. However what I see is gradle suggesting define MANIFEST inside build.gradle. https://docs.gradle.org/current/userguide/osgi_plugin.html
That would make a lot of copy work.

UPDATE There are close to 100 modules with a lot of dependencies information between modules and for nested jar. On average MANIFEST.MF length is about 50 lines (varies from 20 to 300 lines). How to bundle nested jar's is other question. This question is about using existing MANIFEST.MF files. All plugins I saw use bnd that is exactly contrary to manifest first approach.

Tussis answered 25/2, 2016 at 14:20 Comment(9)
If you are writing your manifests by hand then you can pass them directly to the JAR task. Is there something more to it that I'm missing?Gamin
How to pass existing MANIFEST.MF file to jar task? I see as now the only way is to copy information from MANIFEST.MF into build.gradle jar section, that is huge monkey work. Those files may change before gradle build will start working and accepted as main delivery method.Tussis
I don't have enough Gradle knowledge to answer. The jar command from the JDK takes a manifest file using the -m switch, I would be very surprised if the Gradle task did not expose that option in some way.Gamin
This is about OSGi additional properties, that JDK can't know. And the question is can gradle read OSGi dependencies on other bundles (OSGi jars)Tussis
The JDK doesn't need to know. The jar command allows a predefined manifest to be supplied as a file. Quickly checking the Gradle docs, it looks like the Jar task has a manifest property that you can use. Something like Manifest.from(filename).Gamin
You gave me at least 2 ideas already. Great.Tussis
Are you stuck on Gradle? Why not use Maven. Then you can use the standard maven goals for creating osgi manifests etc.Beanpole
Because Gradle is better :) !Satiable
@Beanpole If you know Maven plugin that would solve reading dependencies information, please add as an answer. I could not find such plugin neither.Tussis
T
3

As of April 2016 there's no Manifest-first approach in Maven or Gradle build tools for OSGi.

While for Eclipse plugins (that are also valid OSGi bundles) there is maven/tycho build, that is standard within Eclipse Foundation, it is not really of help for general OSGi projects.

Oposite to Manifest-first is Manifest generation, and there is only one tool bnd, that initially was for manifest creation, then grew into full bundle jar builder and now has BndTools Eclipse integration, looking similar to Maven/Gradle integration managing dependencies.

I would recommend to keep bnd instructions in external standard bnd.bnd file and not to put it inside build script. *.bnd files are similar to usual Java .properties files, so in Eclipse IDE right-click, Open with -> Other ... select Properties File Editor check "Use this editor for.." and check "Use this editor for all '*.nbd' files"

For Gradle

For maven

All bnd-based tools are now collected on http://bnd.bndtools.org/chapters/700-tools.html

There are some examples in https://github.com/paulvi/OSGiBuildExamples

Note: link http://wiki.osgi.org/wiki/Tooling_Approaches has been in "The OSGi Community Wiki was unfortunately hacked and is currently unavailable. " status for more than a week, while this question was opened.

Sadly @Richard gave up too early to receive some thanks as well (for mentioning maven)

Tussis answered 6/4, 2016 at 13:10 Comment(0)
S
10

Gradle has an OsgiManifest class, which is an extended jar manifest:

https://docs.gradle.org/current/javadoc/org/gradle/api/plugins/osgi/OsgiManifest.html

There is a post on StackOverflow that shows similar usage:

How to add Import-Package instructions for runtime dependencies?

The relevant gradle block looks like this:

apply plugin: 'java'
apply plugin: 'osgi'

jar {
    baseName = 'awesome'
    manifest {
        name = 'An Awesome Application'
        symbolicName = 'com.example.awesome'
        instruction 'Import-Package', 'org.springframework.orm', '*'
    }
}

If you have existing manifests and would like to use your own custom files, you can do this by setting the manifest file location within the jar closure:

jar {
    manifest {
        def manif = "${resourcesDir}/MANIFEST.MF"
        if (new File(manif).exists()) {
            from file(manif)
        }
        else{
            name = 'overwrittenSpecialOsgiName'
            instruction 'Private-Package', 'org.mycomp.somepackage'
            instruction 'Bundle-Vendor', 'MyCompany'
            instruction 'Bundle-Description', 'Platform2: Metrics' 
        }
    }
}

The documentation for Gradle's manifest can be found here: https://docs.gradle.org/current/javadoc/org/gradle/api/java/archives/Manifest.html

For your 'other question':

There are additional Gradle plugins for building OSGI bundles, in some cases, including dependencies from other OSGI bundles.

For one example, there is the Gradle Bundle Plugin, which uses the bnd tool and allows you to specify to include transitive-dependencies and even exclude unwanted ones. As an example:

jar {
    manifest {
        attributes 'Implementation-Title': 'Bundle Quickstart',     // Will be added to manifest
                     'Import-Package': '*'  // Will be overwritten by the instuctions below
    }
}

bundle {
    includeTransitiveDependencies = true

    instructions << [
        'Bundle-Activator': 'foo.bar.MyBundleActivator',
        'Import-Package': 'foo.*',
        '-sources': true
    ]

    instruction 'Export-Package', '*' // Specify an individual instruction
    instruction '-wab', ''
}

There is also the Gradle osgi-run plugin, which includes transitive dependencies by default:

dependencies {
    // all your usual dependencies
    ...

    osgiRuntime( "your:dependency:1.0" ) {
        transitive = false // transitive dependencies not included in OSGi runtime
    }
}

Hopefully that's enough to get you going.

Satiable answered 28/3, 2016 at 5:17 Comment(5)
This is already nice answer (upvoted), but it does not address problem of taking all dependencies information, e.g. between modules, and what we have of nested jars.Tussis
Paul, your last comment. Is this related to solving the 'Other question' you have posted? I'm trying to get a clear picture of what exactly you want to help offer additional suggestions.Satiable
Once dependencies information is there, bundle can be built with or without nested jar's, that is other questions. At least for gradle build to be DONE, compilation should pass, i.e. all dependencies from MANIFEST.MF files should be visible to compiler. I am not expert of all possible dependencies declaration within MANIFEST, there are at least package and bundle dependencies.Tussis
Paul, I have added more information to the answer for a couple of other osgi plugins I found. However, I'm thinking (correct me if I am wrong) that what you may need is to use the default OSGI plugin, but after adding your 50+ OSGI modules as dependencies themselves (are they in a common lib?), then you are saying you need to then find information in each modules manifest to explicitly add each modules manifest declared dependencies to the general build classpath as well in order for your build to succeed. Thoughts or clarifications?Satiable
I am researching on my own, trying out all plugins found by osgi query. I have not tried yet osgi-run, the Gradle Bundle Plugin uses bnd, the wuff is monstrous and not updated for a while. What I need first is get off from ant build and get the same build result, before starting changes using new build tool.Tussis
T
3

As of April 2016 there's no Manifest-first approach in Maven or Gradle build tools for OSGi.

While for Eclipse plugins (that are also valid OSGi bundles) there is maven/tycho build, that is standard within Eclipse Foundation, it is not really of help for general OSGi projects.

Oposite to Manifest-first is Manifest generation, and there is only one tool bnd, that initially was for manifest creation, then grew into full bundle jar builder and now has BndTools Eclipse integration, looking similar to Maven/Gradle integration managing dependencies.

I would recommend to keep bnd instructions in external standard bnd.bnd file and not to put it inside build script. *.bnd files are similar to usual Java .properties files, so in Eclipse IDE right-click, Open with -> Other ... select Properties File Editor check "Use this editor for.." and check "Use this editor for all '*.nbd' files"

For Gradle

For maven

All bnd-based tools are now collected on http://bnd.bndtools.org/chapters/700-tools.html

There are some examples in https://github.com/paulvi/OSGiBuildExamples

Note: link http://wiki.osgi.org/wiki/Tooling_Approaches has been in "The OSGi Community Wiki was unfortunately hacked and is currently unavailable. " status for more than a week, while this question was opened.

Sadly @Richard gave up too early to receive some thanks as well (for mentioning maven)

Tussis answered 6/4, 2016 at 13:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.