Skip to content

Add configuration to exclude provided dependencies for <goal>repackage</goal> #8005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jjroldan1 opened this issue Jan 17, 2017 · 7 comments
Closed
Labels
status: declined A suggestion or change that we don't feel we should currently apply

Comments

@jjroldan1
Copy link

We are building a framework that heavily relies in spring boot built modules (MODULE). We are trying to minimize the number of times that the dependencies get repackaged by using the scope provided as much as we can.

Modules are intended to be executed with the boot applications that are built with the ZIP which allow multiple modules to be loaded from outside of the boot application uber jar itself.

Thus, we think there is room for adding a exclude filter that will allow provided dependencies to be not included in the module jar. Please note that the current filters do not allow seamless removal of the transitive dependencies of the provided ones.

@jjroldan1 jjroldan1 reopened this Jan 17, 2017
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 17, 2017
@wilkinsona
Copy link
Member

What do you mean by "module"? Is it a jar that is to be used as a dependency? If so, I wouldn't recommend repackaging it at all.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Jan 17, 2017
@jjroldan1
Copy link
Author

I call module a jar created with the spring-boot-maven-plugin with module layout, a non-bootable uber jar with its dependencies embedded.

I have boot app built with <layout>ZIP</layout> that will load all the modules in runtime via org.springframework.boot.loader.PropertiesLauncher.

I expect a sizable amount of modules in my project, and some of the dependencies are designed to be provided by some specific modules (thus not needed in all of the other uber jar modules , i.e. Spring jars).

The implementation of this enhancement is pretty trivial. I have attached the necessary changes in the plugin (from master)

src.zip

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 17, 2017
@wilkinsona
Copy link
Member

Sorry, I still don't understand why you want to depend on modules that have been built as far jars. What benefit does that offer over using Maven's dependencies plugin to copy them all into a predictable location that can then be referenced by the properties launcher?

The implementation of this enhancement is pretty trivia

The complexity of the implementation is only one factor. We also have to consider the extra complexity that it introduces. It's another configuration option that we have to document and that users of the Maven plugin would have to understand. As things stand, I can't see any benefit over what Maven already offers.

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Jan 17, 2017
@jjroldan1
Copy link
Author

I don't want to depend, the modulles/jars are deployed on my runtime independently, and my boot application fetch them with the PropertiesLauncher.

The benefits of excluding the provided scope dependencies (via configuration) are:

  • the fat jars to grow bigger than they should.
  • reduce the chance of 3rd party libraries from different versions to make it to the runtime.

The current exclusion mechanism is focused only on regular bootable applications which need all the jars it depends on embedded on it to work (that's the only reason that I can think of to ignore the scope provided which have very clear semantics in maven, see war plugin, ear plugin). Furthermore, the mechanism currently implemented is very limited, as excluding a given artifact does not exclude its transitive dependencies as it would be expected but exclusively the artifact that is configured, you have to configure all of the transitive dependencies one by one if you want them gone! I cannot ask the users of my framework to do that, it does not make any sense.

As I see it, it's a must have enhancement in order to use the module layout.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 17, 2017
@wilkinsona
Copy link
Member

The current exclusion mechanism is focused only on regular bootable applications which need all the jars it depends on embedded on it to work

Correct. That's because that's the use case that fat jars aim to address. As far as I can tell you are using a fat jar in a way that isn't intended. We don't want to add extra complexity that affects everyone to addess something that's an unusual edge case.

excluding a given artifact does not exclude its transitive dependencies

That is intentional. Please see #6139, #3602, and #3426.

As you haven't really answered my questions, I still don't understand why you are determined to use fat jars for your particular use case. I don't think they're a good fit. If you want to reduce the chance of different versions of 3rd party libraries being used, then I think that dependency management is a better solution.

If you really want to use Boot's repackaging, then 1.5 introduces a completely pluggable layout mechanism that you can use to have precise control over the jar's contents and its launcher: http://docs.spring.io/spring-boot/docs/1.5.0.RC1/maven-plugin/examples/custom-layout.html.

@wilkinsona wilkinsona added status: declined A suggestion or change that we don't feel we should currently apply and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Jan 17, 2017
@jjroldan1
Copy link
Author

The idea is to deliver auto configured jars that include the dependencies which aren't known to be provided by other modules. Those modules are not to be repackaged again, they will be deployed to the runtime directly, so dependency management is not an option. In the current implementation, if I have a number of very simple modules which use the spring boot starter pom for example, each of them will repack a dozen jars, time and again, even when I know they are going to be provided by one of the modules. I can, to some extent, agree that ignoring the scope provided is fine for bootable jars, but it is not right for the module layout, for sure not even offering the option to honor the scope as one would expect.

Correct. That's because that's the use case that fat jars aim to address. As far as I can tell you are using a fat jar in a way that isn't intended. We don't want to add extra complexity that affects everyone to addess something that's an unusual edge case.

Sure, if you don't plan to enhance it, you may consider removing the complexity of the module layout altogether. People might be tempted to use it to build complex software with it :)

Thanks for the tip, I will have a look at it.

@ernestojpg
Copy link

ernestojpg commented Oct 10, 2022

Hello!

I see a lot of tickets requesting this feature, and I think there are many use cases for it.

In my case, in trying to build a "plugins system" for my application. I was trying to package my plugins as "fat jars", using the "spring-boot-maven-plugin", as plugins can have dependencies and I want each plugin to be packaged together with its dependencies in a single .jar file.

As you can see, those .jar files will not be launched as normal java applications, with java -jar, but they will be loaded directly by the main application, using an isolated classloader. Obviously, I don't want to include in the plugin package some libraries that are provided in the main application classpath (loggers, jackson, etc), so I would like to exclude all of those "provided" dependencies. In my plugin pom.xml I have all those dependencies marked as "provided", so it would be very useful for me to be able to exclude them easily.

At the moment, I'm using the "maven-dependency-plugin", with the "dependency:copy-dependencies" goal to copy only the dependencies that I need. In particular, I'm using the option "excludeScope", which is quite flexible.

Cannot we have something like in the "spring-boot-maven-plugin"? It would be quite useful for many use cases.

Regards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

4 participants