I created a simple SpringBoot application with a Rest controller. When I run it, all the rules work. I would like to deploy it with code in tomkate. I collected the application in war`ku. Created a separate project to raise and deploy this brew:

public class TomcatLauncher { public static void main(String aArgs[]) { try { File catalinaHome = new File("путь"); Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); tomcat.setBaseDir(catalinaHome.getAbsolutePath()); tomcat.getServer().addLifecycleListener(new VersionLoggerListener()); File war = new File("путь до варки"); tomcat.addWebapp("/boot", war.getAbsolutePath()) tomcat.start(); tomcat.getServer().await(); }catch (Exception ex) { ex.printStackTrace(); } } } 

I start, throws out such an action, but everything works:

 .. Запущен томкат тра-та-та запускаем спрингбут ... тратата .. 2016-10-13 14:54:05.202 INFO 12472 --- [ost-startStop-1] osjeaAnnotationMBeanExporter : Registering beans for JMX exposure on startup 2016-10-13 14:54:05.222 INFO 12472 --- [ost-startStop-1] c.aamsystems.SpringBootTestApplication : Started SpringBootTestApplication in 2.758 seconds (JVM running for 7.855) 2016-10-13 14:54:05.243 INFO 12472 --- [ost-startStop-1] oaccC[Tomcat].[localhost].[/boot] : Marking servlet jsp as unavailable 2016-10-13 14:54:05.248 ERROR 12472 --- [ost-startStop-1] oaccC[Tomcat].[localhost].[/boot] : Servlet [jsp] in web application [/boot] threw load() exception java.lang.ClassNotFoundException: org.apache.jasper.servlet.JspServlet at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1284) ~[tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1118) ~[tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:520) ~[tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:501) ~[tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118) ~[tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1061) ~[tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1000) ~[tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4902) [tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5212) [tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152) [tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403) [tomcat-embed-core-8.5.4.jar:8.5.4] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) [tomcat-embed-core-8.5.4.jar:8.5.4] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_101] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_101] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_101] at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101] 

If you do addContext ("/ boot", war.getAbsolutePath ()); instead of addWebApp, there is no escape, but there is no application log itself.

JSP I do not have pages and will not.

Questions such:

  • How to remove this eXception?

  • Do I choose the right approach for all this business? In the future we plan to create spring boot applications in war.
    files and dynamically deploy them with code.

The dependencies in my project tomkata are as follows:

 apply plugin: 'java' apply plugin: 'spring-boot' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-web') } 

In the springBoot project, in principle, the same, but as I understand it, there should be providedRuntime

Mein application class:

 @SpringBootApplication public class SpringBootTestApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(SpringBootTestApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringBootTestApplication.class); } } 
  • Spring Boot has its own embedded Tomcat inside. Do you really want to take the war-nickname with Tomcat inside and run it on another Tomcat? - Slava Semushin
  • If you do this, then I will have to raise each application myself for a server if I want to work with several applications, as I understand it. Some kind of not very good scheme in my opinion - iteracia
  • @iteracia is a self-sufficient web application approach now being popularized. There is nothing fundamentally bad about it. - Nofate
  • As it is difficult for me to understand this approach. If you make 1 application, well, maybe 2, each with its own server, then I still understand it - you can deploy them independently, simply and quickly. But if I have 20-30 applications / services that are not large and EVERYONE will have on his http server, so also with a bunch of configuration objects inside, in my opinion this is a very unjustified load on the machine at least. - iteracia
  • @iteracia if you want 20-30 applications on 1-2 servers, then this is not Embedded Tomcat. Put a separate volume, determine the context-root in it with the config and send it to your descriptor, in which you specify the address of the war-archive of the application for deployment. - Maksim

3 answers 3

We had to resort to the following solution:

  1. We download Tomcat as a ZIP archive on the machine and unpack it into the working directory, for example, C:\project\runtime\apache-tomcat-8.0.32
  2. Create the C:\project\webapp directory where the context-root configuration file will be placed, and transfer the WAR archive with the application to it, say, ROOT.war
  3. Create a configuration file ROOT.xml with the following contents:

     <?xml version='1.0' encoding='utf-8'?> <Context docBase="C:/project/webapp/ROOT.war" override="false" reloadable="false" path="" useNaming="true" unpackWAR="false" > <Parameter name="spring.profiles.active" value="dev" override="true" /> <Parameter name="spring.config.location" value="file:///C:/project/properties/" override="true" /> <Parameter name="LOG_PATH" value="C:/project/logs/" override="false" /> </Context> 

Servlet context parameters are optional.

  1. In the conf\server.xml server configuration file, you need to change the host description as follows:

     <Host xmlBase="C:/project/webapp" appBase="" autoDeploy="true" name="yourproject.io" unpackWARs="false" deployXML="false"></Host> 

And then this exercise can be repeated for each application that will be located on its host.

  • @iteracia don't forget to press arrows if the answer was useful 😊 - Maksim
  • I would love to, I just have a reputation 0 - iteracia

Pay attention to the features that provides Spring Boot - http://projects.spring.io/spring-boot/ . One of which is the ability to create self-sufficient applications, if it is extremely important for you to deploy your war to external Tomcat, try using just Spring and not Spring Boot.

  • I really like the configuration whenever possible. Of course I’m wrong, but if you just use the spring, you’ll have to partially describe the configuration in xml files, which I don’t want at all. + trite 1 dependency in files better than 10+, at least to the eye. The fact that the buta feature is a self-contained application, I understand, but it interests me only at the development stage. - iteracia

I use this method for created by war-a and deployment ...

 @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); } } 

Inherit the SpringBootServletInitializer and override the method

 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) 

Add to pom.xml (If using maven)

 <packaging>war</packaging> 

And if Gradle, then add a line to build.gradle

 apply plugin: 'war' 

Add dependencies. If maven

 <dependencies> <!-- … --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <!-- … --> </dependencies> 

If gradle

 dependencies { // … providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' // … } 

Source Traditional deployment

  • Please try to publish detailed answers containing a specific example of the minimum solution, supplementing them with a link to the source. Answers –references (as well as comments) do not add knowledge to the Runet. - Nicolas Chabanovsky
  • Here is the line in the line I do as it says and throws out the exception. - iteracia
  • Can you show a stack of errors? And the code App.java te e Main class show? - Parviz Rozikov
  • Mein class added. And the error stack is what I described and there is a full stack. No more line, no less than this, only INFO logs - iteracia