What is the difference between <Scope>test</scope> and <Scope>Compile</Scope>? - maven

I'm using the following dependency, what is the affect that i get, if i change the scope to compile?
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>7.0.0.jre8</version>
<scope>test</scope>
</dependency>

The dependency with test scope will not be included in the final build. Lets say you are building a war file and you wrote some junit tests. Per maven convention, your tests resides in src/main/test folder. In your pom.xml you include junit dependency with test scope. When you run mvn package goal, your test will be executed. During the test phase, maven uses the junit jar and compiles the test classes but the junit jar will not be included in the final war file. If you change junit scope to compile, then the junit dependency will be available during testing phase and also it will be included in the final war file.

Related

Two Maven Dependencies with different scope

If I have the following two dependencies in the same pom.xml file:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
And I'd like to remove the redundancy. So should I delete the one with scope as runtime because it's included in the other dependency?
Also I'd be happy to understand why one would specify a dependency with scope of runtime.
From Introduction to the Dependency Mechanism - Dependency Scope:
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.
(...)
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.
So if you have a compile dependency, runtime is already included and therefore superfluous.
As an example for when to use runtime, take the SLF4J logging API: you compile your sources against slf4j-api.jar (compile dependency), but not the actual implementation, which is distributed separately (and there are several to choose from). However, when packaging your application or running unit tests, Maven should still include an implementation jar, e.g. slf4j-simple.jar (runtime dependency), because otherwise nothing will be logged.

How to run Junit Test in Maven when a test file is not in mavenise structure

