From Fedora Project Wiki

Introduction

OSGi bundles are JAR files containing Java bytecode along with meta-data similar to RPMs. This OSGi meta-data can be translated into RPM Requires and Provides similar to how it is done for perl or mono packages. This functionality exists in Fedora's rpm-4.7.0-8.fc12 (bz506471 ) and will be turned on by default in Fedora in the near future.

What this means for Fedora packagers

If your package contains OSGi bundles (JARs), RPM Requires and Provides will automatically be created at the end of the build. If your package does not contain OSGi metadata but another package needs an OSGi bundle of your package's contents, OSGi meta-data should be injected into your package's JAR META-INF/MANIFEST.MF files. While this does cause our packages to diverge from their various upstreams, it allows us to easily have a single copy of the bytecode (and JARs) on the installed system. Non-OSGi Java runtimes will simply ignore the OSGi meta-data. See below for an example of how to inject this meta-data. It is difficult to provide an example for every case as there are many different build systems in use. The requirement is just that JARs that get installed must have the appropriate OSGi properties in their META-INF/MANIFEST.MF files.

Example of injecting OSGi meta-data into an existing package

commons-el-eclipse-manifest.patch contains:

--- META-INF/MANIFEST.MF.orig	2007-07-11 12:47:24.000000000 -0400
+++ META-INF/MANIFEST.MF	2007-07-11 12:49:32.000000000 -0400
@@ -9,3 +9,16 @@
 Implementation-Title: org.apache.commons.el
 Implementation-Vendor: Apache Software Foundation
 Implementation-Version: 1.0
+Import-Package: javax.servlet;version="2.4",javax.servlet.http;version
+ ="2.4",javax.servlet.jsp;version="2.0",javax.servlet.jsp.el;version="
+ 2.0",javax.servlet.jsp.resources;version="2.0",javax.servlet.jsp.tage
+ xt;version="2.0",javax.servlet.resources;version="2.4"
+Bundle-ManifestVersion: 2
+Export-Package: org.apache.commons.el;version="1.0.0",org.apache.commo
+ ns.el.parser;version="1.0.0"
+Bundle-Version: 1.0.0.v200806031608
+Bundle-SymbolicName: org.apache.commons.el
+Bundle-Name: Apache Commons JSP 2.0 Expression Language Interpreter
+Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,J2SE-1.3
+Bundle-Localization: plugin
+Bundle-Vendor: Apache Software Foundation

and is applied as Patch1:

%prep
%setup -q -n %{short_name}-%{version}-src
%patch0 -p1 -b .license
pushd src/conf
%patch1 -p1
popd
...

TODO:

  • add example using ant
  • add example using maven (?)

osgideps.pl Details

  • it doesn't generate Provides for symlinks (these OSGi bundles are not contained in the package as only symlinks are provided).
  • it strictly Requires the file of symlink'd bundles (we ensure that we don't pull-in broken packages due to dead symlinks).
  • it strictly Requires files of symlink'd bundle defined by the Bundle-ClassPath header (an example of this are the symlinks to ant JAR files in the Eclipse packages).
  • it ignores system.bundle (since that's an alias that represents the OSGi framework itself).
  • it doesn't take care of optional dependencies.
  • it always generates the complete OSGi version to be able to match 1.0 and 1.0.0 as equal in RPM.

You can run the script (/usr/lib/rpm/osgideps.pl) manually on a set of JARs. See below for script options and example usage.

Options

-provides print provides of OSGi files (META-INF/MANIFEST.MF and .jar)

-requires print requires of OSGi files

-debug print file path (used with -provides or -requires)

-system print system bundle of OSGi .profile files

Example of script usage

Print OSGi required bundles of all jar files into the current directory :

ls -1  *.jar | /usr/lib/rpm/osgideps.pl -requires | sort -u

Print OSGi required bundles of all JAR files in /usr/share/java directory with the file path on the same line (useful to debug sub-package errors):

find /usr/share/java -name "*.jar" | /usr/lib/rpm/osgideps.pl -provides -debug

Generate provides of an OSGi .profile file:

ls -1 J2SE-1.6.profile | /usr/lib/rpm/osgideps.pl -s | sed "s/^osgi/Provides\:\tosgi/g"