If your app is open source, or you're willing to buy a commercial tool, then you could try Conveyor from my company [1]. It will:
- Find all the shared libraries in your JARs or configured app inputs (files in your build/source tree)
- Sniff them to figure out what OS and CPU arch they are for
- Bundle them into the right package for each platform that it makes, in the right place to be found by System.loadLibrary()
- Sign them if necessary
- Delete them from the JARs now they are extracted. Optionally extract them from library JARs, sign them and then put them back if your library refuses to load the shared library from disk instead of unpacking it (most libs don't need this)
- JLink a bundled JVM for your app for each platform you target, using jdeps to figure out the right set of modules, and combine that with your shared libs.
When building Debian/Ubuntu packages it will also:
- Read the .so library dependencies, look up the packages that contain those other shared libraries and add package dependencies on those packages, so "apt install" will do the right thing.
So that makes it a lot easier to distribute Java apps that use native code.
[1] https://www.hydraulic.dev/