Dodając zależność (dependency) do projektu zarządzanego przez Mavena należy zdecydować pomiędzy jednym z zakresów (scope). Dostępne zakresy to: compile, provided, runtime, test, system, import.
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>...</scope>
</dependency>
compile (domyślny)
compile jest domyślnym zakresem – używanym gdy żaden nie jest zdefiniowany:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Możliwe jest też jawne użycie:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>compile</scope>
</dependency>
Zastosowanie tego zakresu zapewnia, że podczas budowania ta zależność pojawi się na classpath przy kompilacji oraz przy uruchamianiu testów. Dodatkowo, jeśli budujemy paczkę (jar,war,zip…) ta zależność także się w niej pojawi. Warto dodać, że wszystkie zależności tego zakresu są propagowane w dół do zależnych modułów/projektów.
provided
Jest to prawie, że identyczny zakres jak compile – zależność pojawi się na classpath przy kompilacji oraz przy uruchamianiu testów. Ale w tym wypadku w wynikowej paczce nie dostaniemy tej zależności (stąd nazwa provided):
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>provided</scope>
</dependency>
Warto także dodać, że taka zależność nie jest tranzytywna – nie będzie propagowana do zależnych modułów/projektów.
runtime
Zakres runtime powoduje ograniczenie zależności do dwóch zakresów:
1. czasu działania aplikacji (stąd runtime), gdzie zostaje dostarczony podczas budowania paczki
2. classpath dla testów
Co ciekawe taka zależność nie pojawi się na classpathie dla głównej części (najczęściej jest to src/main/java) naszego projektu – nie będzie można wykorzystać klas tej zależności. Przykładem wykorzystania może być wymuszenie dodania zależności do paczki (w sytuacji gdy takową tworzymy) ale zastrzeżenie użycia klas danej zależności w module.
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>runtime</scope>
</dependency>
Zależności z zakresu runtime są tranzytywne.
test
Jak sama nazwa mówi, ten zakres jest przeznaczony do zależności wykorzystywanych tylko w testach (takich jak Mockito czy JUnit):
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
Zależność o zakresie test nie jest tranzytywna – nie będzie propagowana do zależnych modułów/projektów.
system
Pozwala na wskazanie ścieżki do pliku JAR, co powoduje, że zależność nie jest pobierana z repozytorium tylko zaciągana z systemu plików:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/junit_patched.jar</systemPath>
</dependency>
Zależność o zakresie system nie jest tranzytywna – nie będzie propagowana do zależnych modułów/projektów.
import
Jest to zakres wykorzystywany tylko i wyłącznie wobec zależności typu pom (<packaging>pom</packaging>). Dzięki temu możliwe jest zaciągnięcie wszystkich zależności zdefiniowanych w zależności typu pom:
<dependency>
<groupId>maven</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Ten zakres nie żadnego wpływu na tranzytywność zależności.