Running multiple SpringBootApplication classes from a single maven project - maven

Is there a way to specify which SpringBootApplication's main class to run when running mvn spring-boot:run? The docs say I can use mainClass parameter to specify which main class to run. But I am not sure how to specify it in command line. I have tried mvn -DmainClass=mypackage.myclass spring-boot:run but it didn't work.

I got it working by having a placeholder in the plugin configuration of spring-boot
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${mainclass}</mainClass>
</configuration>
</plugin>
and then running different classes
mvn -Dmainclass=mypackage.myclass spring-boot:run

Two answers to your question
You have to create a MANIFEST.MF file in src/main/resources/META-INF/MANIFEST.MF and give an attribute like this as given below
Main-Class= com.yourfilename
You can use maven jar plugin to define main-class configuration in your manifest file, please use this links below which will help you.
link 1
link 2

Related

Why do I need to add Spring Boot plugin but I don't need to add install plugin in Maven pom.xml?

I'm learning about Maven and I want to ask you why do I need to add the Spring Boot Maven plugin in the pom.xml if I want to run it?
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
But I don't need to add the install, deploy, compiler, clean and all other plugins. How does this plugins come in my project?
So I need to add this code in the pom.xml if I want to use this command: mvn spring-boot:run, but I don't need to add any code for these commands: mvn install:install, mvn compiler:compile, etc. I don't understand how. Thank you!
Compile, install, test, etc is part of the default maven lifecycle, specified in default-bindings.xml in your maven installation. This lifecycle configuration connects lifecycle stages (for instance compile) with plugins (maven-compiler-plugin), and is inherited by all your maven projects.
The spring-boot-maven-plugin on the other hand is not part of the any default lifecycle, and thus needs to be specified in each project.

Can maven exec:java be used with an arbitrary java class from the command iine

We have a few java/scala classes with main methods that would be useful to run via mvn exec:java.
Is it possible to do so without specifying the classes in the pom.xml? The examples that I have seen look like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions><execution>
<goals><goal>java</goal></goals>
</execution></executions>
<configuration>
<mainClass>some.main.MyClass</mainClass>
</configuration>
</plugin>
And then get executed as:
mvn exec:java -Dexec.mainClass="some.main.MyClass"
The intent is to be able to run
mvn exec:java -Dexec.mainClass="some.other.main.OtherClass"
even though it were not specified in the pom.xml.
When attempting to run that the error is
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli) on project sentiment: An exception occured while executing the Java class. myapp.MyMain
In other words the class specified on the command line is ignored in favor of the one listed in the pom.xml.
The Documentation at https://www.mojohaus.org/exec-maven-plugin/usage.html
says:
If you want to execute Java programs in the same VM, you can either
use the command line version
mvn exec:java -Dexec.mainClass="com.example.Main" [-Dexec.args="argument1"]
This works without adding anything to your pom.
As written in the comment, this only works, if you don't have a configuration in your pom. If you do have a configuration in your pom, you can use a property in it, which can be overridden from the command line
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions><execution>
<goals><goal>java</goal></goals>
</execution></executions>
<configuration>
<mainClass>${my.mainClass}</mainClass>
</configuration>
</plugin>
and predefine the property (nested directly in <project>)
<properties>
<my.mainClass>some.main.MyClass</my.mainClass>
</properties>
then you can run with
mvn exec:java -Dmy.mainClass="aaa.Test"
Looking from your usage if you are using the -Dexec.mainClass everytime, i would suggest you can get rid of the mainClass in the plugin configuration. The benefit of defining the mainClass would be to run like : mvn exec:java & it picks the main class from your defined class in pom.xml.
Once you remove the mainClass from pom.xml, you should be able to use any mainClass in the maven exec plugin usage from command line.

Wildfly Deploy Maven - Remove Version

