Reputation: 1495
While running tests with Maven I have encountered a NoClassDefFoundError, caused by ClassNotFoundException. The class which was not found definitely exists in my local repository.
The problematic dependency looks like this: a default scoped dependency depends on a jar which scope is a marked as provided, and the file which was not found by the classloader is located inside that jar. It compiles ok, by the file cannot be found while runnig the app.
I have fixed the error by adding that "provided jar" explicitely to my pom as a runtime-scoped dependency, but I want to understand whats going on.
1) What is the meaning of dependency scope = provided if I am running some tests? I understand that a servlet container can have some provided jars, such as servlet-api.jar, but what about tests? This looks like an error in our pom, isn't it? Is there any other case except from servlet-api.jar (and similair web-server jars) when we should use the "provided" scope?
2) I tried to use a maven command-line parameter -U while looking for the solution of this problem. As far as I understand, it forces Maven to check the remote repository and take most fresh the dependencies from there if necessary. A question is: whats going on if I am not specifying this command? It will always get the outdated dependencies from local repository? If not, then why I need this command?
3) For solving issues like this it is good to know which jars are really on classpath when compiling the code, and which are there when running the code. Is it possible with Maven?
Upvotes: 0
Views: 3814
Reputation: 3156
1) You can run tests using a "Test container" (Jetty, Tomcat), and in this case as well, provided scope makes sense (For instance, I use tomcat in prod, but unit test with jetty, they don't even have the same version of the provided jars).
2) Maven by default takes the jars it finds in the local repo, not searching for a more recent one, if not a snapshot. If you provide your own jars, you should always increment the version, even if it is annoying sometimes.
3) mvn dependency:tree can give you all the dependy tree of your project. Some IDE (I use eclipse) give you some nice UI tool to see them too.
Upvotes: 1
Reputation: 101
1) provided always means, that the dependencies shouldn't be copied to the built artifact. tests with some dependencies declared as provided won't run as these dependencies are needed at runtime. you can solve this problem by creating an own profile "Test" for example. So in your "Test" profile you declare your dependencies as default scope, this will override the provided scope. After that you can run your tests with following command:
`mvn <goal> -PTest`
See Introduction on profiles for for information.
2)as far as i know, the command-line parameter -U will cause to fetch the dependencies freshly, as your repository may be broken (for example, if you changed or deleted files in there).
3) mvn dependency:tree
Upvotes: 2