Reputation: 8820
I have a Java program in IntelliJ which has a pom.xml and uses Maven. The packages were downloaded and currently they are found by IntelliJ.
I'm a little confused though because the Maven repository is not part of the CLASSPATH as far as I can tell. So does IntelliJ just do a bit of magic where it looks into its Maven repository to find the packages? (I think that IntelliJ has its own Maven repo. I separately have Maven 3 installed, but I think it isn't using it.)
But more generally: If you build a JAR using Maven then I guess it will put the dependencies in the JAR where the Java program can find them, so there won't be a problem. But if you just run a Java program directly, do you need to add the Maven repository to your classpath or does something else happen?
Thanks for any information you can provide to lessen my confusion :)
Upvotes: 4
Views: 1162
Reputation: 1573
All the required dependencies, defined in the pom.xml file(s), are downloaded from Maven Central (or others if configured) to the local Maven repository. That repository is located at <user home>/.m2/repository
.
Maven generates/calculates a dependency tree to know all the required dependencies for the project. (you can also dump that tree with the command mvn dependency:tree
. I always pipe the result to a file, because the tree can be large mvn dependency:tree > deptree.txt
). Maven put them all on the classpath when executing a maven command like mvn compile
IntelliJ also use/calculate the dependency tree and add all the jar files to the projects classpath (point to the files in the <user home>/.m2/repository
folder). You can see them all in the list with External Libraries, and they will be used / on the classpath for compilation and running the application.
When building a JAR file the dependencies are NOT added to the JAR. Only the bytecode (java classes) and resources from your own project are packaged into the JAR file. (Source files can also be packaged if you configure that)
By adding a Maven plugin (maven-shade-plugin
) you can configure your project to also pack dependencies into the JAR. SpringBoot projects also will do that.
Upvotes: 2
Reputation: 44960
When you start the program from IntelliJ using a runtime configuration for your main()
method IntelliJ constructs the classpath from all the project dependencies. You can see this in the Run window, the first log line is the java
command used to start the main()
. It's a long line but it usually looks similar to:
java -javaagent:/opt/idea/idea-IC-173.3727.127/lib/idea_rt.jar=40165:/opt/infra/idea/idea-IC-173.3727.127/bin -Dfile.encoding=UTF-8 -classpath /home/ [...]
IntelliJ constructs the -classpath
argument adding both the module target
directory and the Maven dependencies referenced from the local Maven repository.
When you package the project using Maven mvn clean package
usually it becomes a standalone JAR with just your code (unless you changed the defaults). Now you have a few choices how to provide dependencies needed to start your main()
:
-classpath
parameter just like IntelliJ.maven-shade-plugin
and use shade
goal to the build a runnable Uber JAR. This creates a fat JAR which doesn't require -classpath
.spring-boot:repackage
goal.Upvotes: 4