Thanks a lot for your answer. We create a separate container for each application, as it seemed like the correct approach. In our company we do have several "levels" of library (even jvm) version requirements. Containers have been very helpful to easy the pain that was managing that on the server side.
I've found that building fat JARs with all dependencies bundled solves a lot of the same dependency management issues containers can be used for. And it does it without container overhead.
That's what we do now: fat JARs, including all dependencies and use embedded app server. On top of that, we use docker containers so we can control de JVM version as well. The overhead is not that high and it gives us the benefit of knowing that the same container that the developer/jenkins tested is the one that passed QA and will run in production.
To update on this since I am a Java programmer who is picking up c again after 10 years:
In modern Java world people often maven or another project tool where upgrading a library is as simple as changing the version number in a "pom" file, push and wait for Jenkins to finish build, unit and integration tests.
Not kidding here, this is one of the things I love about Java development.