When is a time to use Run-time over Compile-time dependencies in Java/Gradle?

Brandon :

From my understanding Gradle will carry over all compile dependencies as runtime dependencies.

What is an instance when you should only use runtime? All child dependencies are grabbed from compile and pulled into the compilation when gradle build is called.

For example, when I do a diff on what is printed when I call

> gradle -q dependencies

The list printed out for compile and runtime are identical. Example output may show following for both:

+--- org.springframework.boot:spring-boot-starter-web: -> 1.5.4.RELEASE
|    +--- org.springframework.boot:spring-boot-starter:1.5.4.RELEASE
|    |    +--- org.springframework.boot:spring-boot:1.5.4.RELEASE
|    |    |    +--- org.springframework:spring-core:4.3.9.RELEASE
|    |    |    \--- org.springframework:spring-context:4.3.9.RELEASE
|    |    |         +--- org.springframework:spring-aop:4.3.9.RELEASE
|    |    |         |    +--- org.springframework:spring-beans:4.3.9.RELEASE
|    |    |         |    |    \--- org.springframework:spring-core:4.3.9.RELEASE
|    |    |         |    \--- org.springframework:spring-core:4.3.9.RELEASE
|    |    |         +--- org.springframework:spring-beans:4.3.9.RELEASE (*)
|    |    |         +--- org.springframework:spring-core:4.3.9.RELEASE
|    |    |         \--- org.springframework:spring-expression:4.3.9.RELEASE
|    |    |              \--- org.springframework:spring-core:4.3.9.RELEASE
|    |    +--- org.springframework.boot:spring-boot-autoconfigure:1.5.4.RELEASE
|    |    |    \--- org.springframework.boot:spring-boot:1.5.4.RELEASE (*)
|    |    +--- org.springframework.boot:spring-boot-starter-logging:1.5.4.RELEASE
|    |    |    +--- ch.qos.logback:logback-classic:1.1.11
|    |    |    |    +--- ch.qos.logback:logback-core:1.1.11
|    |    |    |    \--- org.slf4j:slf4j-api:1.7.22 -> 1.7.25
|    |    |    +--- org.slf4j:jcl-over-slf4j:1.7.25
|    |    |    |    \--- org.slf4j:slf4j-api:1.7.25

I have looked at this answer which helped explain a little about the difference between compile and runtime, but it only showed that runtime is when your code actually executes a dependency. When would you have a runtime dependency, but not a compile time?

Michael Easter :

A typical case involves dynamically creating classes via reflection. As a contrived example, consider this app:

package net.codetojoy;

public class App {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("org.apache.commons.lang3.StringUtils");
        Object object = c.getConstructor().newInstance();
        System.out.println("object is : " + object);
    }
}

It will create an object of StringUtils from Apache Commons Lang. (This example is silly; consider a case where libA will effectively do this for classes in libB).

There is no compile-time dependency so there is no reason to burden the compile-time classpath with the jar. However at run-time, the jar is certainly required. The build.gradle file is below. It uses the application plugin which nicely bundles the dependencies into a runnable deliverable.

apply plugin: 'java'
apply plugin: 'application'

repositories {
    jcenter()
}

dependencies {
    runtime group: 'org.apache.commons', name: 'commons-lang3', version: '3.6'
}

mainClassName = 'net.codetojoy.App'

Example output:

$ gradle run -q
object is : org.apache.commons.lang3.StringUtils@4aa298b7

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=460383&siteId=1
Recommended