maven icon indicating copy to clipboard operation
maven copied to clipboard

Provided dependencies in consumer POM

Open Vampire opened this issue 1 month ago • 9 comments

Affected version

4.0.0

Bug description

I've read at maven.apache.org/whatsnewinmaven4.html, that the consumer POM only contains information about compile and runtime scoped dependencies.

But aren't provided dependencies also an important detail?

They are not considered during resolution. But it imho still is important information which dependencies a component expects to be present at runtime. I also know some projects that programmatically use this information from the POM to collect and verify that the necessary dependencies will be present at runtime, which will probably not work anymore, if the provided dependencies are not part of the consumer POM.

Vampire avatar Nov 15 '25 13:11 Vampire

@gnodet ping

cstamas avatar Nov 15 '25 13:11 cstamas

As you say, from the Maven perspective they are and were ignored. What tools do this inspection? Can you show an example?

cstamas avatar Nov 15 '25 13:11 cstamas

The cases where I know the information is used is proprietary closed-source, so I cannot share it, sorry

Vampire avatar Nov 15 '25 13:11 Vampire

These tools can continue doing this, but they should switch to build pom then. Consumer pom is being transformed on purpose. Otherwise maven cannot progress, with the model set in stone.

cstamas avatar Nov 15 '25 13:11 cstamas

@Vampire , Have you considered going with Gradle Module Metadata instead of provided scope? You could generate and publish the metadata even if you use Maven, you could add whatever info you need, and it would likely have a better API than the obscure provided.

The problem with going for provided for custom info is that provided is not extensible. You can't have two teams injecting different pieces of information into provided.

vlsi avatar Nov 15 '25 13:11 vlsi

These tools can continue doing this, but they should switch to build pom then.

But the build pom will not be published, will it? And even if it is, the tools at least have to be adapted to support both styles in parallel and also to recognize the cases.

Of course it can be reprogrammed and humans can also look into two places for the information. But imho it is important information for the consumer of a module which dependencies it expects to be present at runtime.

You might of course disagree and close this issue. I just wanted to have it thought and talked about, because I think it is important information and also will "break" existing tooling, and in a way that is silent, some of those checks will just be happy in the future as there are no provided dependencies listed anymore.

Consumer pom is being transformed on purpose. Otherwise maven cannot progress, with the model set in stone.

Of course, no doubt about it, I did not question that.

@Vampire , Have you considered going with Gradle Module Metadata instead of provided scope? You could generate and publish the metadata even if you use Maven, you could add whatever info you need, and it would likely have a better API than the obscure provided.

I can also put the information in a text file and publish that, that is not the point. We are talking here about Maven and about loosing imho important information from the build pom in the consumer pom, and that also existing tooling depends on currently and I want to make sure this is considered, even if decided against. In thus it is also not really relevant what I want to use for libraries I create. My concern is mainly about libraries I do consume and where I can no longer from the consumer POM directly see which dependencies it requires to be present at runtime.

I also don't know why provided should be obscure. In my mind it has a clear definition and meaning. The project needs those at runtime, for example if a library targets only running inside an app server and compiles against some classes that are available in the app server already. So at compilation time the libs are used, at runtime the runtime environment has to provide them.

The problem with going for provided for custom info is

Why custom info? This is not custom info put purely Maven-supported standard info. It will "just" be lost in the consumer POM with Maven 4.0.0 currently.

that provided is not extensible. You can't have two teams injecting different pieces of information into provided.

I totally do not get what you mean here. This is no different from compile or runtime or whatever, and the information is already there in the build pom, just gets lost in the consumer pom.

Vampire avatar Nov 15 '25 13:11 Vampire

Ok, I got corrected.

So far my experience with provided was provided servlet-api:servlet-api while in practice the runtime was weblogic.jar :) I'm not sure how would I one use that.

component expects to be present at runtime

There's module-info.java with a similar intention. There's OSGi set of manifest entries which mention per-package "requirement".

However, I wonder what would you do with a case when pom declares <provided>javax.servlet:javax.servlet-api</provided> while the runtime has its own jar with the same classes instead. How is that servlet-api useful then? It might be servlet-api should be <scope>compile</scope> (as the classes probably implement Servlet or Filter).

Frankly, I would like to hear more on the use cases for provided. As for now, I somewhat like that Maven strips the pom for publication, so people do not accidentally depend on the implementation details.

vlsi avatar Nov 15 '25 15:11 vlsi

So far my experience with provided was provided servlet-api:servlet-api while in practice the runtime was weblogic.jar :)

That's quite possible, but not different to other cases like org.codehaus.groovy:groovy vs. org.apache.groovy:groovy. Or also javax.activation:activation, jakarta.activation:jakarta.activation-api, javax.activation:javax.activation-api, com.sun.activation:javax.activation, and com.sun.activation:jakarta.activation which all contain the classes for the Activation API. See also https://github.com/gradlex-org/jvm-dependency-conflict-resolution/blob/dc82f98dd33433906571d96dd1c9f9652d101f42/src/main/java/org/gradlex/jvm/dependency/conflict/detection/rules/CapabilityDefinition.java for other popular examples.

So yes, you cannot directly reason from provided coordinates to a jar. But in some cases it matches. In others you could have a manual mapping wich jar provides the classes of which other dependency. In yet other cases you could get the provided dependency, list all classes in there, list all classes in the runtime classpath and check whether the first is a subset of the second. There are many ways to use this information in a good way.

Vampire avatar Nov 15 '25 16:11 Vampire

I've read at maven.apache.org/whatsnewinmaven4.html, that the consumer POM only contains information about compile and runtime scoped dependencies.

This need to be update for rc-5 which does not flatten the Consumer POM by default anymore.

But aren't provided dependencies also an important detail?

They are not considered during resolution. But it imho still is important information which dependencies a component expects to be present at runtime. I also know some projects that programmatically use this information from the POM to collect and verify that the necessary dependencies will be present at runtime, which will probably not work anymore, if the provided dependencies are not part of the consumer POM.

The build POM are always published with a build classifier, but as they are. So if they are written with a different syntax, the original POM is published unmodified.

gnodet avatar Nov 17 '25 09:11 gnodet