question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

for flat classpath should we try put dependencies in a separate directory by default?

See original GitHub issue

I saw this blog recently which was discussing why fat jars can be suboptimal: http://product.hubspot.com/blog/the-fault-in-our-jars-why-we-stopped-building-fat-jars

each build requires re-downloading all jars again; even when no dependencies change.

I wonder if there’s a way to promote base image sharing with flat classpath apps? e.g. if folks are doing CI/CD and doing lots of builds per day of the same microservice; most times its only the microservices’s code changing; the dependencies will rarely change. So it’d be awesome if one docker layer was the dependencies; then another docker layer was the apps jar. Then this would promote docker caching.

I wonder if we could implement this by default by using a dependencies folder? e.g. for microservice foo we create an install like this…

/app
  foo.jar
  dependencies/
     jackson-core-2.7.4.jar
     ...

then the Dockerfile contains 2 ADD statements; one for the dependencies, one for the builds jar.

Then hopefully docker will try cache the dependency layer as much as possible; which will help speed up docker builds, pushes, pulls

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:10 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
jstrachancommented, Sep 30, 2016

how about if by default we always ADD the dependencies first in the generated Dockerfile; then we ADD the ‘skinny jar / war’ second? (If it makes things easier lets use 2 different folders for dependencies and the ‘skinny jar/war’)

Then when we build in interactive developer mode we calculate a hash/string of all the dependencies and versions; build the image as normal - then we figure out the docker layer (docker image ID) created by adding the dependencies. (This is the trickiest bit really).

Then when we do a second build, we see the hash/string and docker layer - see that dependencies haven’t changed; so the Dockerfile we generate ignores everything from the ‘ADD dependencies’ upwards and starts FROM the previous dependencies image and just does the ADD of the skinny jar/war. So we effectively split the generated Dockerfile logically into 2 parts; and only rebuild the first part if the dependencies change.

That way we don’t have to confuse the developer into creating 2 logical docker images for each build; we just reuse the docker layers. But it lets us optimise away having to jar up 50Mb of dependencies and POST them to docker just for docker to tell us its cacheable - when we know its cached as we previously built it 😉

0reactions
jstrachancommented, Oct 3, 2016

@chirino yeah it should totally work with docker or S2I binary builds; since its just an option to generate a smaller incremental Dockerfile that just uses the first clean build’s image output and then just copy the current project’s artefact

Read more comments on GitHub >

github_iconTop Results From Across the Web

What does it mean to have a flat classpath? - Stack Overflow
The goal is to isolate the dependencies of each bundle. You can even have conflicting versions of the same jar file in OSGi....
Read more >
Declaring dependencies - Gradle User Manual
Every dependency declared for a Gradle project applies to a specific scope. For example some dependencies should be used for compiling source code...
Read more >
Mastering Maven: Dependency Basics - Oracle Blogs
Welcome back to the Mastering Maven series. In this post we'll explore dependency resolution and its effects on a single project.
Read more >
4. Dependency Management - Gradle Beyond the Basics [Book]
You may have worked with a build that constructed the compile classpath for your compile step by blindly grabbing all the JAR files...
Read more >
Add build dependencies - Android Developers
The Gradle build system in Android Studio makes it easy to include external binaries or other library modules to your build as dependencies....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found