Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When would I need maven dependency with runtime scope

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?

like image 882
Tuomas Toivonen Avatar asked Aug 23 '17 14:08

Tuomas Toivonen


1 Answers

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.

like image 181
davidxxx Avatar answered Oct 18 '22 03:10

davidxxx