Spring boot rest tomcat deployment error - spring

I have created a rest api using Spring rest and Spring boot. When I am trying to deploy it on tomcat on linux server, I get following error:
rror during ServletContainerInitializer processing
javax.servlet.ServletException: Failed to instantiate WebApplicationInitializer class at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:160
Caused by: java.lang.ClassNotFoundException: org.glassfish.jersey.server.ResourceConfig
I am following exact Spring boot instruction for tomcat. My question is that I am not using anything related to Jersey for my application (apis) then why it is looking for Jersey related code, and how I can fix it.
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
Contoller code:
#RestController
#RequestMapping("/rest/cmscontent")
public class BatchController {

If you add spring-boot-starter-web into your POM file as dependency,
it will include embedded web container (Tomcat by default) automatically.
Therefore, just execute JAR directly without deploying it to any web container.

Related

What Is the Correct Way To Use AbstractReactiveWebInitializer

I've got a Spring WebFlux application running successfully as a standalone spring boot application.
I am attempting to run the same application in a Tomcat container, and following the documentation, I've created a class that extends AbstractReactiveWebInitializer. The class requires that I implement a method getConfigClasses that would return classes normally annotated with #Configuration. If the working spring boot app started with a class called ApplicationInitializer, then the resulting implementations would look like this:
#SpringBootApplication(scanBasePackages = "my.pkg")
#EnableDiscoveryClient
#EnableCaching
public class ApplicationInitializer {
public static void main(String... args) {
SpringApplication.run(ApplicationInitializer.class, args);
}
}
and
public class ServletInitializer extends AbstractReactiveWebInitializer {
#Override
protected Class<?>[] getConfigClasses() {
return new Class[] {ApplicationInitializer.class};
}
}
When deployed, the only thing that starts is ApplicationInitializer, none of the autoconfigured Spring Boot classes (Cloud Config, DataSource, etc) ever kick off.
The documenation states this is the class I need to implement, I just expected the remainder of the spring environment to "just work".
How should I be using this class to deploy a Reactive WebFlux Spring Boot application to a Tomcat container ?
Edit:
After some additional research, I've narrowed it down to likely just Cloud Config. During bean post processing on startup, the ConfigurationPropertiesBindingPostProcessor should be enriched with additional property sources (from cloud config), but it appears to be the default Spring properties instead, with no additional sources.
The misisng properties is causing downstream beans to fail.
Spring Boot does not support WAR packaging for Spring WebFlux applications.
The documentation you're referring to is the Spring Framework doc; Spring Framework does support that use case, but without Spring Boot.
you can extend SpringBootServletInitializer, add add reactive servlet on onStartup method

Convert a Spring MVC application to Spring Boot - BeanCurrentlyInCreationException issue

I have a Spring MVC application, using Hibernate for my entities persistence management. I am able to build, deploy and run it on some application server such as glashfish or tomcat, all is fine.
Now, I want to convert it into a Spring Boot application. I added the following class:
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
}
}
and added the spring-boot, spring-boot-autoconfigure, and spring-boot-starter-tomcat dependencies to my pom.
Alas, when trying to run the application, I get the following error:
BeanCurrentlyInCreationException: Error creating bean with name
'MyClassDAO': Bean with name 'MyClassDAO' has been injected into
other beans [MyOtherClassDAO] in its raw version as part of a circular
reference, but has eventually been wrapped. This means that said other
beans do not use the final version of the bean. This is often the result
of over-eager type matching - consider using 'getBeanNamesOfType' with
the 'allowEagerInit' flag turned off, for example.
I don't know how to use 'getBeanNamesOfType' and set the allowEagerInit off (I do not use XML configuration). Of course, I'm not sure this would solve my issue anyway.
Any ideas on how I can fix this?
If it's really some intilization issue then i believe the you must be having your class in other package and due to some cache issues it doesn't include those classes in class path to scan in container so to do this manually you can put a annotation just below #springbootapllication is #EnableComponentScan("enter the package name of the class which is not initializing") also on that dao class put #service or #component annotation to let the application include then in container

SpringBoot, run a daemon as CommandLine (JAR) and inside Tomcat (WAR)?

I want to create a Java deamon process (MQ processor) which can be run both from the commandline (java -jar ...) but also as WAR inside a JEE Container like Tomcat. It should automatically start once the WebApp starts. This App is not going to have a WebGUI.
It seems that I can use SpringBoot for this. SpringBoot can both create WAR and JAR-files.
My question is: should I use SpringBoot ApplicationRunner for a portable daemon?
What is the best practice/recipe to create a portable (CLI/WebApp) daemon process with SpringBoot?
How does this work under the hood? If I use ApplicationRunner and create a WAR, does SpringBoot create a Servlet of this?
Tx
ApplicationRunner is new in Spring Boot 1.4. It is similar to CommandLineRunner of Spring Boot 1.3. It isn't involved in the wiring up of the Application context as such that interface wouldn't be responsible for creating any Servlets in the WAR deployment. Here is details on deploying your app as a WAR:
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
The SpringBootServletInitializer is what will create the servlet.
Now I am not sure how you are setting up the MQ processor but if it is wired up as a bean and has some listener thread for messages on a queue then you don't really need the ApplicationRunner. You would just need to wire up the processor as a bean and have a #PostConstruct annotation on it so that you can start the listener thread. If you don't have control of the annotations on the bean then you can use the ApplicationRunner and have it Autowired with the processor bean. The runner would then start up the listener thread.

cannot resolve reference to bean 'jmsconnectionfactory' when using spring boot + spring integration

I had a problem i'm using hornetq using spring boot and had to create a jmschannel in spring configuration using spring integration <int-jms:channel id="jmsChannel" queue-name="${spring.hornetq.embedded.queues}" connection-factory="jmsConnectionFactory">
<int-jms:interceptors><int:wire-tap channel="logger"/></int-jms:interceptors>
</int-jms:channel>
This is working fine in local when loading with undertow, when deployed the war to Jboss it is throwing up saying bean named jmsConnectionFactory not found, any help is greatly appreiciated
Looks like there is nothing to do with the Spring Integration, but only Spring Boot stuff, which is called deployable war:
The first step in producing a deployable war file is to provide a SpringBootServletInitializer subclass and override its configure method. This makes use of Spring Framework’s Servlet 3.0 support and allows you to configure your application when it’s launched by the servlet container. Typically, you update your application’s main class to extend SpringBootServletInitializer:
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}

Production equivalent to Spring Boot EmbeddedServletContainerCustomizer

My question relates to Spring Boot and how to configure error pages in a production web app running in cloudfoundry.
In the Spring IO Sagan reference application, I noticed in the MvcConfig, the following code:
#Configuration
public static class ErrorConfig implements EmbeddedServletContainerCustomizer {
#Override
public void customize(ConfigurableEmbeddedServletContainer factory) {
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/404"));
factory.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500"));
}
}
Is this configuration used in the cloud too? If so why is it named: EmbeddedServletContainerCustomizer? If not what is the equivalent for the cloud?
Yes, you can use EmbeddedServletContainerCustomizer when deploying to the cloud. Sagan itself is doing exactly that on CloudFoundry for the spring.io website.
The "embedded" in the name of EmbeddedServletContainerCustomizer refers to the fact that the servlet container is embedded in your application's executable jar file. It's the recommended approach for cloud deployment.

Resources