Spring Boot: come aggiungere altri file WAR al tomcat incorporato?

Il tomcat incorporato di Spring Boot è molto utile, sia per lo sviluppo che per l’implementazione.

E se fosse necessario aggiungere un altro file WAR (di terze parti) (ad esempio, GeoServer)?

Forse la seguente è la procedura normale:

  1. Installa un normale server Tomcat.
  2. Crea l’applicazione Spring Boot come file WAR e aggiungila alla cartella webapps di Tomcat.
  3. Aggiungi anche un altro file WAR (di terze parti) alla cartella webapps.

Ma sarebbe bello se fosse ansible la seguente configurazione.

  1. Crea l’applicazione di avvio Spring come Jar autonomo, che include Tomcat incorporato.
  2. Distribuire l’applicazione di avvio Spring Jar.
  3. Aggiungi un altro file WAR (di terze parti) a una cartella riconosciuta da Tomcat incorporato.
  4. Fornisci sia il contenuto dell’applicazione di avvio Spring che i contenuti di un’altra WAR utilizzando Tomcat incorporato.

Come può essere fatto?

AGGIORNARE

Quando l’applicazione di avvio a molla è fatta di barattolo di grasso (= jar eseguibile), il codice nella risposta non è sufficiente. Il revisionato è il seguente:

@Bean public EmbeddedServletContainerFactory servletContainerFactory() { return new TomcatEmbeddedServletContainerFactory() { @Override protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer( Tomcat tomcat) { try { Context context = tomcat.addWebapp("/foo", "/path/to/foo.war"); WebappLoader loader = new WebappLoader(Thread.currentThread().getContextClassLoader()); context.setLoader(loader); } catch (ServletException ex) { throw new IllegalStateException("Failed to add webapp", ex); } return super.getTomcatEmbeddedServletContainer(tomcat); } }; } 

Poiché i file jar in un jar fat non possono essere caricati dal classloader di sistema, è necessario specificare un classloader padre esplicito. Altrimenti, la WAR aggiuntiva non può caricare i jar della libreria nel jar grasso dell’applicazione di avvio a molla che ha aggiunto WAR.

Puoi aggiungere un file di guerra a Tomcat incorporato utilizzando Tomcat.addWebapp . Come dice la javadoc, è “l’equivalente di aggiungere un’applicazione web alla directory delle app Web di Tomcat”. Per utilizzare questa API in Spring Boot, è necessario utilizzare una sottoclass TomcatEmbeddedServletContainerFactory personalizzata:

 @Bean public EmbeddedServletContainerFactory servletContainerFactory() { return new TomcatEmbeddedServletContainerFactory() { @Override protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer( Tomcat tomcat) { // Ensure that the webapps directory exists new File(tomcat.getServer().getCatalinaBase(), "webapps").mkdirs(); try { Context context = tomcat.addWebapp("/foo", "/path/to/foo.war"); // Allow the webapp to load classs from your fat jar context.setParentClassLoader(getClass().getClassLoader()); } catch (ServletException ex) { throw new IllegalStateException("Failed to add webapp", ex); } return super.getTomcatEmbeddedServletContainer(tomcat); } }; }