I have so many java files and those java files test.java is not in src/test/java structure.
for ex: i have java file named abc.java in src/java/abc but the the test file of this java file named as abcTest.java is in src/java/junit/abc.
so how i will do the junit testing of this java file through maven pom.xml as maven wants normal java file in src/main/java and test files in src/test/java so how i will do the test through maven?
I have added the junit dependency and surefire plugin in my pom.xml .
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
and the surefire plugin is
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<testSourceDirectory>${basedir}/../src/java/junit/*.java</testSourceDirectory>
<testClassesDirectory>${project.build.directory}/classe‌​s/</testClassesDirectory>
<includes>
<include>abcTest.java</include>
</includes>
</configuration>
</plugin>
i have given mvn test command but still it is giving zero tests in log. Can anyone help me on this how to run junit test.java files through maven?
i have added these two below lines in my pom.xml after basedirectory tag and junit test cases ran successfully . and now i am running mvn install and all my testcases in test.java are running although i don't have maven like structure.
<testSourceDirectory>${basedir}/../src/java/junit</testSourceDirectory>
<testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
and after that i have added surefire plugin and thats all my junit testcases are running.
Assuming you can't really the structure of the project, you'll have to customize the Surefire plugin.
Adding a Junit dependency won't be sufficient - its only allow to compile your test classes.
So, you're in the right direction - you'll have to customize a Surefire plugin of Maven responsible for running the tests.
Now, in order to make Surefire plugin running the tests that don't end with *Test.java you'll have to change inclusions. Namely, you'll have to specify regular expressions that will reflect the names of tests you wish to run.
This page describes just this.

Does Maven need to explicitly specify the dependency that Spring/Hibernate dependented?

I'm new to Maven, I try to use Maven with Spring, Hibernate in my project. After go though the Spring and Hibernate reference, I found that "there is no need to explicitly specify the dependent liberaries in POM.xml file for such Apache commons liberaries".
My questions is that : If my other parts of project refer to Apache commons liberary, such as commons-io, SHOULD I explicit specify this dependency in POM.xml file?
You should define those dependencies in Maven which your project is using. For example, even though some library depends on commons-io but if your code needs this then you should directly define commons-io in your pom.xml
You should not worry about the dependencies of the libraries you have defined in your pom.xml. Maven will do that for you.
Maven is used to avoid the issue of having to run down JAR files that are dependent on other JAR files. Of course you do not HAVE to use maven to do this, but you should. Maven will automatically download the dependent JAR files of the JAR file you require. THe hibernate-entity manager JAR file, for example, has over 100 dependencies and maven does the work for you.
Anyway,even if you do add the commons-io file to the build path/classpath of the maven project,and then update the project configuration, maven will kick it out.
You can provide a lib name on a site like mvnrepository.com to see what it depends on (e.g. take a look at a section called "This artifact depends on ..." in case of spring-webmvc library). Those dependencies (which your artifact depends on) are called transitive dependencies. You don't have to specify these in your pom.xml as maven will resolve them for you.
For the sake of readability you should only state those dependencies in your module that you rely on directly. You want JUnit to test your software, only declare JUnit; you need hibernate to use ORM, declare hibernate, and so on. Leave the rest to Maven.
And most of the time you should state what you intend to use in the very module you want to use it in. So if you want to use a dependency in more than one module, consider moving it into a dependencyManagement block in a parent pom and referencing it from there in the module you want it in.
parent pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
child pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
This guarantees you version-stability and still allows you to find out what a module uses by only looking in it's pom (and not all over the place).

Maven test dependency not being found

I'm declaring a test dependency on powermock with easymock bundled in.
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>1.4.12</version>
<type>pom</type>
<scope>test</scope>
</dependency>
When I run mvn test, the test src claims to be able to find org.powermock but not org.easymock, despite it being included in the above dependency.
I wondered whether it was a problem due to transitivity of the test scope, so i tried compile scope also (as the documentation http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html mentions that the compile dependencies are available at test time) without any luck.
I've also tried using a bundled jar instead of pom, to no avail. I realise i could declare the dependencies separately (ie separate dependencies for powermock and easymock) but for my purposes i'm restricted to having just the one dependency including all necessary test libs.
Tracing this back to the powermock parent pom I see that the easymock dependency is marked "provided."
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.1</version>
<scope>provided</scope>
</dependency>
Looks like powermock is expecting its clients (you in this case) to supply the easymock jars.
According to the powermock-easymock-release-full POM, it does not depend on easymock (ie easymock does not appear in the powermock-easymock-release-full dependencies). So you'll have to add another dependency to easymock, dependending on the test engine you're using (JUnit or TestNG): http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.powermock%22%20AND%20%22easymock%22

Maven 3 and JUnit 4 compilation problem: package org.junit does not exist

I am trying to build a simple Java project with Maven. In my pom-file I declare JUnit 4.8.2 as the only dependency. Still Maven insists on using JUnit version 3.8.1. How do I fix it?
The problem manifests itself in a compilation failure: "package org.junit does not exist". This is because of the import statement in my source code. The correct package name in JUnit 4.* is org.junit.* while in version 3.* it is junit.framework.*
I think I have found documentation on the root of the problem on http://maven.apache.org/plugins/maven-surefire-plugin/examples/junit.html but the advice there seems to be meant for Maven experts. I did not understand what to do.
Just to have an answer with the complete solution to help the visitors:
All you need to do is add the junit dependency to pom.xml. Don't forget the <scope>test</scope>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
#Dennis Roberts: You were absolutely right: My test class was located in src/main/java. Also the value of the "scope" element in the POM for JUnit was "test", although that is how it is supposed to be. The problem was that I had been sloppy when creating the test class in Eclipse, resulting in it being created in src/main/java insted of src/test/java. This became easier to see in Eclipse's Project Explorer view after running "mvn eclipse:eclipse", but your comment was what made me see it first. Thanks.
my problem was a line inside my pom.xml i had the line <sourceDirectory>${basedir}/src</sourceDirectory> removing this line made maven use regular structure folders which solves my issue
removing the scope tag in pom.xml for junit worked..
I had the same problem. All i did was - From the pom.xml file i deleted the dependency for junit 3.8 and added a new dependency for junit 4.8. Then i did maven clean and maven install. It did the trick. To verify , after maven install i went project->properties-build path->maven dependencies and saw that now the junit 3.8 jar is gone !, instead junit 4.8 jar is listed. cool!!. Now my test runs like a charm.. Hope this helps somehow..
Add this dependency to your pom.xml file:
http://mvnrepository.com/artifact/junit/junit-dep/4.8.2
<!-- https://mvnrepository.com/artifact/junit/junit-dep -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.8.2</version>
</dependency>
I had my files at the correct places, and just removing <scope>test</scope> from the JUnit dependency entry solved the problem (I am using JUnit 4.12). I believe that with the test scope the dependency was just being ignored during the compilation phase. Now everything is working even when I call mvn test.
My case was a simple oversight.
I put the JUnit dependency declaration inside <dependencies> under the <dependencyManagement/> node instead of <project/> in the POM file. Correct way is:
<project>
<!-- Other elements -->
<dependencies>
<!-- Other dependencies-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
<project>
I had a quite similar problem in a "test-utils" project (adding features, rules and assertions to JUnit) child of a parent project injecting dependencies.
The class depending on the org.junit.rules package was in src/main/java.
So I added a dependency on junit without test scope and it solved the problem :
pom.xml of the test-util project :
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
pom.xml of the parent project :
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
How did you declare the version?
<version>4.8.2</version>
Be aware of the meaning from this declaration explained here (see NOTES):
When declaring a "normal" version such as 3.8.2 for Junit, internally this is represented as "allow anything, but prefer 3.8.2." This means that when a conflict is detected, Maven is allowed to use the conflict algorithms to choose the best version. If you specify [3.8.2], it means that only 3.8.2 will be used and nothing else.
To force using the version 4.8.2 try
<version>[4.8.2]</version>
As you do not have any other dependencies in your project there shouldn't be any conflicts that cause your problem. The first declaration should work for you if you are able to get this version from a repository. Do you inherit dependencies from a parent pom?
Me too had the same problem as shown below.
To resolve the issue, below lines are added to dependencies section in the app level build.gradle.
compile 'junit:junit:4.12'
androidTestCompile 'com.android.support.test:runner:0.5'
Gradle build then reported following warning.
Warning:Conflict with dependency 'com.android.support:support-annotations'.
Resolved versions for app (25.1.0) and test app (23.1.1) differ.
See http://g.co/androidstudio/app-test-app-conflict for details.
To solve this warning, following section is added to the app level build.gradle.
configurations.all {
resolutionStrategy {
force 'com.android.support:support-annotations:23.1.1'
}
}
I had a similar problem of Eclipse compiling my code just fine but Maven failed when compiling the tests every time despite the fact JUnit was in my list of dependencies and the tests were in /src/test/java/.
In my case, I had the wrong version of JUnit in my list of dependencies. I wrote JUnit4 tests (with annotations) but had JUnit 3.8.x as my dependency. Between version 3.8.x and 4 of JUnit they changed the package name from junit.framework to org.junit which is why Maven still breaks compiling using a JUnit jar.
I'm still not entirely sure why Eclipse successfully compiled. It must have its own copy of JUnit4 somewhere in the classpath. Hope this alternative solution is useful to people. I reached this solution after following Arthur's link above.
I also ran into this issue - I was trying to pull in an object from a source and it was working in the test code but not the src code. To further test, I copied a block of code from the test and dropped it into the src code, then immediately removed the JUnit lines so I just had how the test was pulling in the object. Then suddenly my code wouldn't compile.
The issue was that when I dropped the code in, Eclipse helpfully resolved all the classes so I had JUnit calls coming from my src code, which was not proper. I should have noticed the warnings at the top about unused imports, but I neglected to see them.
Once I removed the unused JUnit imports in my src file, it all worked beautifully.
Find the one solution for this error if you have code in src/main/java Utils
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.9.1</version>
</dependency>
Changing the junit version fixed this for me. Seems like version 3.8.1 didn't work in my case. Issue fixed upon changing it to 4.12
I met this problem, this is how I soloved it:
Context:
SpringBoot application
Use maven to manage multiple modules
Add junit's maven dependency in root POM's dependencyManagement(rather than dependencies, their differences can be found here)
Intend to test class or folder inside one of the root module's child module
PS: If your situation does not match the context above, this solution may not solve your problem.
Steps
right click at the class or folder you want to test:
Choose More Run/Debug -> Modify Run Configuration
Change the module option to the one you want to test from root module
By default , maven looks at these folders for java and test classes respectively -
src/main/java and src/test/java
When the src is specified with the test classes under source and the scope for junit dependency in pom.xml is mentioned as test - org.unit will not be found by maven.

Resources