What is <scope> under <dependency> in pom.xml for? - maven

Looking at documentation http://maven.apache.org/surefire/maven-surefire-plugin/examples/testng.html, we can see <scope> tag under <dependency>
What is that and how can we use it for running test?

The <scope> element can take 6 values: compile, provided, runtime, test, system and import.
This scope is used to limit the transitivity of a dependency, and also to affect the classpath used for various build tasks.
compile
This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.
provided
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
runtime
This scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath.
test
This scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases.
system
This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.
import (only available in Maven 2.0.9 or later)
This scope is only used on a dependency of type pom in the section. It indicates that the specified POM should be replaced with the dependencies in that POM's section. Since they are replaced, dependencies with a scope of import do not actually participate in limiting the transitivity of a dependency.
To answer the second part of your question:
How can we use it for running test?
Note that the test scope allows to use dependencies only for the test phase.
Read the documentation for full details.

Six Dependency scopes:
compile: default scope, classpath is available for both src/main and src/test
test: classpath is available for src/test
provided: like complie but provided by JDK or a container at runtime
runtime: not required for compilation only require at runtime
system: provided locally provide classpath
import: can only import other POMs into the <dependencyManagement/>, only available in Maven 2.0.9 or later. It is not always practical to change parent, many projects already specify a parent project to manage their organization standards. dependencyManagement allows us to add parent project without making parent, it's like multiple inheritance.

Scope tag is always use to limit the transitive dependencies and availability of the jar at class path level.If we don't provide any scope then the default scope will work i.e. Compile .
Compile means that you need the JAR for compiling and running the app. For a web application, as an example, the JAR will be placed in the WEB-INF/lib directory. Provided means that you need the JAR for compiling, but at run time there is already a JAR provided by the environment so you don't need it packaged with your app. For a web app, this means that the JAR file will not be placed into the WEB-INF/lib directory. For a web app, if the app server already provides the JAR (or its functionality), then use "provided" otherwise use "compile".

.pom dependency scope can contain:
compile - available at Compile-time and Run-time
provided - available at Compile-time. (this dependency should be provided by outer container like OS...)
runtime - available at Run-time
test - test compilation and run time
system - is similar to provided but exposes <systemPath>path/some.jar</systemPath> to point on .jar
import - is available from Maven v2.0.9 for <type>pom</type> and it should be replaced by effective dependency from this file <dependencyManagement/>

Related

Meaning of SCOPE tag in Maven Dependency

When we use scope tag while providing dependencies in POM file of Maven, we can give several valid values (compile, run, provided etc..). I understand that tag is applicable for only transitive dependencies (i.: list of JARs required by direct dependencies that we give in POM).
When we give the scope as provided, will the dependency not be downloaded from Maven central repository ? Can someone please confirm.
Thanks!
Dependencies with scope provided are meant to be provided by the container in which the application runs (e.g. provided by jboss).
This means that they are downloaded by Maven, put on the compile and test classpath, but not included into the final WAR or EAR you are building.

What is the final dependency scope when different scopes are specified for one JAR?

I am studying some JARs in the Maven Repository and discovered this:
Hibernate Validator Engine 5.4.0.FINAL lists jboss-logging as a compile dependency, and jboss-logging-processor as a provided dependency
jboss-logging-processor lists jboss-logging as a provided dependency
In general, when a JAR is mentioned multiple times along the way under different scopes, what is the final, actual scope? Is there an order of precedence of sorts?
It depends on the context rather than inheritance.
However, if some implications are present:
something is marked as compile it is implicitly a runtime dependency.
something is marked as runtime it is implicitly a test dependency.
provided will be used in both runtime and test though it is not loaded during run or test time.
system will be used in both runtime and test

Direct dependency and transitive dependency in test scope through maven

