2

In Java, there's the fairly ubiquitous notion of a POM file which provides the dependencies of your modules.

For example

https://repo1.maven.org/maven2/org/typelevel/cats-core_2.13/2.12.0/cats-core_2.13-2.12.0.pom

Something that has never made sense to me, is that these public files contain things with a 'test' scope, which define the dependencies used at test time by the modules creator. e.g.

<dependency>
<groupId>org.scalameta</groupId>
<artifactId>munit_2.13</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>

By why would I ever care? Yes I see that when some other module by the same creator uses this thing, they might like to be consistent with respect to the test dependencies used, but why should this be exposed to the public?

In my experience the sole things such dependencies accomplish is upset vulnerability scans. For sure just because e.g. cats-core used munit to test their code doesn't mean I have any interest in doing so.

2 Answers 2

3

There is absolutely no value. Indeed information not used in runtime is actively detrimental after deployment.

However, Maven is a very old and simple tool. It does not do any processing of POM file except effective POM computation. No information is stripped on deployment. All the garbage that was required to service the project reaches consumers of a final deployed POM.

Special effort is required to strip the information and deliver a sensible POM.

7
  • :( I really thought there would be a rationale. To make concrete to people a real problem that arises from this, you go to e.g. mvnrepository.com/artifact/com.squareup.okhttp3/okhttp/4.1.0 and it lists 4 'vulnerabilities from dependencies', but one of these 'vulnerabilities' is a test dependency. That being said, I have actually in trying to explain maven's decision come up with one rationale. If a library is tested with a vulnerable dependency, in principle that vulnerability could have changed the published class files (imagine at test runtime it mutates the class file). Commented Jul 1 at 22:34
  • 1
    @danielpurdew seems more an issue with how vulnerabilities are assigned. If wanted the respective scanner could easily skip test scope dependencies, so either somebody did not care or considers the test dependencies relevant. Commented Jul 2 at 18:48
  • @FrankHopkins exactly my point! I'm not sure we disagree. Either the dependencies genuinely are relevant (hence my original question), or they didn't care, in which case the dependencies being included in the pom has been actively detrimental, as its allowed this situation to happen of someone caring about something they were supposed to care about, which is exactly why you don't expose things to the public that the public aren't supposed to care about (because someone will come along and care about it). Commented Jul 2 at 19:07
  • @danielpurdew no my view is different: Adding them gives the choice to include them in a security analysis. Not adding them prevents this. If considering them in a security analysis is a problem, then the part where they are considered is the primarily problematic one. Sure, if they wouldn't be there this couldn't be an issue, but I'm not convinced having them available for analysis is detrimental. I would rather have the overview that lists the CVEs make it clear those are in the tests - so I can also decide whether I care when using the module. Commented Jul 2 at 19:10
  • @danielpurdew and yes, sometimes limiting information is a good choice, I don't see strong arguments here for it - at least on this front (deployment information and SCM information etc I would see a stronger argument). A counter-argument if the pom file is used for both uses would be that you don't want to overcomplicate it and confuse people by having the published pom file look different than the original one. I guess an optimal "approach" would have been to clearly separate both into clearly different files, say a .build and .public-descriptor file (not like this but you get the idea) Commented Jul 2 at 19:15
3

When I checkout the source code of a project and I want to compile and test it, this tells maven that it needs to pull munit_2.13 to run the test stage. Without the dependency the test likely would not work and I could not verify the code is fine and does what it should.

However, the fact that it is marked as test scope also means that the dependency is not needed for simple compilation and execution of the project. Thus if I simply want to run it, it would be no problem if I had no access to munit_2.13.

Furthermore, this means that a) derived projects won't need munit_2.13 and thus no dependency conflicts with this library "just" needed to run the tests can occur. And b) projects generating a super-jar that contains all dependencies won't include the munit_2.13 artifact thus resulting in smaller jar files, lower download and deployment costs for resulting jars, less main memory usage when running such a jar file and potentially lower bootup time. Similar arguments hold when you compile natively and run a derived program without forming a super-jar.

So specifying the scope makes it possible to only require the dependency when it is actually needed (i.e. when someone wants to build and run the tests).

If the question is primarily why this is published as part of the pom file in central repositories, then the answer most likely is "because no one bothered to filter it out" and because the pom file serves multiple purposes - to describe how to build the project as well as how to integrate the project in external projects and the respective information has not been deemed harmful to warrant explicit removal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.