Java – spring boot Jar – missing embeddedservletcontainerfactory
Spring boot (1.2.7) web application (responding to SSL request) runs well on IntelliJ idea
Build a jar artifact to run from the command line and throw an error at startup
org. springframework. context. Applicationcontextexception: unable to start embedded container; The nested exception is org springframework. context. Applicationcontextexception: unable to start embeddedwebapplicationcontext. Because the embeddedservletcontainerfactory bean is missing
problem
>How can I avoid this error? > If I need to declare an embeddedservletcontainerfactory, how can I make its servletcontainer handle my controller request?
Try a solution
Embeddedservletcontainerfactory was added as requested in error The project now starts with the jar, but the controller will not receive the request as it did from the IntelliJ runtime
This is the application after I added embeddedservletcontainerfactory Class look
package org.coursera.diabetes; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.support.ConnectionSource; import diabetes.common.model.*; import org.apache.catalina.connector.Connector; import org.apache.coyote.http11.Http11NioProtocol; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.core.env.Environment; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import java.io.File; import java.io.IOException; import java.sql.sqlException; import java.util.ArrayList; import java.util.List; @SpringBootApplication public class Application { private static final Logger logger = LoggerFactory.getLogger(Application.class); private static final String dbUrl = "jdbc:h2:mem:testdb"; public static void main(String[] args) { SpringApplication.run(Application.class,args); } @Bean @Profile("production") public EmbeddedServletContainerFactory servletContainer(@Value("${keystore.file}") Resource keystoreFile) { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); //factory.setPort(8443); String absoluteKeystoreFile = ""; try { absoluteKeystoreFile = keystoreFile.getFile().getAbsolutePath(); logger.info(String.format("******** keystore: %s",absoluteKeystoreFile)); } catch (IOException e) { e.printStackTrace(); } tomcat.addAdditionalTomcatConnectors(createSslConnector(absoluteKeystoreFile)); return tomcat; } private Connector createSslConnector(String absKeystoreFile) { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); try { connector.setScheme("https"); connector.setSecure(true); connector.setPort(8443); protocol.setSSLEnabled(true); protocol.setKeystoreFile(absKeystoreFile); protocol.setKeystorePass("changeit"); protocol.setKeyAlias("tomcat"); return connector; } catch (Exception ex) { throw new IllegalStateException("can't access keystore: [" + "keystore" + "] or truststore: [" + "keystore" + "]",ex); } } }
note
The spring boot (WEB) application runs well on IntelliJ idea, responds to HTTPS requests, and does not need to be in application Do anything in properties:
security.require-ssl=true server.port=8443 server.ssl.key-store=src/main/resources/private/keystore server.ssl.key-store-password=changeit server.ssl.key-password=changeit
To start a jar artifact from the command line, I use:
java -Dspring.profiles.active=production -Dkeystore.file=file:///$PWD/keystore -jar diabetes-spring.jar
There is no error when the jar starts, but the HTTPS web request (working from IntelliJ) only returns Apache / Tomcat 404 "the requested resource is unavailable"
EDITS
Running the jar with - ddebug will output the following information (I omitted all the debug messages application.properties/application/application-production.properties that did not find the configuration file, which do not seem relevant)
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__,| / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: 2015-11-13 14:16:39.980 INFO 47600 --- [ main] org.coursera.diabetes.Applica tion : Starting Application on Bakers-MacBook-Pro.local with PID 47600 (/User s/baker/coursera-android/MoCCA-15/spring-tests/diabetes_root2/diabetes-spring/out/artifa cts/diabetes_spring_jar/diabetes-spring.jar started by blam in /Users/blam/coursera-and roid/MoCCA-15/spring-tests/diabetes_root2/diabetes-spring/out/artifacts/diabetes_spring _jar) 2015-11-13 14:16:39.983 DEBUG 47600 --- [ main] o.s.boot.SpringApplication : Loading source class org.coursera.diabetes.Application 2015-11-13 14:16:40.011 DEBUG 47600 --- [ main] o.s.b.c.c.ConfigFileApplicati onListener : Activated profiles production 2015-11-13 14:16:40.011 DEBUG 47600 --- [ main] o.s.b.c.c.ConfigFileApplicati onListener : Loaded config file 'file:./config/application.properties' 2015-11-13 14:16:40.020 INFO 47600 --- [ main] ationConfigEmbeddedWebApplica tionContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbe ddedWebApplicationContext@23faf8f2: startup date [Fri Nov 13 14:16:40 WET 2015]; root o f context hierarchy 2015-11-13 14:16:40.022 DEBUG 47600 --- [ main] ationConfigEmbeddedWebApplica tionContext : Bean factory for org.springframework.boot.context.embedded.AnnotationConf igEmbeddedWebApplicationContext@23faf8f2: org.springframework.beans.factory.support.Def aultListablebeanfactory@6cc7b4de: defining beans [org.springframework.context.annotatio n.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.inter nalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalrequired AnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProc essor,application]; root of factory hierarchy 2015-11-13 14:16:40.220 DEBUG 47600 --- [ main] ationConfigEmbeddedWebApplica tionContext : Unable to locate MessageSource with name 'messageSource': using default [ org.springframework.context.support.DelegatingMessageSource@20ce78ec] 2015-11-13 14:16:40.221 DEBUG 47600 --- [ main] ationConfigEmbeddedWebApplica tionContext : Using ApplicationEventMulticaster [org.springframework.context.event.Simp leApplicationEventMulticaster@393671df] 2015-11-13 14:16:40.226 WARN 47600 --- [ main] ationConfigEmbeddedWebApplica tionContext : Exception encountered during context initialization - cancelling refresh attempt org.springframework.context.ApplicationContextException: Unable to start embedded conta iner; nested exception is org.springframework.context.ApplicationContextException: Unab le to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactor y bean. at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRe fresh(EmbeddedWebApplicationContext.java:132) at org.springframework.context.support.AbstractApplicationContext.refresh(Abstr actApplicationContext.java:474) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refr esh(EmbeddedWebApplicationContext.java:117) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:68 9) at org.springframework.boot.SpringApplication.run(SpringApplication.java:321) at org.springframework.boot.SpringApplication.run(SpringApplication.java:969) at org.springframework.boot.SpringApplication.run(SpringApplication.java:958) at org.coursera.diabetes.Application.main(Application.java:40) Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:182) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:155) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:129) ... 7 common frames omitted 2015-11-13 14:16:40.227 INFO 47600 --- [ main] .b.l.ClasspathLoggingApplicationListener : Application Failed to start with classpath: [file:/Users/baker/coursera-android/MoCCA-15/spring-tests/diabetes_root2/diabetes-spring/out/artifacts/diabetes_spring_jar/diabetes-spring.jar] 2015-11-13 14:16:40.228 ERROR 47600 --- [ main] o.s.boot.SpringApplication : Application startup Failed org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:132) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:117) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:689) at org.springframework.boot.SpringApplication.run(SpringApplication.java:321) at org.springframework.boot.SpringApplication.run(SpringApplication.java:969) at org.springframework.boot.SpringApplication.run(SpringApplication.java:958) at org.coursera.diabetes.Application.main(Application.java:40) Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:182) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:155) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:129) ... 7 common frames omitted
Solution
In IntelliJ idea – project structure – artifact – available elements, all gradle dependency libraries need to be extracted into the output root so that the jars of spring boot applications can run normally from the Java command line execution
After changing the jar artifact to, I can build the jar and run it from the command - line JVM
For the default tomcatembeddedservletcontainerfactory running on HTTPS / SSL port 8443, specify equal to application Java command line parameters required in properties
Namely
java -jar your-spring.jar --security.require-ssl=true --server.port=8443 --server.ssl.key-store=keystore --server.ssl.key-store-password=changeit --server.ssl.key-password=changeit