generate - spring boot war to external tomcat
Spring Boot War desplegada en Tomcat (11)
Estoy tratando de implementar una aplicación Spring Boot en Tomcat, porque quiero implementar en AWS. Creé un archivo WAR, pero no parece ejecutarse en Tomcat, aunque es visible.
Detalles:
0. Aquí está mi aplicación:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class App {
public static void main(String[] args) {
SpringApplication.run(SampleController.class, args);
}
}
@Controller
@EnableAutoConfiguration
public class SampleController {
@RequestMapping("/help")
@ResponseBody
String home() {
String input = "Hi! Please use ''tag'',''check'' and ''close'' resources.";
return input;
}
}
application.properties tiene lo siguiente:
server.port=${port:7777}
-
Después de leer varias pages y question-answers , agregué lo siguiente a mi POM:
http://maven.apache.org/xsd/maven-4.0.0.xsd "> 4.0.0
<groupId>com.niewlabs</groupId> <artifactId>highlighter</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <java.version>1.8</java.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.1.9.RELEASE</version> </parent> <dependencies> <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> </dependencies>
-
Ejecuté "mvn package" y obtuve el archivo WAR (tamaño 250Mb), que puse en la carpeta "webapps".
- Inicié Tomcat y puedo ver mi aplicación en la lista, en mi caso "/highlighter-1.0-SNAPSHOT".
- Al hacer clic en el enlace de la aplicación, aparece la página "Estado 404".
- Cuando ejecuto la aplicación Spring Boot solo, sin contenedor, se ejecuta en localhost: 7777, pero no hay nada cuando la ejecuto en Tomcat.
Actualización: hay otra reference . No estoy seguro de lo útil que es.
Solución para personas que usan Gradle
Agregue el complemento a
build.gradle
apply plugin: ''war''
Agregar dependencia proporcionada a tomcat
dependencies {
// other dependencies
providedRuntime ''org.springframework.boot:spring-boot-starter-tomcat''
}
Actualice 2018-02-03 con Spring Boot 1.5.8.
En pom.xml, debe decirle al plugin Spring cuando se está construyendo que es un archivo war por cambiar el paquete a war, así:
<packaging>war</packaging>
Además, debe excluir el tomcat incrustado al compilar el paquete agregando esto:
<!-- to deploy as a war in tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
El ejemplo completo ejecutable está aquí https://www.surasint.com/spring-boot-create-war-for-tomcat/
Creo que estás confundido por diferentes paradigmas aquí. Primero, los archivos war y la implementación del servidor: esas cosas pertenecen a Java Enterprise Edition (Java EE). Estos conceptos no tienen un lugar real en una aplicación de arranque por resorte, que sigue un modelo diferente.
Spring-boot es responsable de crear un contenedor integrado y ejecutar sus servicios directamente desde archivos jar estándar (aunque puede hacer mucho más). Creo que la intención de este modelo es apoyar el desarrollo de microservicios, donde cada servicio tiene su propio contenedor y es completamente autónomo. También puede usar su código para generar aplicaciones Java EE, pero eso sería una tontería teniendo en cuenta que spring-boot es mucho más fácil (para ciertos tipos de aplicaciones / servicios).
Entonces, dada esta información, ahora tiene que decidir qué paradigma va a seguir, y debe seguir eso y solo eso.
Spring-boot es ejecutable: solo tiene que ejecutar el método principal en la clase de aplicación que puede hacer desde la línea de comandos o utilizando su IDE favorito o maven o gradle (consejo: maven es la respuesta correcta).
Esto abrirá un servidor Tomcat (por defecto) y su servicio estará disponible dentro de él.
Dada la configuración que publicó anteriormente, su servicio debería estar disponible en:
http://localhost:7777/context/help
: el
context
debe reemplazarse con su nombre de contexto, que no ha compartido.
No debes crear una guerra, ejecutar tomcat o desplegar nada.
Nada de eso es necesario en spring-boot.
El embalaje en su pom debe ser
jar
, no
war
y el
scope
de
spring-boot-starter-tomcat
debe eliminarse; ciertamente no se proporciona.
Cuando ejecuta su método principal, la salida de la consola debe indicarle el contexto que ha registrado; use eso para obtener la URL correcta.
Habiendo dicho todo eso, el arranque de primavera tiene que existir en un mundo JEE por ahora (hasta que sea ampliamente adoptado). Por esa razón, la gente de primavera ha documentado un enfoque para construir una guerra en lugar de un jar ejecutable, para su despliegue en un servlet o contenedor JEE. Esto permite que gran parte de la tecnología de arranque de resorte se use en entornos donde hay restricciones para usar cualquier cosa que no sean guerras (u orejas). Sin embargo, esta es solo una respuesta al hecho de que dichos entornos son bastante comunes y no se consideran una parte necesaria o incluso deseable de la solución.
Después de seguir la guía (o usar Spring Initializr), tuve un WAR que funcionaba en mi computadora local, pero no funcionaba de forma remota (ejecutándose en Tomcat).
No hubo ningún mensaje de error, solo decía "Se encontró el inicializador de servlet Spring", pero no hizo nada en absoluto.
17-Aug-2016 16:58:13.552 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.4
17-Aug-2016 16:58:13.593 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /opt/tomcat/webapps/ROOT.war
17-Aug-2016 16:58:16.243 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
y
17-Aug-2016 16:58:16.301 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath
17-Aug-2016 16:58:21.471 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
17-Aug-2016 16:58:25.133 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log ContextListener: contextInitialized()
17-Aug-2016 16:58:25.133 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log SessionListener: contextInitialized()
No pasó nada más. Spring Boot simplemente no se ejecutó.
Aparentemente compilé el servidor con Java 1.8, y la computadora remota tenía Java 1.7.
Después de compilar con Java 1.7, comenzó a funcionar.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version> <!-- added this line -->
<start-class>myapp.SpringApplication</start-class>
</properties>
Esta guía explica en detalle cómo implementar la aplicación Spring Boot en Tomcat:
reference
Esencialmente necesitaba agregar la siguiente clase:
public class WebInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
}
También agregué la siguiente propiedad a POM:
<properties>
<start-class>mypackage.App</start-class>
</properties>
La aplicación de clase pública extiende SpringBootServletInitializer {}
solo extiende SpringBootServletInitializer. Funcionará en su AWS / tomcat
Oye, asegúrate de hacer estos cambios en pom.xml
<packaging>war</packaging>
en la sección de dependencias, asegúrese de indicar que se proporciona el tomcat para que no necesite el complemento tomcat incrustado.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
Este es todo el pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>com.example.Application</start-class>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Y la clase de aplicación debería ser así
Application.java
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
/**
* Used when run as JAR
*/
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
/**
* Used when run as WAR
*/
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
Y puede agregar un controlador para probar MyController.java
package com.example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@RequestMapping("/hi")
public @ResponseBody String hiThere(){
return "hello world!";
}
}
Luego puede ejecutar el proyecto en una versión de tomcat 8 y acceder al controlador de esta manera
Si por alguna razón no puede agregar el proyecto a Tomcat, haga clic derecho en el proyecto y luego vaya a Build Path-> configure build path-> Project Faces
asegúrese de que solo estos 3 estén seleccionados
Módulo web dinámico 3.1 Java 1.8 Javascript 1.0
Si está creando una nueva aplicación en lugar de convertir una existente, la forma más fácil de crear una aplicación de arranque de primavera basada en WAR es a través de Spring Initializr .
Genera automáticamente la aplicación por ti. De forma predeterminada, crea Jar, pero en las opciones avanzadas, puede seleccionar crear WAR. Esta guerra también se puede ejecutar directamente.
Aún más fácil es crear el proyecto desde IntelliJ IDEA directamente:
Archivo → Nuevo proyecto → Spring Initializr
Si su objetivo es implementar su aplicación Spring Boot en AWS , Boxfuse le ofrece una solución muy fácil.
Todo lo que necesitas hacer es:
boxfuse run my-spring-boot-app-1.0.jar -env=prod
Esta voluntad:
- Fusiona una imagen mínima del sistema operativo a medida para tu aplicación (aproximadamente 100 veces más pequeña que una distribución típica de Linux)
- Empújalo a un repositorio en línea seguro
- Conviértalo en un AMI en aproximadamente 30 segundos
- Crear y configurar una nueva Elastic IP o ELB
- Asignarle un nuevo nombre de dominio
- Inicie una o más instancias en función de su nuevo AMI
Todas las imágenes se generan en segundos y son inmutables. Se pueden ejecutar sin cambios en VirtualBox (dev) y AWS (prueba y producción).
Todas las actualizaciones se realizan como implementaciones azules / verdes sin tiempo de inactividad y también puede habilitar el escalado automático con solo un comando.
Boxfuse también comprende que la configuración de Spring Boot configurará
automáticamente los grupos de seguridad y las comprobaciones de estado de ELB en función de las propiedades de su
application.properties
.
Aquí hay un tutorial para ayudarlo a comenzar: https://boxfuse.com/getstarted/springboot
Descargo de responsabilidad: soy el fundador y CEO de Boxfuse
Su clase
Application.java
debería extender la clase
SpringBootServletInitializer
, por ejemplo:
public class Application extends SpringBootServletInitializer {}
Tuve el mismo problema y encuentro la solución siguiendo esta guide . Corro con gol en maven.
paquete limpio
Me funcionó Thanq