Is a direct dependency available in test scope while using maven?
So, if user-management have a dependency on utility module in normal flow:
<dependency>
<groupId>GROUP ID</groupId>
<artifactId>utils</artifactId>
<version>${version.product}</version>
</dependency>
Then will it also be available in test scope while testing user-management?
Is transitive dependency available in test scope while using mavan?
like User-managment-> utility-> plan
Then I don't think it would be available as maven document Maven: The Complete Reference
3.4. Project Dependencies.
So how can I include transitive dependency in test scope?
While testing user-management I am using some domain objects and service classes of other modules also.
I am shocked with this and it would be great help if someone can help that how to run these test cases as a project level.
Thanks in advance!!!!!
During tests, the test output directory and main output directory are the first two things on the test classpath, respectively. Then come all of your direct and transitive dependencies of all scopes, following the rules for scopes and transitive dependencies in the link you mentioned and in the order you've declared them in the POM. Find details about each scope in "Dependency Scope" on the Maven site.

Understanding Maven scoping better

I have been struggling to figure out what's the use of scoping that is provided by Maven
as mentioned here.
Why should you not always have compile time scoping? Real life examples would be really appreciated.
The compile scoped dependencies are only used during compilation.
The test scoped ones -- only during tests. Say you have tests using junit, or easymock. You obviously do not want your final artifact to have a dependency on them, but would like to be able to just depend on these libraries while running your tests.
Those dependencies which are marked provided are expected to be on your classpath when you're running the produced artifact. For example: you have a webapp and you have a dependency on the servlet library. Obviously, you should not package it inside your WAR file, as the webapp container will already have it and a conflict may occur.
One of the reasons to have different scopes for dependencies is that different parts of the build can depend on different dependencies. For example, if you are only compiling your code and not executing any tests, then there is no point in having Maven downloading your test dependencies (if they're not already present in your local repository, of course). The other reason is that not all dependencies need to be placed in your final artifact (whether it's an assembly, or WAR file), as some of the dependencies are only used during the build and testing phases.
compile
Will copy these jar files into prepared War file.
Ex: hibernate-core.jar need to have in our prepared War.
provided
These jars will be considered only at complie time and test time
Ex:
servlet.jar will be provided by deployed server, so no need to provide from our prepared War file.
test
These jars are only required for running test classes.
Ex: Junit.jar will be required only for running Junit test classes, no need to deploy these.
Scopes are quite well explained in here:
https://maven.apache.org/pom.html#Dependencies
As a reference, I copied the paragraph:
scope: This element refers to the classpath of the task at hand
(compiling and runtime, testing, etc.) as well as how to limit the
transitivity of a dependency. There are five scopes available:
compile
- this is the default scope, used if none is specified. Compile dependencies are available in all classpaths. Furthermore, those
dependencies are propagated to dependent projects.
provided - this is
much like compile, but indicates you expect the JDK or a container to
provide it at runtime. It is only available on the compilation and
test classpath, and is not transitive.
runtime - this scope indicates
that the dependency is not required for compilation, but is for
execution. It is in the runtime and test classpaths, but not the
compile classpath.
test - this scope indicates that the dependency is
not required for normal use of the application, and is only available
for the test compilation and execution phases.
system - this scope is
similar to provided except that you have to provide the JAR which
contains it explicitly. The artifact is always available and is not
looked up in a repository.
there are a couple of reasons that you might not want to have all dependencies to be default compile scope
reduce the size of final artifact(jar,war...) by indicating different scope.
when you have a multiple-modules project, you have ability to let each module have it's own version of dependency
avoid class version collision by provided scope, for instance if you are going deploy a war file to weblogic server, you need to get rid of some javax jars, like javax.servlet, javax.xml.parsers, JPA jars and etc. otherwise you might end up with class collision error.

Multiple reusable modules in maven

I have a couple of java modules set up in IDEA and I am wanting to mavenize them. These java modules use classes from one another.
I was not quite sure how I should take up this and I decide to add modules on a maven project using IDEA. Hence first I created a maven project, let's name it pm1 which has a class let's name it TempClass1. Now this class can be used in other maven project. Hence I added another maven module - pm11 and tried to use TempClass1 with in pm11. It worked and I notices that IDEA had added module dependency of pm1 in pm11. So whole structure looks as -
But now when I do mvn test from pm11 then it fails with error message package package1 does not exist and it looks to me that it is because package1 is in a different maven project. And I am not sure how I could use classes which reside in a different maven project. I hope I am clear in my question.
You can use classes of other maven projects, as long as there's a proper maven dependency defined in pom.xml. Ensure that the dependency is defined and its' scope is either undefined or relevant (You may have problems if the scope is provided for example).

Resources