Spring boot without embedded servlet container - spring-boot

I have a spring-boot web application, but I don't want to start it in embedded Tomcat/Jetty. What is the correct way to disable embedded container?
If I do smth like:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
I keep getting
org.springframework.context.ApplicationContextException: Unable to start embedded container;

Since you are using Maven (instead of Gradle) check out this guide and this part of the official documentation.
The basic steps are:
Make the embedded servlet container a provided dependency (therefore removing it from the produced war)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Add an application initializer like:
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class WebInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
That class is needed in order to be able to bootstrap the Spring application since there is no web.xml used.

Related

Spring Boot + Apache Wicket - JSP pages are downloading instead of rendering

My application is built using Spring Boot 2.1.4 + Apache wicket and some legacy web servlet and JSP pages. But JSP pages are getting downloaded instead of rendering.
I have provided the following dependencies to compile JSP for embedded tomcat.
pom.xml
<dependencies>
<dependency>
<groupId>com.giffing.wicket.spring.boot.starter</groupId>
<artifactId>wicket-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-spring</artifactId>
<version>8.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
I tried with moving all my JSP pages to
main/java/resources/META-INF/resources for default spring boot classpath.
Booting up the application using the following code:
#SpringBootApplication
public class ClaimIQWicketApplication
extends WicketBootStandardWebApplication {
public static void main(String[] args) throws Exception {
context = SpringApplication.run(ClaimIQWicketApplication.class, args);
}
}
I expect my JSP pages should get rendered instead of download.
Please help me if anybody else has encountered such issue and found any solution.

Spring WebFlux and MVC config in the same library

I'm looking for a way to implement a "switch" in my library so that it would be able to work in 2 modes - reactive and blocking.
As of now i have two libraries doing basically the same thing - set of filters and interceptors and a factory providing end user with preconfigured WebClient/RestTemplate, Authentication and Authorization.
I found that SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE) is supposed to force application to run in either a reactive or an mvc mode. However, when i add mvc-dependency i can see in log that Tomcat is being chosen as a container to run the app
Starting service [Tomcat]
Here's my pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
And the Application class
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
app.run(args);
}
}
Am i doing something wrong or the property is not supposed to allow switching between Netty and Tomcat to start with?

Camel ActiveMQ + Spring boot not reading spring activemq configurations

