I am new to Maven
My question is where does maven download the external dependency jars in the local machine.
Basically my application uses a lot of external dependencies and i am able to compile the application using maven
But is there a way to run the application from commandline with Java without having to create a Jar-with-dependencies, basically by just using all the class files and specifying my main class. For that i will have to set the classpath to the directory where my external jars are located. How do i do that?
Thanks in advance!!
You can also use the exec maven plugin to run your application inside the maven lifecycle. In its simplest form the command would be
mvn exec:java -Dexec.mainClass=com.example.Main
The full set of configuration options are described on the exec:java page. The classpathScope option might be especially interesting.
The advantage of this method would be that you can configure any command line arguments and system properties in your pom file.
You can use the dependency plugin to ask maven for the classpath. Just run
mvn dependency:build-classpath
and you can use the output in your java -cp command.
Regarding your first question:
My question is where does maven download the external dependency jars in the local machine.
Your local repository is usually here (on a Windows machine)
C:\Users\[username]\.m2\repository
Read more about Maven settings (especially the localRepository setting):
http://maven.apache.org/settings.html
Related
I have a simple java main class and can execute it using the below command on server
java com.....MainClass
Now we are trying to use Maven in our application.
I am seeing on web that the maven command to execute java program is
mvn exec:java -Dexec.mainClass=com......MainClass
Can I still use regular java command or do I have to use the maven command exec:java?
It's not clear to me when to use the maven exec:java command.
Please help me understand when to use regular java command and when to use the maven exec:java command.
when I use Maven can I still execute program using regular java command.
Maven
According to https://maven.apache.org/what-is-maven.html Maven's objectives are
Making the build process easy
Providing a uniform build system
Providing quality project information
Providing guidelines for best practices development
Allowing transparent migration to new features
So, you should use Maven for building your project... like building a JAR package with main class.
Running JAR packaged main class
See this answer or this Oracle's tutorial for running a JAR packaged Java class.
You can also use Maven for running the main class but you should not make your production environment depended on Maven.
maven is mainly a dependency mangement and a build tool.
u can still use java command to run your main class from the jar generated by maven under the target folder of your project.
java -cp "yourProject/target/folder-containing-dependenc-jars-if-exist/*:yourProject/target/thejar.jar" package.mainClass
ps: use the ":" separator on linux system , if you are under windows use ";"
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 :)
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():
Provide them using -classpath parameter just like IntelliJ.
Add maven-shade-plugin and use shade goal to the build a runnable Uber JAR. This creates a fat JAR which doesn't require -classpath.
Use some other Maven plugin to perform point 2 e.g. Spring Boot spring-boot:repackage goal.
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.
I need to release our Maven build Java project to an remote QA team. For this I would like to download all the dependencies, and send them so they do not need to download them.
Currently all dependencies are defined in the pom.xml file, and we use either mvn install or mvn package to build the project. Some of the project members use uber jars, others use jars + dependencies to do execution.
What would be the easiest way to pre-package the dependent jar files so that there is no download from the internet, and does not change our current build process too much?
A possible solution would be to purge your local repository, tell Maven to download every dependencies and plugin dependencies of your project and make a ZIP of that.
To purge your local repository, you can simply delete the folder {user.home}/.m2/repository. Then, you can use the dependency:go-offline goal:
Goal that resolves all project dependencies, including plugins and reports and their dependencies.
mvn dependency:go-offline
This will download everything that your project depends on and will make sure that on a later build, nothing will be downloaded.
Then, you can simply make a ZIP of {user.home}/.m2/repository and send that to your Q/A team. They will need to unzip it inside their own {user.home}/.m2/repository to be able to build the project.
Offline Package deploy
Your requirement can be accomplished by creating a stand alone jar file with full dependencies. You can port it anywhere please refer https://stackoverflow.com/a/35359756/5678086
Build a full dependency JAR file as said in the answer
Copy the JAR to the destination machine you want
Run the below command from there
mvn install:install-file -Dfile=<path-to-file>
This will install the dependecies in the maven repository of the destination machine. This is fully offline
Theoretically if you know which maven commands you'll use (package, install, etc.) you could clear out your ~/.m2/repository folder, run those commands once on somebody's dev box, then distribute the repository folder. You can run maven -o install etc. to have it not give annoying warnings. This might be a slightly smaller distro than the go-offline answer.
Suppose that we have a Java application, rather than a library, which is available through Maven central. For example, one such project is jol, which has its corresponding CLI interface in Maven central.
As far as I can tell, the main difference from a library is that the corresponding JAR file contains a class with an appropriate main() method and, optionally, a related Main-Class: header in the JAR manifest. If such an artifact is used as a dependency on a project, Maven will happily download the JAR file to the local repository along with its dependencies, as it does for any other artifact.
Is it possible to use Maven to execute such an application directly, without setting up a Maven project?
The exec:java plugin works nicely for local projects by setting up the JVM classpath so that dependencies are available. The user does not have to worry about JAR or .class file locations and such. Unfortunately, from what I can tell, it also requires an enclosing Maven project, so it cannot be used from an arbitrary command line prompt.
No, Maven will not do what you are asking for. It is a build tool, intended to build a Java project based on it's pom.xml file which describes the project.
So, you can't run a maven build without a pom.xml file.
And if you have a pom.xml, then by definition, you have 'set up a Maven project'.
As #DaveNewton says, you should be able to set up a very small pom.xml with the dependency for the jar file in question, and the exec-maven plugin. I'm afraid that it's just not going to get any simpler than that.
A hacky solution working with Maven 3 would be to use the Maven Dependency Plugin in combination with the Maven Help Plugin to resolve the local repository path:
# Download JAR from Maven repo
mvn dependency:get -DremoteRepositories=http://repo1.maven.org/maven2/ \
-DgroupId=some.group.id \
-DartifactId=some-artifact-cli \
-Dversion=1.0.0 \
-Dtransitive=false
# Resolve local repository path
MVN_REPO=$(mvn help:evaluate -Dexpression=settings.localRepository -q -DforceStdout)
# Execute JAR from the local repository
java -jar $MVN_REPO/some/group/id/some-artifact-cli/1.0.0/some-artifact-cli-1.0.0.jar
I have a huge project (Application) with another project inside it (Core). Application has a big set of libraries inside as does Core. I'm using Eclipse and so I'm using the Export Runnable Jar option to create Application.jar but when I run it part of the code uses the Core which has a dependency on an image library within that. When I look inside the runnable jar file all the libraries for the Application project are there but when I look inside the Core project jar file the libraries aren't there. To give you an idea of what I mean the structure I'm expecting looks like this:
Application
- Core.jar
+ ImageLibrary.jar
+ OtherLibraries.jar
:
+ OtherLibraries.jar
:
I'm using Maven to build the projects individually. But I'm not really an expert with Maven as I've only being using it for a short time.
Is it possible to build Application so that Core also has its libraries with it?
Thanks in advance,
Alexei Blue.
In your Maven build for Application, is Core not specified as a dependency? If so, it should be included with all its dependencies. You should probably check whether the dependencies themselves have the correct scope in Maven to be included.
Okay so I figured this one out in the end. When I was using Maven to build the project it was doing so and then not updating the build path in eclipse. So I in the core directory I ran:
# mvn clean install
# mvn eclipse:eclipse
As the image library was an addition to the Core dependencies I had to ensure that the build path for eclipse was set otherwise eclipse won't pick up the changes. The eclipse:eclipse command did this for me but I think it only works in projects that are one module, however it reads any dependencies from your pom file and ensures your project can see and access them.
And then in the App directory I re built the project:
# mvn clean install
Then from within eclipse I exported the App project as a Runnable Jar which worked fine.
Hope this helps anyone having the same problem.
Cheers,
Alexei Blue.