How to reproduce:
Download the default maven/java spring project from https://start.spring.io/ with spring-web, build it and then I'd like to start it using the following command:
java -cp target/demo-0.0.1-SNAPSHOT.jar com.example.demo.DemoApplication
The error I'm getting is:
Error: Could not find or load main class com.example.demo.DemoApplication
I know it works with java -jar, but I explicitly want to put more things on the classpath. Why doesn't it work?
The solution was to use a shadow jar plugin instead of the spring-boot one, because spring-boot plugin creates a jar that puts classes in a subfolder, which makes them inaccessible for the java -cp command.
Assuming (but it is obvious) that you will be putting jar files in class path.
install the jar file which you want to put in class path using mvn install like this below
mvn install:install-file -Dfile=<complete path here for jar.jar> -DgroupId=com.example.groupId -DartifactId=example-artifact -Dversion=1.0 -Dpackaging=jar
Make sure if you have multiple jars to be included in your spring project, you should put different unique groupId, and artifactId, so tha mevn doesn't get confused.
Then add those jars in pom.xml as dependency:
<dependency>
<groupId>groupID from above install command</groupId>
<artifactId>artifact Id from above install command</artifactId>
<version>version from above install command</version>
</dependency>
And then build and run your spring project as you ideally do with
java -jar SpringProject.jar
Related
I have a project downloaded from git. Here is the link to source code https://github.com/dwdyer/reportng, I have downloaded it and now I am trying to create a JAR file and then want to attach it to maven repository. When I compile it using mvn compile and mvn package, it gives me the same INFO message, and in my target folder there is a jar file is created. But only pom.xml and pom.properties are shown inside it, instead of whole hierarchy of compiled class files replaced with Java files
Maven is very picky about following a very specific folder layout in the given project (which you can override but it is not really intended to do so).
Instead you may want to just install the generated jar file directly in your local repository using the mvn install:install command.
If you want to script this, see Multiple install:install-file in a single pom.xml for instructions on how to create a pom.xml doing this.
First of all, you have to debug problem:
cd reportng/
mvn -e clean install
-e switch on errors' trace.
If everything ok, install will add jar just created jar file to your local repository.
Then it will be available as dependency to any project:
<dependency>
<groupId>org.uncommons</groupId>
<artifactId>reportng</artifactId>
<version>1.1.4</version>
</dependency>
By the way:
Jar is available in maven central, so referencing it as dependency, having compile time internet connection, will be enough.
This can be solved by changing the Maven strusture. Maven must contain src/main/java, whereas in the program it is src/java/main
I have an application.properties file with default variable values. I want to be able to change ONE of them upon running with mvn spring-boot:run. I found how to change the whole file, but I only want to change one or two of these properties.
You can pass in individual properties as command-line arguments. For example, if you wanted to set server.port, you could do the following when launching an executable jar:
java -jar your-app.jar --server.port=8081
Alternatively, if you're using mvn spring-boot:run with Spring boot 2.x:
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8081"
Or, if you're using Spring Boot 1.x:
mvn spring-boot:run -Drun.arguments="--server.port=8081"
You can also configure the arguments for spring-boot:run in your application's pom.xml so they don't have to be specified on the command line every time:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<arguments>
<argument>--server.port=8085</argument>
</arguments>
</configuration>
</plugin>
To update a little things, the Spring boot 1.X Maven plugin relies on the --Drun.arguments Maven user property but the Spring Boot 2.X Maven plugin relies on the -Dspring-boot.run.arguments Maven user property.
So for Spring 2, you need to do :
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8081"
And if you need to pass multiple arguments, you have to use , as separator and never use whitespace between arguments :
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8081,--foo=bar"
About the the maven plugin configuration and the way of passing the argument from a fat jar, it didn't change.
So the very good Andy Wilkinson answer is still right.
Quick update:
if you are using the latest versions of spring-boot 2.X and maven 3.X, the below command line will override your server port:
java -jar -Dserver.port=9999 your_jar_file.jar
If not working with comma, to override some custom properties or spring boot properties in multiple mode, use whitespace instead of comma, like this code bellow:
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8899 --your.custom.property=custom"
You can set an environment variable to orverride the properties. For example, you have an property name test.props=1 . If you have an environment variable TEST_PROPS spring boot will automatically override it.
export TEST_PROPS=2
mvn spring-boot:run
You can also create a json string with all the properties you need to override and pass it with -Dspring.application.json or export the json with SPRING_APPLICATION_JSON.
mvn spring-boot:run -Dspring.application.json='{"test.props":"2"}'
Or just pass the properties with -Dtest.props=2
mvn spring-boot:run -Dtest.props=2
Tested on spring boot 2.1.17 and maven 3.6.3
Running by Gradle:
Run in default port(8080): ./gradlew bootRun
Run in provided port(8888): ./gradlew bootRun --args='--server.port=8888'
If we have any variable in the application.properties file named PORT, run this: PORT=8888 ./gradlew bootRun
Running by Maven:
Run in default port(8080): mvnw spring-boot:run
Run in provided port(8888): mvnw spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=8085'
Run in provided port(8888): mvn spring-boot:run -Dspring-boot.run.arguments='--server.port=8085'
Run in provided port(8888) with other custom property: mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8899 --your.custom.property=custom"
If we have any variable in the application.properties file named PORT, run this: SERVER_PORT=9093 mvn spring-boot:run
Using java -jar:
Create the .jar file:
For Gradle: ./gradlew clean build. We will find the jar file inside: build/libs/ folder.
For Maven: mvn clean install. We will find the jar file inside:target folder.
Run in default port(8080): java -jar myApplication. jar
Run in provided port(8888): java -jar myApplication.jar --port=8888
Run in provided port(8888): java -jar -Dserver.port=8888 myApplication.jar
Run in provided port(8888) having variable SERVER_PORT in application.properties file: SERVER_PORT=8888 java -jar target/myApplication.jar
In Spring Boot we have provision to override properties as below
mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8082
If you have the jar file after doing mvn clean install, you can override any property that you have in your application.yml using the double -, like this:
java -jar name_of_your_jar_file.jar --parameter=value
For example, if you need to change your server port when starting you server, you can write the following:
java -jar name_of_your_jar_file.jar --server.port=8888
I Was making a mistake with the syntax of commandline command , while passing command-line arguments, I was wrapping multiple arguments between " " and this was the issue. I simply ran the same command having multiple arguments separated by a space without wraaping them between "" and it worked just fine.
Please note this answer is for cases where we are trying to run this scenario from a jar file(not using mvn).
Correct Command: java -jar myJar.jar --com.arg1=10 --com.arg2=1
Incorrect Command: java -jar myJar.jar "--com.arg1=10 --com.arg2=1"
If I know the coordinates of an artifact, and a name of the class inside that artifact, can I make Maven run the class, including all of its dependencies on the Java classpath?
For example, suppose a coworker told me about a tool I can run, which is published to our internal Nexus with the artifact coordinates example:cool-tools:1.0.0. I used this answer to download the artifact. Now, I know that the main class name is example.Main. But if I just go to the artifact's download location and run java -cp cool-tools-1.0.0.jar example.Main, I get NoClassDefFoundErrors for any dependencies of cool-tools.
I'm aware of the maven-exec-plugin, but as far as I can tell that's only for projects where you have the source. Suppose I don't have access to the source, only the Nexus containing the tool (and all its dependencies). Ideally, I'd do something like mvn exec:exec -DmainArtifact='example:cool-tools:1.0.0' -DmainClass='example.Main', but I don't think the exec plugin is actually capable of this.
ETA: To be clear, I do not have a local project / POM. I want to do this using only the command line, without writing a POM, if possible.
There is no out-of-the-box solution for your task. But you can create a simple script to solve it:
Download pom.xml of your tool from the repo.
Download jar of your tool.
Download all its dependencies.
Run java against resolved libraries.
Command line:
> mvn dependency:copy -Dartifact=<tool.group.id>:<tool.artifact.id>:<tool.version>:pom -DoutputDirectory=target
> mvn dependency:copy -Dartifact=<tool.group.id>:<tool.artifact.id>:<tool.version> -DoutputDirectory=target
> mvn dependency:copy-dependencies -f target/<tool.artifact.id>-<tool.version>.pom -DoutputDirectory=target
> java -cp target/* <tool.main.class>
Directory ./target will contain your tool + all dependencies.
See details on dependency:copy and dependency:copy-dependencies mojos.
Edit
As alternative, you can build classpath using libraries in the local repo by:
> mvn dependency:build-classpath -DincludeScope=runtime -f target/<tool.artifact.id>-<tool.version>.pom [-Dmdep.outputFile=/full/path/to/file]
See details on build-classpath mojo.
You could download the pom from the repository using wget, for instance. Then resolve the dependencies, and build the classpath exporting it to a file using Maven. Finally, execute with Java and the built classpath using something like bash backticks to use the content of the file.
Just like in this answer.
For me the first anwer almost worked, but I needed to slightly adjust the script. In the end I came (on windows machine) to following solution:
> mvn dependency:copy -Dartifact=<tool.group.id>:<tool.artifact.id>:<tool.version>:pom -DoutputDirectory=target
> mvn dependency:copy -Dartifact=<tool.group.id>:<tool.artifact.id>:<tool.version> -DoutputDirectory=target
> mvn dependency:copy-dependencies -f target/<tool.artifact.id>-<tool.version>.pom -DoutputDirectory=target
> cd target
> java -cp target/*;<tool.artifact.id>-<tool.version>.jar <tool.main.class>
On Unix/Linux machine in the last command the semicolon ";" must be replaced with colon ":".
When input arguments must be provided, just put them in the last script line:
> java -cp target/*;<tool.artifact.id>-<tool.version>.jar <tool.main.class> arg1 arg2 ...
u can use IDEs like Intellij idea which automatically resolve dependencies as u write them in your pom
As it has been mentioned by others already there is no solution without creating an extra POM.
One solution could be to use the Maven Shade Plugin in this POM: "This plugin provides the capability to package the artifact in an uber-jar, including its dependencies"
I think the Executable JAR is close to that what you'd like to achieve.
I want to add jpoller.jar as a maven dependency, so I edited my pom.xml file to include it:
<dependency>
<groupId>org.sadun</groupId>
<artifactId>jpoller</artifactId>
<version>1.5.2</version>
</dependency>
Now, as expected, when I compile from the command line I get an error because jpoller isn't in any of the repositories I have listed in my pom, nor could I find one for it. Although I could create a repository for it, I'd rather not at this point. Thus, I get the following error:
[INFO] Failed to resolve artifact.
Missing:
---------- 1) org.sadun:jpoller:jar:1.5.2
Try downloading the file manually
from the project website.
Then, install it using the command:
mvn install:install-file -DgroupId=org.sadun -DartifactId=jpoller -Dversion=1.5.2 -Dpackaging=jar -Dfile=/path/to/file
How can I do this from the M2Eclipse plugin on machines where the maven CLI isn't available?
How can I do this from the M2Eclipse plugin on machines where the maven CLI isn't available?
Well, simply do it from Eclipse. First, get that jpoller jar and save it somewhere on your file system. Then, in Eclipse, from the top bar, Run > Run Configurations... then right-click on Maven Build and configure the New_configuration freshly created:
Select an arbitrary Base directory
Fill the Goals with install:install-file
Add parameters for each required parameters, without the -D prefix (e.g. file as Parameter name and /path/to/file as Value and so on for groupId, artifactId,packaging and version).
And run this configuration. Or... just install Maven.
The install command automates the creation of a folder structure in ~/.m2 and pom.xml file for the dependency artifact. This can be done manually. OR You can simply copy the ~/.m2/{group}/{artifact} folder from a machine that does have mvn installed.
Edit: This tool will help you find public repositories for a given dependency.
Edit2: See http://maven.apache.org/guides/mini/guide-coping-with-sun-jars.html for an explination of the process of installing dependencies manually. Note that most sun jars are now available in the java.net repository http://download.java.net/maven/2/
I'm trying to use Google protocol buffer for Java(I'm a newbie about Java, just trying).
First of all, I'm using OSX and I've installed protocol buffer with brew install protobuf command.
protoc command works okay.
I've generated MyProtocol.java by protoc.
I've installed protocol buffer for Java as its instruction(README.txt).
mvn install command created .m2 directory and I can find protobuf-java-2.4.1.jar file somewhere in the directory.
I wrote simple test Java code just importing MyProtocol.java and it complains could not find package com.google.protobuf.
So, I've just make jar file mvn package and add its directory as CLASSPATH and it compiled well.
javac -classpath <protobuf-dir>/jara/target/classes Test.java ./com/example/tutorial/AddressBookProtos.java
If I use maven's repository directory (~/.m2/repository), it complains again.
Doesn't maven make CLASSPATH for me if I install the package?
If not, how can I use installed package by maven to compile my code?
The Maven Dependency Plugin has a goal called build-classpath which does what you need. You can get usage hints on the Usage page
Maven doesn't change your setup, so it's up to you to set your CLASSPATH according to your need.
However there are at least two ways in which Maven can halp you:
You can use the Maven Assembly plugin to collect all your dependencies in a directory or an archive, so that you only need to add a single directory to your CLASSPATH in order to run your program;
You can use the Exec Maven plugin to add the running of your program as a goal in your POM and then run it with Maven.