jarjar
jarjar copied to clipboard
Shading native dependencies (or other resource files)
In some projects, such as Netty, the JAR files ship with native dependencies (e.g. META-INF/native/libnetty_tcnative.so
files). In order for shaded versions of such projects to coexist, the native dependencies must be renamed to avoid collisions. Netty supports this by prefixing the native library it looks for with a transformation of its current package path unless the package path matches its usual io.netty
(in which case the default native dependency name is used).
It would be incredibly convenient if jarjar could be used to rename the native dependency as a shading rule. Similar rules could be applied to resource files as well. I'm not sure if you would consider this in scope for jarjar or not. If this is something that could be done, I can look at submitting a pull request. I would appreciate it if you could offer some suggestions on how you would prefer to see this implemented.
Roughly I would expect at least to require:
- New shade rule for renaming resources
- Only permit resource to be renamed (e.g. non-class files)
- Offer no guarantees on renaming resource references
After reading more of the code and writing some unit tests it looks like you can get pretty close with a "hack" rule like this:
rule META-INF.native.* META-INF.native.libcom_example_shaded_RESOURCE
In such a rule, the RESOURCE
keyword is replaced with the current file name being mapped. For example, the rule above will rename META-INF/native/libnetty_tcnative.so
to META-INF/native/libcom_example_shaded_libnetty_tcnative.so
.
Unfortunately, in the case of the netty native library (at least) this does not solve the problem completely. Specifically, the lib
prefix needs to be removed from the original resource name prior to adding the prefix or looked at another way the new shading name component (e.g. com_example_shaded_
) needs to be inserted between existing lib
and netty_tcnative
name components.
It looks like a new rename rule like this would be simple and effective:
rename META-INF.native.libnetty_tcnative.so META-INF.native.libcom_example_shaded_netty_tcnative.so
Other rules that I have tried which do not work in this case are:
rule META-INF.native.lib* META-INF.native.libcom_example_shaded_@1
rule META-INF.native.lib** META-INF.native.libcom_example_shaded_@1