Why does Eclipse turn a maven runtime dependency into a compile dependency?

Viewed 1103

I have a maven project imported into Eclipse Oxygen. Eclipse reports no compile issues (Alt + F5). When I run maven from the command line I get

[ERROR] /home/dean/src/TAP3UIs/TAP3Desktop/src/main/java/com/ms/tap3/controller/RequestAccessController.java:[8,30] package com.google.common.base does not exist

That package does exist in my .m2/repository in guava-15.0.jar. I can also see it in Eclipse mvn dependencies. When I check the mvn dependency:tree for the project I see

[INFO] | | | +- com.google.guava:guava:jar:15.0:runtime

It is a runtime transitive dependency on the command line, which explains why it doesn't compile on the command line. Somehow Eclipse has turned a transitive dependency from runtime to compile.

Does anyone know why this happens and how I make Eclispe m2e respect the scope of the transitive dependencies?

2 Answers

The main point is this: If you import external classes in your source code, you must set them as compile dependencies, and never trust the fact that they might already be transitive dependencies (because, since they are transitive, you have not direct control over them, so in a future version they might diseappear as well).

What is happening is this:

  • You need some classes from com.google.common.base package, so you need to set com.google.guava:guava:jar:15.0 as a dependency.
  • Instead, you didn't because you realised it was already a transitive dependency, but you missed the fact that is a runtime dependency.
  • Eclipse M2 does not distinguish the different Maven's standard classpaths, so it treats all dependencies as if they were of "compile" scope. So Eclipse includes guava-15.0.jar in the compilation and the project is compiled OK.
  • Maven, instead, won't include a runtime dependency in the compilation phase, so a compile error is raised.

In brief: You should include guava-15.0 (as well as any other artifact your code needs) as a direct dependency (with compile scope) in your pom file.

Related