I realise this is more of a semantic quest rather than a functionality quest.
I have three types of compile-scope dependencies:
Compile-only scope, not used at run-time. GWT client-side dev, MVP4G, RestyGWT, Source retention annotation processors. I use REST, so I don't need GWT server side.
Provided - Hibernate jars required for compilation but provided by JBoss.
Compile + runtime jars.
For case 2, we could use provided scope. Case 3, we would use compile scope.
However for case 1, I use provided scope, even though JBoss does not provide those files at all. Nor are they needed at run-time.
Anyway, don't you think Maven should provide for a synonym for "provided" for a scope where the artefacts are not really needed except at compile time? Perhaps, should there be a "compile-only" scope?
There are two types of dependencies in Maven: direct and transitive. Direct dependencies are the ones that we explicitly include in the project. On the other hand, transitive dependencies are required by direct dependencies. Maven automatically includes required transitive dependencies in our project.
provided scope is only available on the compilation and test classpath, whereas compile scope is available in all classpaths. provided dependencies are not packaged.
compile This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.
Maven includes a dependency with this scope in the runtime and test classpaths, but not the compile classpath.
Don't complain that the language does not offer fine distinctions if you only know half its vocabulary.
If a dependency is only used for building, such as an annotation processor, it should be a maven <plugin>
, or <dependency>
thereof.
Otherwise, if it is in the compilation classpath, it will be necessary for linking the generated class file at runtime. Then, there are two cases:
<scope>compile</scope>
<scope>provided</scope>
<optional>true</optional>
The only option not covered is compiling a Java program, and never running it in a JVM. This is a really obscure use case, and I can't fault the designers of maven for not including a scope just to express this distinction - particularly since it is irrelevant to Maven's core responsibility (building the software).
If the jars with are not true "runtime" dependencies (only for building) but not for the final artifact, you can exclude them various means:
I agree that shipping unnecessary classes is annoying (I've seen junit and testng jars in production deployments - brrrr...), but for all practical purposes it's a rather minor one.
If you have a dependency conflict (i.e shipping a "all deps" version of a library or framework), that's a different story, but doesn't sound like what you're facing here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With