Create war file from Spring:boot project in Eclipse - java

I am pretty new to Spring Boot and I have completed a application that works well on my localhost. As I have been told to deploy it outside my localhost on for example a webbhotel or simular I need to export the project as a war-file and not as a jar-file.
UPDATE!!
I run the project as a Springproject generated in Spring Initialzr and using Eclipse as a IDE.
In Eclipse I have followed the steps
<packaging>war</packaging>
and
<dependencies>
<!-- … -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- … -->
</dependencies>
from Spring Boot Referencepage
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file
In my project I use
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
Do I need to add the sprinng-boot-starter-tomcat dependency and add provided to that on aswell as tomcat-embed-jasper so that my dependency will be like this?
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
When I try to export to war-file in Eclipse, Eclipse can't find my project. It can find it if I try to export Java>JAR FILE but not if I try Web>WAR FILE
Do anyone know what I am doing wrong and if it is neccesary to export to a WAR-file to deploy to a external server?

You need to extend ****SpringBootServletInitializer**** in your #SpringBootApplication
You don't need to add the ****sprinng-boot-starter-tomcat**** dependency for war file generation
Use below configuration in pom.xml
<packaging>war</packaging>
Configure Build Path for your project and select JDK
Right click on project > Run As > Maven Install
It will generate the war file inside target folder.
Copy this war and deploy to any web/application server (I have renamed it to demo.war).
You can access the app by using your host name followed by the port and app name.

To generate WAR file in STS (Spring Tools Suite):
Run as-> Maven Install

After change to <packaging>war</packaging> in pom.xml.
utilize the command: mvn package

You can also proceed by selecting menus File -> Export -> Web -> War file

I generated a war file by the following steps:
Add above dependency.
Open command prompt.
cd into your project directory.
Run the command: mvn clean install.
Then a war file will be generated in the target directory.

If you are using maven, you can add tag to specify the type we want to create - jar or war. After that in sts you trigger a maven build and specify the goals - clean install and specify the number of threads you want to run for the build. In case you want to skip the test case you can give skipTest =true, or if you to run from command prommpt you can give -Dmaven.test.skip=true.
Once done, war file will be generated under target folder. (unless we specify a specific deployment folder)

Step1:- Create ServletInitializer file by extending SpringBootServletInitializer
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DemoApplication.class);
}
}
Step2:- Use #SpringBootApplication in main class
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Step3:- Package type as war in pom.xml
<packaging>war</packaging>
Step4:- Give build filename as like this
<build>
<finalName>demo</finalName>
</build>
Step5:- Add external tomcat dependency as provided scope
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Note:- For reference purpose, I'm adding my completed pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

Related

How to bundle/package latest version of custom library in maven web project without updating pom.xml?

I have a custom library - Dao.jar which contains the database persistence logic.
I push this jar to artifactory with new version each time there is a change in code as shown below :
mvn install:install-file -Dfile=C:\*****\target\Dao.jar -DgroupId=non-public.com.karthik -DartifactId=dao -Dversion=2.0 -Dpackaging=jar
I have another maven web project which has a dependency on this jar. This jar is also packaged/bundled in the maven webapp project/war.
<dependency>
<groupId>non-public.com.karthik</groupId>
<artifactId>dao</artifactId>
<version>2.0</version>
</dependency>
Currently, I am changing the version of dao dependency in the pom.xml & re-building the maven webapp project each time a new version of Dao.jar is available in the artifactory.
Is there any option to build the maven project with the latest version of Dao.jar without manually changing the dependency version in the pom.xml?
When Maven searches for a dependency, it first checks the local repository (~/.m2/repository). If it's not found, it tries other resources, such as remote repositories defined in the POM file or in the settings file (~/.m2/settings.xml).
By that logic, if you try to use a version of a local project that's not yet installed to the local repository, Maven will never be able to find it to use in another project.
To avoid changing version numbers all the time and manually building both projects. You could create a parent POM for both projects. The parent would then be able to recognize that one of the child projects depends on the other and build them in the correct order.
Based on Luciano's inputs, I have created a multi-module maven project/parent POM with 2 modules(dao & web)
Parent
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
..........
</dependencies>
</dependencyManagement>
<modules>
<module>web</module>
<module>dao</module>
</modules>
Child module # 1 - dao
<parent>
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dao</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
.........
</dependencies>
Child module # 2 - web(declared dao dependency in POM)
<parent>
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>web</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>com.karthik</groupId>
<artifactId>dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
.........
</dependencies>
When I run mvn package command at root path of parent pom, both modules - web.war and dao.jar are built. This method ensures always the latest version of dao.jar is packaged in web.war.

