bndtools / bnd

Bnd/Bndtools. Tooling to build OSGi bundles including Eclipse, Maven, and Gradle plugins.
https://bndtools.org
Other
532 stars 305 forks source link

-includeresource should support appending duplicate unrolled files in addition to overwriting (META-INF/services use case) #6325

Closed chrisrueger closed 2 weeks ago

chrisrueger commented 1 month ago

Scenario

The instruction -includeresource has various unroll options to add content from multiple jars to the resulting bundle jar.

e.g. the following line

@${repo;org.apache.xmlgraphics:fop-core;latest}!/META-INF/services/*,\

extracts the META-INF/services folder including all files into the resulting jar.

Problem to solve:

If two or more bundles contain the same filenames then the files in the resulting jar are overwritten (last one wins).

Proposed solution:

-includeresource should allow to specify a duplicate-strategy so that you can define what should happen with files with the same name:

@${repo;org.apache.xmlgraphics:fop-core;latest}!/META-INF/services/*
@${repo;org.apache.xmlgraphics:xmlgraphics-commons;latest}!/META-INF/services/*;:duplicates:=APPEND

Notice the duplicates:=APPEND in the last line. This should mean that when unrolling the second file all duplicated files in /services folder, their content should be appended to the existing file with the same name (instead of overwriting it)

Possible strategies could be:

Full Example

Consider the following bnd.bnd to wrap 4 bundles regarding Apache FOP. The problem is that FOP supports an extension mechanism via ServiceLoader in META-INF/services

To solve classloading issues a possible solution is to wrap all FOP-related jar files into a single bundle. BUT: Their META-INF/services need to be in the bundle root and basically need to be merged together, so that the bundle-classloader of the new resulting JAR can see them.

# bnd.bnd

Bundle-Version: 1.2.3
-includeresource: \
    @${repo;org.apache.xmlgraphics:fop-core;latest}!/*,\
    @${repo;org.apache.xmlgraphics:fop-util;latest}!/*,\
    @${repo;org.apache.xmlgraphics:fop-events;latest}!/*,\
    @${repo;org.apache.xmlgraphics:xmlgraphics-commons;latest}!/*,\
    @${repo;org.apache.xmlgraphics:fop-core;latest}!/META-INF/services/*,\
    @${repo;org.apache.xmlgraphics:xmlgraphics-commons;latest}!/META-INF/services/*;:duplicates:=APPEND,\

-metainf-services: auto

Notice the duplicates:=APPEND in the last line.

  1. fop-core.jar
    • contains a fileMETA-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreLoader with the content
org.apache.fop.image.loader.batik.PreloaderWMF
org.apache.fop.image.loader.batik.PreloaderSVG
  1. org.apache.xmlgraphics:xmlgraphics-commons.jar
    • contains a fileMETA-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreLoader with the content
org.apache.xmlgraphics.image.loader.impl.PreloaderTIFF
org.apache.xmlgraphics.image.loader.impl.PreloaderGIF
org.apache.xmlgraphics.image.loader.impl.PreloaderJPEG
org.apache.xmlgraphics.image.loader.impl.PreloaderBMP
org.apache.xmlgraphics.image.loader.impl.PreloaderEMF
org.apache.xmlgraphics.image.loader.impl.PreloaderEPS
org.apache.xmlgraphics.image.loader.impl.imageio.PreloaderImageIO
org.apache.xmlgraphics.image.loader.impl.PreloaderRawPNG

Goal:

Result should look like

wrap.jar/META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreLoader:

org.apache.fop.image.loader.batik.PreloaderWMF
org.apache.fop.image.loader.batik.PreloaderSVG
org.apache.xmlgraphics.image.loader.impl.PreloaderTIFF
org.apache.xmlgraphics.image.loader.impl.PreloaderGIF
org.apache.xmlgraphics.image.loader.impl.PreloaderJPEG
org.apache.xmlgraphics.image.loader.impl.PreloaderBMP
org.apache.xmlgraphics.image.loader.impl.PreloaderEMF
org.apache.xmlgraphics.image.loader.impl.PreloaderEPS
org.apache.xmlgraphics.image.loader.impl.imageio.PreloaderImageIO
org.apache.xmlgraphics.image.loader.impl.PreloaderRawPNG