I want to deploy a war that I have created using maven to wildfly using the wildfly-maven-plugin.
The final name of the war is something like: my-war-1.0.war
The war also contains a jboss-web.xml specifying the context root (e.g. /my-war)
Problem Description
If I now deploy the war to wildfly I will get a "my-war-1.0.war" deployment.
If I later want to deploy a new version (e.g. the war is now named my-war-1.1.war) I get a conflict as the context root is already known but the deployment has a new name.
Is there a way using the wildfly-maven-plugin to deploy a "my-war.war" instead?
I need to keep the original final build name inside the maven build for versioning and deploying to our nexus.
The simplest solution is to use the <finalName/> element on the <build/> configuration.
<build>
<finalName>${project.artifactId}</finalName>
</build>
You can use the maven war plugin to rename the final war. For Eg:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>my-war</warName>
</configuration>
</plugin>
</plugins>
</build>
This will always generate the war with the name my-war.war in your "target" directory.
I found out that I can use the parameters <name/> and <runtimeName/> inside the <configuration/> of the maven-wildfly-plugin.
That way I can specify what the deployment should be called on the server and each time just replace it. It is important to have the two parameters end in ".war", otherwise you will get a 404 error.
Using this method I can keep the original name of the final build result containing the version (my-app-1.0.war) and archive it inside our internal nexus repository.

How to force Maven to always create a new jar file?

If all classes are up-to-date "Nothing to compile - all classes are up to date"
so will maven create jar again?
As I am seeing in my log that jar is not creating again. so maven come to know that all classes are up-to-date.
Question: is there any process or another thing which work on this?
The Maven Jar Plugin will create a jar via its jar goal if none exists or skip its creation if existing but nothing changed.
You can force the creation of the jar via its forceCreation option (since version 2.2). From official documentation:
Require the jar plugin to build a new JAR even if none of the contents appear to have changed. By default, this plugin looks to see if the output jar exists and inputs have not changed. If these conditions are true, the plugin skips creation of the jar. This does not work when other plugins, like the maven-shade-plugin, are configured to post-process the jar. This plugin can not detect the post-processing, and so leaves the post-processed jar in place. This can lead to failures when those plugins do not expect to find their own output as an input. Set this parameter to true to avoid these problems by forcing this plugin to recreate the jar every time.
Its default value is at false, which explains the behavior you are having.
If you want to force it always, you can add to your pom file:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<forceCreation>true</forceCreation>
</configuration>
...
</plugin>
</plugins>
</build>
...
</project>
Or just on a single build, invoke it as following:
mvn package -Djar.forceCreation=true
So, going back to your question:
is there any process or another thing which work on this?
The answer is: Yes, the Maven Jar Plugin works on this and the option above will change its behavior.

How to replace a property in a POM in a Maven/Jenkins job?

I have a project with client and server components. Both have their own Maven multi-module build projects.
The correct server version must be referenced in various frontend modules. To accomplish this I set a property in my client parent POM like this:
<properties>
<server.version>1.2.3</server.version>
</properties>
Now I'd like to update the version number in the POM (i.e. not just injecting a different version from the command line with -D...) during/after a Jenkins build job. Is there a way to do this?
I found the com.google.code.maven-replacer-plugin:replacer Maven plugin which works perfectly for my case. It accepts an xpath and a regex to define what to replace in an XML file.
Example plugin configuration:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<configuration>
<file>${project.basedir}/pom.xml</file>
<xpath>/project/properties/server.version/text()</xpath>
<token>^.*$</token>
<value>${newServerVersion}</value>
</configuration>
</plugin>
And the plugin can be run for each affected maven module:
mvn --non-recursive replacer:replace -DnewServerVersion=xxxx
At itembase we use Jenkins Pipeline Plugin. It comes with some useful built in functions like for example readMavenPom and writeMavenPom. So in your build pipeline you could do something like:
def pom = readMavenPom file: 'pom.xml'
//Do some manipulation
writeMavenPom model: pom
Did you check maven versions plugin?
(Tbe website is shutdown but the plugin page is still avaiable in google cache)
mvn -DnewVersion=<version> versions:set

Resources