I want to deploy my application using the embedded tomcat in spring -boot. I figured that I have to run the java -jar spring-boot-app.jar command, but I cannot find the jar file for the application anywhere.
On running mvn clean package I am able to generate a war file to deploy externally, how can I do the same with embedded tomcat ?
You need to remove following line from pom.xml
<packaging>war</packaging>
or replace war packaging with jar. Make sure you have spring-boot-maven-plugin in maven build plugins
The jar should then be available in target folder
To create an executable jar, we need to add the spring-boot-maven-plugin to our pom.xml. To do so, insert the following lines just below the dependencies section:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
For more information,refer this :
https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html
If you visit official Lombok Maven guide, you will see that it's scope should be provided.
When I create a new project from scratch using start.spring.io and add Lombok, it gets only <optional>true</optional> in resulting pom.
Then I package Spring boot app like this and out of curiosity decide to see what gets packaged inside of jar:
mvn clean package -DskipTests=true && unzip target/demo-0.0.1-SNAPSHOT.jar -d exploded
Lombok is packaged, does not matter if I set scope to provided or only have optional=true.
How to prevent Lombok from being included to Spring Boot jar?
My last thought was to try another goal which comes with Spring Boot plugin:
mvn spring-boot:repackage
But unfortunately it produces the following error:
repackage failed: Source file must be provided
Lombok will only be available in a seperate folder lib-provided instead of the usual lib folder if you are packaging war file.
In order to exclude lombok completely from the final jar/war file, you have to do this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.1.RELEASE</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
Please refer to Exclude a dependancy section of Spring Boot Maven Plugin https://docs.spring.io/spring-boot/docs/2.3.x/maven-plugin/reference/html/#repackage-example-exclude-dependency for more details.
Looks like it's a transitive dependency of one of your dependency. If you confirm it, you know what to do.
I have a spring-boot application that needs to:
Be deployable as a war in a servlet container
Be runnable via `mvn spring-boot:run``
I'd also like to be able to run this application in my IDE (Eclipse or IntelliJ IDEA Community) by right clicking on the main and running it.
Here are the interesting parts of my pom.xml (Note that I do not inherit from spring-boot-starter-parent pom):
...
<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>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Here's my SpringBootServletInitializer:
#Configuration
#EnableAutoConfiguration
#ComponentScan("com.company.theproject")
public class Application extends SpringBootServletInitializer
{
private static final Logger logger = LoggerFactory.getLogger(Application.class);
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(Application.class);
}
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
When running the main inside an IDE I get the following error:
org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
... 12 common frames omitted
Seems like mvn spring-boot:run does some more magic that does not happen when running the main directly.
Removing the provided scope from the spring-boot-starter-tomcat dependency fixes this issue but causes trouble when the war is run inside a servlet container.
Right now the only "fix" I've found is to run mvn spring-boot:run within IntelliJ IDEA instead of running the main directly. While this is an acceptable workaround, I'd still like to know why this doesn't work and if it can be fixed.
A workaround that is strongly inspired from https://youtrack.jetbrains.com/issue/IDEA-140041 is to start your main class with the test classpath (which includes the embedded servlet.)
Steps (IntelliJ 16):
Run -> Edit Configurations -> Add new configuration -> Pick Application type.
Set Main class to <your.main.class>
Set Use classpath of module to <*>_test (the test module!)
Ok and Run it!
I believe this could be related to https://youtrack.jetbrains.com/issue/IDEA-107048
IntelliJ IDEA is not injecting the provided dependencies into the CLASSPATH and as Andy stated this is why spring is unable to create the embedded servlet container.
They have a feature request since 2005 about this: https://youtrack.jetbrains.com/issue/IDEABKL-99
Workarounds mentioned in the comments includes having a fake module with the necessary libs and using it as classpath, using the -Xbootclasspath JVM argument or using custom maven profiles for running (compiled) vs building (provided).
I had the same problem using IntelliJ 2018.
Initially, Make sure that you have added the maven library for the spring project in your IntelliJ.
My solution is:
Go to Run -> Edit Configurations.
Select Application && choose your current project.
Check Include dependencies with "Provided" scope.
OK -> RUN
I was able to make this work by changing the scope of the spring-boot-starter-tomcat dependency to "compile" under Project structure->Dependencies tab. This doesn't effect pom.xml but allows this dependencies to be available to spring boot run configuration
Click here for image on where to change this setting in idea
mvn spring-boot:run includes provided dependencies when it's creating the classpath. It sounds like IntelliJ IDEA does not. Without Tomcat on the classpath, Spring Boot's unable to create an embedded servlet container which causes the exception you're seeing. Arguably this is a bug in IntelliJ as, if there's no container to provide the dependency, then it really needs to be on the classpath.
You may be able to fix the problem by overriding the default classpath that IntelliJ uses when running the main method to include the spring-boot-starter-tomcat dependency.
I find this page, and use the maven profile to manage the profiles.
<profiles>
<profile>
<id>PROD</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>DEV</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>TEST</scope>
</dependency>
</dependencies>
</profile>
</profiles>
and config the main class beforeLanuce,set the command
mvn clean compile -Pdev
I was able to work around this problem in Intellij IDEA 2017.2 by adding the provided libaray (spring-boot-starter-tomcat) to the project configuration.
Select File -> Project Structure. Select Libraries and add a new project library (type = From Maven...). Search for spring-boot-starter-tomcat using the dialog, select the correct version and add it by clicking on OK. The library is added to the list of external libraries.
The disadvantage is that if the Spring Boot version is changed then you will have to remember to delete this library and add the new version.
Using the profile and instructions below, you can add a profile to maven that allows development in IntelliJ without changing things for other environments.
<!-- Leave original dependency as-is -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>
<!-- Enable this profile to run in IntelliJ. IntelliJ excludes provided dependencies from compile by default. -->
<profile>
<id>intellij</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
Click the Maven Projects button on the right side of IntelliJ, and under Profiles, select intellij.
Follow these steps:
On the top right side of intellij window, click the drop down and select edit configuration and a new window will open.
In this window, on top left side, click "+" button and select sprint boot.
Then add you main class, and other details as shown in screenshot.
Now Run the application.
I have created a Maven plugin called foo that needs a JAR file say xyz.jar in order to compile and run. In the pom file of plugin project foo I have provided xyz.jar with provided scope in the dependencies section. I do not want to package the xyz.jar file in the plugin.
The plugin foo will be triggered by another project say bar in its install phase. So I added the plugin foo in the <build><plugins><plugin>...</plugin></plugins></build> section of the project bar. Project bar has the dependency of xyz.jar in its <dependencies> section. When I run install goal the classes present in the xyz.jar and which are referred by the plugin foo throw ClassNotFoundException at runtime.
How can I resolve this?
Every plugin and the Maven Project have separated classloaders, that's why it is not working. In general a plugin shouldn't depend on a dependency of the project. So remove the provided scope will solve it. Manipulating the classloader is very tricky.
I do not want to package the xyz.jar file in the plugin.
Well, it is not. It is just a reference.
I can't tell what your plugin is doing. I suggest to have a look at the plugins from Apache Maven or Codehaus Mojo to see how it is done.
Project and plugin dependencies are separated in Maven. If your plugin requires some external jars you need to provide them in <dependencies> section located in the plugin tag (not together with your project dependencies). For example:
<build>
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>yourPluginArtifactId</artifactId>
<version>...</version>
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>xyz</artifactId>
<version>...</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
I'm developing CXF web services with JDK 7 + Eclipse Juno + Maven 3 and deploying on a WebSphere 7 Application Server.
I've spent hours to fiund the right configuration of dependencies (a complex mix of runtime, system, compile and provided scopes) that the WAS accepts without conflicts, but with this configuration my jetty plug in does not work anymore.
How can I specify a classpath specific only for the Jetty plugin (hopefully a maven configuration)?
AFAIK, the only way to make the jetty plugin working properly regarding all those dependency issues is to specify all dependencies that are <provided> in your webapp as direct dependencies of the jetty plugin (and unfortunately, this brings kind of redundancy):
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.0.0.v20130308</version>
...
<dependencies>
<!-- put here all your dependencies with scope provided in your webapp -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0</version>
</dependency>
...
</dependencies>
</plugin>