I am trying a very simple route with Spring Boot 1.5.2.RELEASE + Camel (Spring Boot Starter) + ActiveMQ, which is to read from a particular queue and then log it. However, it looks like it is not picking up my spring.activemq configuration for URL as I see in the log it is trying to connect to a different url and it continues to connect it and the my spring boot app never starts. The questions are based on my configuration that I am providing below how can I do the below:
Fix the configuration to allow spring's activemq configuration
Configure maxReconnectAttempts so that it does not try to connect forever if the URL is not reachable, which could be possible if the ActiveMQ instance goes down
Any assistance would be greatly appreciated. I did search relevant questions on stackoverflow but none gave me a solution to the issue I am facing
Error I am seeing on the console and this continues to like 60-70 attempts and counting. As you can see the broker URL that camel is picking up is some default URL that probably spring has configured by default
Failed to connect to [tcp://localhost:61616] after: 10 attempt(s) continuing to retry.
Here are my current configurations / code:
pom.xml - relevant portion
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud is part of the project where I am configuring camel routes -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-dependencies</artifactId>
<version>2.19.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- I have this as the same project works as a web app as well
and therefore I do not need the
camel.springboot.main-run-controller=true configuration to be set
which is as per camel's spring boot documentation-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Camel - start -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-camel</artifactId>
</dependency>
<!-- Camel - end -->
</dependencies>
application.yml (Spring Boot ActiveMQProperties)
spring:
activemq:
brokerUrl: tcp://my.company.host:[port] //This port is up and running
user: user
password: password
Camel Route in JAVA
package com.mycamel.route;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
#Component
public class SampleAmqCamelRouter extends RouteBuilder {
#Override
public void configure() throws Exception {
from("activemq:some.queue").to("log:com.mycamel.route?level=INFO&groupSize=10");
}
}
First you should add the spring-boot-starter-activemq dependency to your pom.xml. Then you can use its AutoConfiguration capabilities which will create a ConnectionFactory based on the properties you have specified in your application.yml.
After that you have to configure Camel's ActiveMQComponent too. If you would like to reuse the ConnectionFactory (which created by the autoconfig) then it can be achievable with the following:
#Configuration
public class ActiveMQComponentConfig {
#Bean(name = "activemq")
public ActiveMQComponent createComponent(ConnectionFactory factory) {
ActiveMQComponent activeMQComponent = new ActiveMQComponent();
activeMQComponent.setConnectionFactory(factory);
return activeMQComponent;
}
}
You can find more information in Camel's ActiveMQ documentation.

Spring boot , apache camel and hawtio: cannot send message to endpoint

I'm trying to integrate hawtio in a spring-boot application using apache camel. I followed Spring-Boot Embedded Wars and added HawtioConfiguration from How to run hawt.io in spring boot application with embedded tomcat (except for the kubeservice and kubepod which are not in io.hawt.web package)
So, that works, up to the point where I try to manualy send a message to a direct endpoint from the hawtio interface ( http://localhost:8080/hawtio/index.html#/camel/sendMessage?tab=camel&nid=root-org.apache.camel-camel-1-endpoints-%22direct:%2F%2Fdummy%22 ) . The following warning appears, and no message is sent:
Camel does not support sending to this endpoint.
So, did I forget anything ? Here is my set up : springboot 1.3.3.RELEASE with the following dependencies :
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.hawt</groupId>
<artifactId>hawtio-springboot</artifactId>
<version>1.4.64</version>
</dependency>
<dependency>
<groupId>io.hawt</groupId>
<artifactId>hawtio-core</artifactId>
<version>1.4.64</version>
</dependency>
and the Application.java :
#SpringBootApplication
#EnableHawtio
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Application {
#Autowired
private ServletContext servletContext;
public static void main(String[] args) {
System.setProperty(AuthenticationFilter.HAWTIO_AUTHENTICATION_ENABLED, "false");
SpringApplication.run(Application.class, args);
}
#PostConstruct
public void init() {
final ConfigManager configManager = new ConfigManager();
configManager.init();
servletContext.setAttribute("ConfigManager", configManager);
}
}
Thanks !
edit: using hawtio as a standalone app and connecting to springboot works fine
edit2: moving on, I used hawtio as a war on another project (same version) , deployed on a tomcat 7. Same issue, cannot send to a direct endpoint.
go figure.
The option of using hawtio as war works very well with application using spring boot and camel, I am already using it successfully.
check the hawtio github code example, it contains good samples to try
https://github.com/hawtio/hawtio
Also I will share my github link with sample's of using hawtio wat or as maven plug-in.
I had the same problem: I could not use hawt.io to send to a direct endpoint (nor any other endpoint). Maybe it is a general Bug/ unimplemented feature in hawt.io?
However, the following was possible:
Copy the Endpoint URL
Select the context node in hawt.io
Click on "Operations"
Use the method sendStringBody(java.lang.String,java.lang.String) to send a string to that endpoint
First parameter is the endpoint URI that you can paste in

deploy spring boot websocket sample application to tomcat7

Following tutorial helped me to get a spring boot application up and running real fast: https://spring.io/guides/gs/messaging-stomp-websocket/
But now I'm stuck trying to generate a war file and deploying it on my tomcat7 application server.
I followed the [instructions][1] to create a deployable war file, but this just isn't working. I don't see any errors in the logs, but I don't see my nice sample application either when I browse to http://localhost:8080.
Here are the steps I took to generate a war file:
1) Modify pom.xml by changing the packaging to war and marking the spring-boot-starter-websocket as provided
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
</dependency>
</dependencies>
2) Modify Application.java to override the SpringBootServletInitializer configure method.
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3) Then I run
mvn clean package
and deploy the generated war-file, but I just keep getting the default Tomcat welcome page, when I browse to http://localhost:8080/.
I also tried changing the application contextPath by adding the following application.properties:
server.contextPath=/websocketclient
server.port=8082
But this doesn't solve the problem.
I get it working, I am using Tomcat 8.
Take a look at my code here:
https://github.com/pauldeng/gs-messaging-stomp-websocket
Read and edit the pom file accordingly and run mvn package to create the package specified.
I made a mistake in my pom.xml, the provided scope shouldn't be added to the spring-boot-starter-websocket artefact. But you should add the spring-boot-starter-tomcat artefact with the provided scope.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
</dependency>
</dependencies>
I also had to modify my javascript to contact the websocket, which is now under /gs-messaging-stomp-websocket-0.1.0
var socket = new SockJS('/gs-messaging-stomp-websocket-0.1.0/hello');
The deployed application war needs to be called ROOT.war otherwise you will have to configure server.xml.
Second you should turn on the NIO connector for websockets see server.xml and http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html

Resources