Make a maven dependency provided based on active spring profile

So I am building a spring boot web application, packaging as a war, and deploying to a tomcat application server.
I have the following dependency in my pom.xml for tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
The scope of this dependency needs to be provided in order to be able to deploy it to a tomcat instance. However, when I want to run the war via the spring boot CLI or via IntelliJ's default spring boot run configuration, I need to remove the <scope>provided</scope> in order for it to run the embedded tomcat.
My question is, is there some way to make the dependency conditionally provided based on an active spring profile, or some other method?
In your specific case, you can just do :
In the dependencies to run spring-boot with embedded tomcat :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
And in a profile to deploy under tomcat
<profile>
<id>tomcat</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
After, to build for a specific profile
mvn clean install -Ptomcat
You can't control dependencies via spring profiles. However you can control spring profiles by maven profiles and it can solve your problem.
You can declare several maven profiles in your application and provide different set of dependencies for each of them.
Then you can configure maven profiles to use particular spring profile.
Take a look on maven profiles and an example of such configuration in this thread
This is a solution that will work with both, jar and war packaging:
pom.xml
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>...</artifactId>
<groupId>...</groupId>
<version>0-SNAPSHOT</version>
<packaging>${packaging.type}</packaging>
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>...</start-class>
<packaging.type>jar</packaging.type>
...
</properties>
<dependencies>
<dependency>
<!-- Brings in Embedded Tomcat dependencies -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
</dependencies>
<profiles>
<profile>
<id>tomcat-war</id>
<properties>
<packaging.type>war</packaging.type>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
...
</profiles>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
...
Build artifact as jar:
mvn clean package
Build artifact as war:
mvn clean package -Ptomcat-war
Main class, that goes in <start-class> in pom.xml:
package ...
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

Add 3rd Party Jars with Maven Package

I have a very simple spring boot project and I use a 3rd party jar named jsoup.
When I run the project from Eclipse, the code is working fine. But when I use mvn clean package command and export it to an executable jar; project still works, but the parts that i use jsoup throws an exception that jsoup cannot be found. So my executable jar does not contains jsoup.
I searched and tried some methods but they did not work. If you can help me i will appreciate it.
Here is my pom file,
<modelVersion>4.0.0</modelVersion>
<groupId>com.tools</groupId>
<artifactId>parser</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>parser</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jsoup</groupId>
<artifactId>jsoup</artifactId>
<scope>system</scope>
<version>1.0</version>
<systemPath>${basedir}\src\lib\jsoup-1.10.1.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
In case when your 3-rd party jar has no Maven support and is not in any Maven repository, from where you can download it you need to make a Maven artifact for it and then deploy it into some Maven repository with Maven deploy plugin.
It can be your local repository, your company repository or any public repository you'd like to use.
please see it at:
Guide to deploying 3rd party JARs to remote repository
that is a Maven command format from it:
mvn deploy:deploy-file -DgroupId=<group-id> \
-DartifactId=<artifact-id> \
-Dversion=<version> \
-Dpackaging=<type-of-packaging> \
-Dfile=<path-to-file> \
-DrepositoryId=<id-to-map-on-server-section-of-settings.xml> \
-Durl=<url-of-the-repository-to-deploy>
You are using JSoup version 1.10.1 but use it with <scope>system</scope>. Maven doesn't include those jars in the artifacts build, just like <scope>provided</scope>. See also this Stackoverflow question and answers.
However JSoup is a normal jar like your other dependencies and is in Maven Central. As you can see here. Just add it as a regular dependency.
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.1</version>
</dependency>
Instead of what you have now. This will make it be included into your executable jar that Spring Boot will create for you. (And saves you from manually looking for that jar and updates etc.).

How to deploy spring boot app project to Heroku

