Po co są runtime only dependencies

0

Budując program przez gradle, można dodać runtime only dependencies "runtimeOnly"
https://docs.gradle.org/current/userguide/declaring_dependencies.html

Ale ja nie mogę skumać po co są runtime only dependencies - przecież skoro kod źródłowy nie odnosi się do tej dependencji w czasie kompilacji (bo przecież nie ma jak - ta dependencja jest tylko run time, czyli on jej w ogóle nie zna, nie może się z kodu do niej odwołać) to jak jest ona używana?

1

Hm Gradle dependency configuration : implementation vs api vs runtimeonly vs compileonly

runtimeonly: Gradle adds the dependency to the build output only, for use during runtime. That is, it is not added to the compile classpath. This configuration behaves just like apk (which is now deprecated).

teraz tylko trzeba się dowiedzieć co to apk :D

2

przecież skoro kod źródłowy nie odnosi się do tej dependencji w czasie kompilacji (bo przecież nie ma jak - ta dependencja jest tylko run time, czyli on jej w ogóle nie zna

Oh sweet summer child. Używałeś kiedyś "ręcznie" JDBC? Albo ładowałeś kiedyś jakieś klasy za pomocą refleksji czy dynamic classloadera? Zaręczam ci, że jak najbardziej można odnosić się do klas które nie są znane w czasie kompilacji. Ot np. głupia konfiguracja datasource w Springu wymaga od ciebie podania property z driver class name i ta klasa zostanie załadowana dynamicznie, mimo że w kodzie nie masz nigdzie bezpośrednio do niej odwołania.

0

Aplikacja zna kilka podstawowych interfejsów ogólnego standardu np JDBC, a konkretny driver to zależność runtime.
Więc nie jest tak, że zupełnie NIC nie wie o JDBC, bo zna interfejsy.

Przy pewnej dyscyplinie, czasem jest to tylko dla sportu, da sie pisać w JPA ( jar z API to niewiele kB) a uruchamianiać wobec nie tylko Hibernate, ale Eclipselink, OpenJPA, i kilku bardziej egzotycznych.
Więc zależność kompilacji to ten mały Jar, a konkretny provider to runtime.

2

Prosty przykład masz bibliotekę która ma API oraz różne implementacje, np. SLF4J ma api, oraz implementacje które mogą nie robić absolutnie nic, pisać na konsole, użyć pod spodem standardowego logowania z Javy, lub innej biblioteki np. log4j.

api slf4j dajesz jako compile time dependency, a konkretną implementację jako runtime dependency. Dzięki temu przy kompilacji kodu nie będziesz mógł się odwoływać do klas implementacji a jedynie do api. Ale przy uruchomieniu gradle doda klasy z zależności runtime na classpath. Znajdą się też one w wygenerowanym jarze.

Oprócz runtime, jest też scope provided. Jeżeli twoja aplikacja jest uruchamiana w "kontenerze" takim jak np. jboss albo tomcat to kontener dostarcza na classpath pewnych klas od siebie. Wtedy przy kompilacji mamy co prawda dostęp do bibliotek które są provided ale nie znajdą się one już w wygenerowanym jarze.

0

dziękuję za podpowiedzi, tu znalazłem dalsze informację do drążenia
https://tomgregory.com/gradle-implementation-vs-compile-dependencies/

What is an implementation dependency?

Forget Gradle for a moment. When you’re building and running a Java project there are two classpaths involved:

Compile classpath – this is a list of dependencies that are required for the JDK to be able to compile Java code into .class files
Runtime classpath – this list of dependencies is required to actually run the compiled Java code

When we’re configuring Gradle dependencies all we’re really doing is configuring which dependencies should appear on which classpath. Given there are only two classpaths, it makes sense that we have three options to declare our dependencies.

compileOnly – put the dependency on the compile classpath only
runtimeOnly – put the dependency on the runtime classpath only
implementation – put the dependency on both classpaths

1 użytkowników online, w tym zalogowanych: 0, gości: 1