Avoid direct dependency on tomcat

- Use reflection to invoke tomcat configs

Signed-off-by: Andrew DeMaria <lostonamountain@gmail.com>
master
Andrew DeMaria 8 years ago
parent 0cdfbc0e12
commit 97a54658c6
No known key found for this signature in database
GPG Key ID: 0A3F5E91F8364EDF
  1. 54
      libresonic-main/src/main/java/org/libresonic/player/boot/Application.java
  2. 34
      libresonic-main/src/main/java/org/libresonic/player/boot/TomcatApplication.java

@ -1,10 +1,8 @@
package org.libresonic.player.boot; package org.libresonic.player.boot;
import net.sf.ehcache.constructs.web.ShutdownListener; import net.sf.ehcache.constructs.web.ShutdownListener;
import org.apache.catalina.Container;
import org.apache.catalina.Wrapper;
import org.apache.catalina.webresources.StandardRoot;
import org.directwebremoting.servlet.DwrServlet; import org.directwebremoting.servlet.DwrServlet;
import org.libresonic.player.Logger;
import org.libresonic.player.filter.*; import org.libresonic.player.filter.*;
import org.libresonic.player.spring.LibresonicPropertySourceConfigurer; import org.libresonic.player.spring.LibresonicPropertySourceConfigurer;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -16,18 +14,19 @@ import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfigurati
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource; import org.springframework.context.annotation.ImportResource;
import org.springframework.util.ReflectionUtils;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
import java.lang.reflect.Method;
@SpringBootApplication(exclude = { @SpringBootApplication(exclude = {
JmxAutoConfiguration.class, JmxAutoConfiguration.class,
JdbcTemplateAutoConfiguration.class, JdbcTemplateAutoConfiguration.class,
@ -41,6 +40,8 @@ import javax.servlet.ServletContextListener;
"classpath:/libresonic-servlet.xml"}) "classpath:/libresonic-servlet.xml"})
public class Application extends SpringBootServletInitializer implements EmbeddedServletContainerCustomizer { public class Application extends SpringBootServletInitializer implements EmbeddedServletContainerCustomizer {
private static final Logger LOG = Logger.getLogger(Application.class);
/** /**
* Registers the DWR servlet. * Registers the DWR servlet.
* *
@ -186,29 +187,28 @@ public class Application extends SpringBootServletInitializer implements Embedde
@Override @Override
public void customize(ConfigurableEmbeddedServletContainer container) { public void customize(ConfigurableEmbeddedServletContainer container) {
if (container instanceof TomcatEmbeddedServletContainerFactory) { // Yes, there is a good reason we do this.
TomcatEmbeddedServletContainerFactory tomcatFactory = (TomcatEmbeddedServletContainerFactory) container; // We cannot count on the tomcat classes being on the classpath which will
tomcatFactory.addContextCustomizers((TomcatContextCustomizer) context -> { // happen if the war is deployed to another app server like Jetty. So, we
// ensure this class does not have any direct dependencies on any Tomcat
// Increase the size and time before eviction of the Tomcat // specific classes.
// cache so that resources aren't uncompressed too often. try {
// See https://github.com/jhipster/generator-jhipster/issues/3995 Class<?> tomcatESCF = Class.forName("org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory");
StandardRoot resources = new StandardRoot(); if(tomcatESCF.isInstance(container)) {
resources.setCacheMaxSize(100000); LOG.debug("Attempting to optimize tomcat");
resources.setCacheObjectMaxSize(4000); Object tomcatESCFInstance = tomcatESCF.cast(container);
resources.setCacheTtl(24 * 3600 * 1000); // 1 day, in milliseconds Class<?> tomcatApplicationClass = Class.forName("org.libresonic.player.boot.TomcatApplication");
context.setResources(resources); Method configure = ReflectionUtils.findMethod(tomcatApplicationClass, "configure", tomcatESCF);
configure.invoke(null, tomcatESCFInstance);
// Put Jasper in production mode so that JSP aren't recompiled LOG.debug("Tomcat optimizations complete");
// on each request. } else {
// See http://stackoverflow.com/questions/29653326/spring-boot-application-slow-because-of-jsp-compilation LOG.debug("Skipping tomcat optimization as we are not running on tomcat");
Container jsp = context.findChild("jsp"); }
if (jsp instanceof Wrapper) { } catch (ClassNotFoundException e) {
((Wrapper)jsp).addInitParameter("development", "false"); LOG.debug("Skipping tomcat optimization as the tomcat classes are not available");
} } catch (Exception e) {
}); LOG.warn("An error happened while trying to optimize tomcat", e);
} }
} }
public static void main(String[] args) { public static void main(String[] args) {

@ -0,0 +1,34 @@
package org.libresonic.player.boot;
import org.apache.catalina.Container;
import org.apache.catalina.Wrapper;
import org.apache.catalina.webresources.StandardRoot;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
public class TomcatApplication {
public static void configure(TomcatEmbeddedServletContainerFactory tomcatFactory) {
tomcatFactory.addContextCustomizers((TomcatContextCustomizer) context -> {
// Increase the size and time before eviction of the Tomcat
// cache so that resources aren't uncompressed too often.
// See https://github.com/jhipster/generator-jhipster/issues/3995
StandardRoot resources = new StandardRoot();
resources.setCacheMaxSize(100000);
resources.setCacheObjectMaxSize(4000);
resources.setCacheTtl(24 * 3600 * 1000); // 1 day, in milliseconds
context.setResources(resources);
// Put Jasper in production mode so that JSP aren't recompiled
// on each request.
// See http://stackoverflow.com/questions/29653326/spring-boot-application-slow-because-of-jsp-compilation
Container jsp = context.findChild("jsp");
if (jsp instanceof Wrapper) {
((Wrapper) jsp).addInitParameter("development", "false");
}
});
}
}
Loading…
Cancel
Save