I have created a simple server that uses JPA repository and returns a response in Json. It includes methods post and get. It is a spring starter boot app project and everything works on my localhost (I use postman to send and receive json objects). My problem is when I try to deploy to Heroku I run into many problems. I added a jetty-runner dependency and plugin. I also created a procfile as shown below:
web: java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war
Initially the target folder was empty and foreman start web was saying that it couldn't find my war file, so I added the following line to pom.xml:
<packaging>war</packaging>
But the project created an error, so I disabled maven nature of the project, then configured maven again and then it included pom.properties and pom.xml in the target folder. When I tried to deploy it, it said it was unable to access jetty jar file in target/dependency because there was no folder like that. So I did maven install and it installed the missing folders. Now I get the error that No transaction manager can be found, so I installed a dependency for jetty-plus and Atomikos. But now I still get the error that there is not transaction manager found and there is a java.net.bindexception.
I feel like I am really on the wrong path. I was wondering if anyone can tell me from the beginning on how to deploy a spring starter boot project to heroku. Any help would really be appreciated.
This is my pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Challenge-Server1</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-runner</artifactId>
<version>7.4.5.v20110725</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>copy</goal></goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-runner</artifactId>
<version>7.4.5.v20110725</version>
<destFileName>jetty-runner.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I found out that the deploying a spring boot application is a little different then deploying spring boot mvc project. Basically you don't need a jetty-runner dependency or plugin, you just do the following steps:
Configure a mvn project
mvn clean and install
Declare Procfile as: web: java $JAVA_OPTS -Dserver.port=$PORT -jar target/*.jar
All found from this site:
http://web.archive.org/web/20171018145733/http://nicholaspaulsmith.com/spring-boot-on-heroku/
I outlined some details in my blog
https://exampledriven.wordpress.com/2016/11/04/spring-boot-heroku-example/
The main point is to use the heroku maven plugin like this
heroku plugins:install heroku-cli-deploy
mvn clean install
# Creates an app with the specified name, without setting up a git remote
heroku create <APP-NAME> --no-remote
#deploys the jar file
heroku deploy:jar target/demo-0.0.1-SNAPSHOT.jar --app <APP-NAME>
but there are more details like how to set up a CI/CD pipeline

how to add project jar into eclipseworkspace\.metadata\.plugins\serverfolder\projectfolder\web-inf\lib

i am using Eclipse IDE. i have a maven projects as lmexadapter-core-api, lmexadapter-core-impl, lmex-moodle-api, lmexserver-mobile-api, lmexadapter-moodle-api, lmexadapter-moodle-impl. i have dependency in pom as below :
<parent>
<artifactId>lmexadapter-moodle</artifactId>
<groupId>com.platysgroup.lmex.adapter</groupId>
<version>1.0</version>
</parent>
<groupId>com.platysgroup.lmex.adapter</groupId>
<artifactId>lmexadapter-moodle-web</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>Maven Webapp Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.platysgroup.lmex.adapter.core</groupId>
<artifactId>lmexadapter-core-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.platysgroup.lmex.adapter.core</groupId>
<artifactId>lmexadapter-core-impl</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.platysgroup.lmex.server.mobile</groupId>
<artifactId>lmexserver-mobile-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.platysgroup.lmex.adapter.moodle</groupId>
<artifactId>lmexadapter-moodle-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.platysgroup.lmex.adapter.moodle</groupId>
<artifactId>lmexadapter-moodle-impl</artifactId>
<version>${project.version}</version>
</dependency>
i am using tomcat as my application server. i get all the jar except lmexadapter-moodle-api, lmexadapter-moodle-impl in my D:\EclipseWorskpace\ew-pg\lmexadapter.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\lmexadapter-moodle-web\WEB-INF\lib. because of this application is unable to locate class of lmexadapter-moodle-impl. what should i have to define so it will take both jar in a specified path as above.
please help me.
Thank you
Assuming current version of Eclipse and Maven plugin, is this something that can be solved by adding Maven dependencies to "project deployment assembly"?
If you have your project configured as Dynamic Web Project and Tomcat as server in Eclipse, this is under Project->Deployment Assembly->Add->java build path entries -> Maven dependencies.

Categories

Resources