jarjar icon indicating copy to clipboard operation
jarjar copied to clipboard

Shading native dependencies (or other resource files)

Open vjkoskela opened this issue 5 years ago • 1 comments

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

vjkoskela avatar May 22 '19 23:05 vjkoskela

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

vjkoskela avatar Jul 01 '19 15:07 vjkoskela