I'm trying to understand the specific need for runtime
scoped dependency in maven. In which situation I would need this, where neither compile
or provided
scope won't do?
For example, I would use compile
scope for dependency, when I have to call the library API directly in the code (compile against it) and package the dependency in the artifact or dependent project artifacts.
I would use provided
scope when I have to compile against the API, but don't package it (rather except it to be available at runtime).
But when would I need runtime
scope? Is this for situations, when I don't directly call the library API (rather use reflection), but want to package it inside the artifact? Why not just to use compile
scope? Is the only benefit faster compile time, or is there something other special in runtime
scope that couldn't be achieved or avoided with compile
scope?
All what you can do with the runtime
scope can be also done with the default scope : compile
.
So why use runtime
?
Because in some cases, this makes really sense and can make your build more robust.
A typical use case is ensuring that the client code doesn't use a specific implementation.
Suppose you build an application relying on an API packaged as a Maven dependency (my-service-api
) and the implementation of this API is packaged as another Maven dependency (my-service-impl
).
Suppose now you need to provide the implementation at the runtime in the built application but you don't want that the client code of your application refers directly the implementation.
By using the runtime
scope for my-service-impl
:
<dependencies>
<dependency>
<groupId>my-group</groupId>
<artifactId>my-service-api</artifactId>
</dependency>
<dependency>
<groupId>my-group</groupId>
<artifactId>my-service-impl</artifactId>
<scope>runtime</scope>
</dependency>
<dependencies>
As the compiler will never have the dependency in the classpath, you cannot create any coupling with the implementation in the client code of your application.
Client code will only see the API of the dependency :
By using the compile
scope for my-service-impl
:
<dependencies>
<dependency>
<groupId>my-group</groupId>
<artifactId>my-service-api</artifactId>
</dependency>
<dependency>
<groupId>my-group</groupId>
<artifactId>my-service-impl</artifactId>
</dependency>
<dependencies>
Things are different : you could by mistake reference implementation classes and so create an undesirable coupling with the implementation.
A known usage to favor runtime
scope is as you have to cope with a JDBC dependency of a specific DBMS (Oracle, PostgreSQL or whatever).
To write portable code, you don't want to allow the client code to refer to classes of this JDBC dependency but you want all the same include it in your application as at runtime the classes are needed to make the JDBC api works with this DBMS.
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