Reputation: 14266
I am not very much experienced with Maven and it's compilation and packaging logic gets me confused.
I have some dependencies declares as :
<dependency>
<groupId>com.dependency_group</groupId>
<artifactId>dependency_1</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.dependency_group</groupId>
<artifactId>dependency_2</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
So as far as I understand, dependency_1
will be added to the classpath of my program as something that comes along with my jar, and dependency_2
on the other hand, will be added to the classpath as something that the system runtime will provide upon deployment.
Then I run the package
goal of Maven and none of my dependencies are packed with my code (I am using the shade
plugin, but even without it nothing changes).
I expected that when some dependency is set as compile
scope
, it will be exported with my compiled code, since AFAICS, there's no point in setting the classpath saying a dependency will come along with my code, and Maven just don't package that dependency with it. It looks to me as if Maven is not obeying it's contract.
So:
1 - What's the logic behind this?
2 - Do I have to always use the Assembly plugin?
3 - Are there cases where people will define a dependency as compile
and will not want it packaged within a jar
?
Upvotes: 1
Views: 75
Reputation: 35785
Let me shed some light on the main point here. There are fundamentally two kinds of java artifacts:
For Applications your reasoning makes perfectly sense. Wars and Ears automatically package all their compile dependencies and you need no assembly plugin for that. For libraries, you do not pack the dependencies into the library. Maven handles transitive dependency resolution and would be confused if you put a fat jar on the classpath.
The thing is that packaging jar
can be both a libary or an application. If you want a standalone application, you need to tell Maven to package everything, e.g. by using the assembly plugin or shade plugin.
Upvotes: 2
Reputation: 32507
You use compile
scope when you want some dependencies to come along with your code. For example you want Jackson
to be a part of your application if you are using it for json serialization.
You use provided
scope, if you want dependency to be on the classpath during the compilation but wont be included within your application. It must be provided by running environment. For example you want Lombok
as it is compile only library, or you want to have Servlet Api
dependency as provided when you are writing servlet application because such app will be ran on servlet container thus there is no need to pack it within your application (it will be available in container runtime)
Do I have to always use the Assembly plugin
Nobody forces you to do so.
Upvotes: 0