views:

131

answers:

5

Using Apache Felix, I have an OSGi component I've authored that wraps some middleware my company uses. Currently it depends on a good number of external libraries, and I appear to have run into a limit on the Bundle-classpath: parameter length. I've had to rename libraries such as commons-collections.jar to ccoll.jar.

I'm curious if anyone has any advice on working around this limitation?

Bundle-ClassPath: .,lib/log4j.jar,lib/cvfs.jar,lib/backport.jar,lib/cbeanutils.jar,lib/ccodec.jar,lib/ccoll.jar,lib/chttp.jar,lib/cjxpath.jar,lib/clang.jar,[libs redacted],lib/saaj-api.jar,lib/saaj-impl.jar,lib/Schemas.jar,lib/xbean.jar,lib/clog.jar,lib/dom4j.jar,lib/xml-apis.jar,lib/xerces.jar,lib/xalan.jar,lib/jaxp-ri.jar,lib/japi.jar,lib/mail.jar

I suppose I could get more characters by leaving off the lib/ bits, but I'm curious if this is a bug, a defined limitation, or just simply idiocy on my part.

+6  A: 

Manifest line lengths are limited to 72 bytes as stated in http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html. After that you will have to split the line and start a new one beginning with a space character. In this case:

Bundle-ClassPath: .,lib/log4j.jar,lib/cvfs.jar,lib/backport.jar,lib/cbea
 nutils.jar,lib/ccodec.jar,lib/ccoll.jar,lib/chttp.jar,lib/cjxpath.jar,l
 ib/clang.jar,[libs redacted],lib/saaj-api.jar,lib/saaj-impl.jar,lib/Sch
 emas.jar,lib/xbean.jar,lib/clog.jar,lib/dom4j.jar,lib/xml-apis.jar,lib/
 xerces.jar,lib/xalan.jar,lib/jaxp-ri.jar,lib/japi.jar,lib/mail.jar

Alternatively you could use a tool like BND that does things like this (and more) for you automatically.

Moritz
+3  A: 

Also, consider packaging third-party libraries in their own bundles, some are even osgi-ready.

Tassos Bassoukos
An example perhaps? I presume you can have a bundle without an Activator?
Chris Kaminski
Yes, Activator classes are optional. I was referring to f.e. commons-beanutils, the JAR of which is a ready-made bundle, as the proper headers are already set in the MANIFEST.MF.
Tassos Bassoukos
+2  A: 

There is, as Moritz says, a 72-byte limit per line.

The Java jar package includes code for writing manifests:

Manifest manifest = new Manifest();
Attributes attributes = manifest.getMainAttributes();
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
attributes
    .putValue(
        "Bundle-Classpath",
        "<snip>");
manifest.write(System.out);

Note: Manifest-Version is mandatory.

This produces the output:

Manifest-Version: 1.0
Bundle-Classpath: .,lib/log4j.jar,lib/cvfs.jar,lib/backport.jar,lib/cb
 eanutils.jar,lib/ccodec.jar,lib/ccoll.jar,lib/chttp.jar,lib/cjxpath.j
 ar,lib/clang.jar,[libsredacted],lib/saaj-api.jar,lib/saaj-impl.jar,li
 b/Schemas.jar,lib/xbean.jar,lib/clog.jar,lib/dom4j.jar,lib/xml-apis.j
 ar,lib/xerces.jar,lib/xalan.jar,lib/jaxp-ri.jar,lib/japi.jar,lib/mail
 .jar
McDowell
A: 

Have a look at http://wiki.apache.org/commons/CommonsOsgi for Apache-Commons OSGi ready libraries. Otherwise look at http://www.springsource.com/repository/app/ if they bundled your 3rd party library already.

Install these bundles independent and do not embed them in your bundle.

K. Claszen
A: 

First, never directly edit MANIFEST.MF. Edit it in a standard text file, for example mymanifest.txt, then pass to the jar command as follows:

jar cfm output.jar mymanifest.txt <other files>

The jar tool will then insert the line-wraps as necessary.

Better answer: use the Bnd tool by Peter Kriens to generate your manifest.

Also as other commenters have pointed out, it is much better to use these libraries as OSGi bundles. Sticking all of your dependencies into one bundle is kind of missing the point of OSGi.

Neil Bartlett