Bug 51096 - jar task, nested element "service" not merged
Summary: jar task, nested element "service" not merged
Status: NEW
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.8.1
Hardware: PC Linux
: P2 minor (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-20 13:06 UTC by Nam3l3ss
Modified: 2011-04-21 18:02 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nam3l3ss 2011-04-20 13:06:56 UTC
Using multiple services in different jar files, then using a single jar file, eg.

Let there be a service "X", and let there be providers Alpha,Beta,Gamma.

A.jar contains provider Alpha
B.jar contains provider Beta

C.jar provides provides Gamma, and includes A.jar and B.jar as zipfilesets.

I would except it to be possible to create C.jar in a way that the service descriptor files are merged, but this does not seem to be the case. With either of the jar task's manifest affecting options, the result is separate files in the archive, with the same filename.

From what I have seen so far, only the "duplicate" property affects the resulting descrpitor files, but it does not have the option to merge, so it's of no use.

When creating the jar file C.jar, there are (in case duplicate is not on "preserve") multiple entries of the same descriptor file, as the format allows this; however, the ServiceLoader only parses the first such file, causing failures in some of my applications.

My current workaround is simply to extract the jar files, manually rearrange the service descriptors, then repackage them.

Am I doing someting wrong? Is it possible to alter the build file so the service descriptors are merged?
Comment 1 Matt Benson 2011-04-20 13:32:08 UTC
Since the zip format does permit same-named entries, are you sure that C.jar isn't still capable of providing multiple service provider implementations despite these actually being represented in different jar entries?
Comment 2 Nam3l3ss 2011-04-21 17:47:10 UTC
I'm practically sure, but I'll create a presentable test case as soon as I have some time.
Comment 3 Jesse Glick 2011-04-21 18:02:18 UTC
(In reply to comment #1)
> Since the zip format does permit same-named entries, are you sure that C.jar
> isn't still capable of providing multiple service provider implementations
> despite these actually being represented in different jar entries?

sun.misc.URLClassPath.JarLoader.getResource can only return one resource, since it is using JarFile.getJarEntry. Iterating all entries would be inefficient, and there is no method in JarFile to get multiple entries with the same name.

Probably there is some way to write the script to concatenate META-INF/services/* entries from its inputs, but it does not sound easy. Maybe use a custom task - either a subclass of Zip which overrides zipFile and knows how to merge these entries, or set duplicate=add and then run a separate task to merge entries in the result.

In general it would be nice to have a helper type ResourceMerger, which you could pass to <zip>, <copy>, etc.; one impl could simply concatenate the incoming resources, but custom impls could perform more complex merges.