Precompile jsp

Signed-off-by: Andrew DeMaria <lostonamountain@gmail.com>
master
Andrew DeMaria 5 years ago committed by jvoisin
parent ff08f6dd02
commit e7bd5da6fa
  1. 21
      airsonic-main/pom.xml
  2. 2
      airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java
  3. 2
      airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java
  4. 73
      airsonic-main/src/main/java/org/airsonic/player/spring/RegisterPrecompiledJSPInitializer.java
  5. 32
      airsonic-main/src/main/java/org/airsonic/player/spring/webxmldomain/ServletDef.java
  6. 33
      airsonic-main/src/main/java/org/airsonic/player/spring/webxmldomain/ServletMappingDef.java
  7. 34
      airsonic-main/src/main/java/org/airsonic/player/spring/webxmldomain/WebApp.java
  8. 1
      pom.xml

@ -638,6 +638,27 @@
<groupId>net.nicoulaj.maven.plugins</groupId> <groupId>net.nicoulaj.maven.plugins</groupId>
<artifactId>checksum-maven-plugin</artifactId> <artifactId>checksum-maven-plugin</artifactId>
</plugin> </plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jspc-maven-plugin</artifactId>
<version>9.4.19.v20190610</version>
<executions>
<execution>
<id>jspc</id>
<goals>
<goal>jspc</goal>
</goals>
<phase>compile</phase>
<configuration>
<!-- Since we are using spring boot - we do not have a web.xml so there is no sense
enabling merging. Furthermore, we output the webXmlFragment to the target/classes
directory such that it will be on the classpath for use during runtime -->
<mergeFragment>false</mergeFragment>
<webXmlFragment>${project.build.outputDirectory}/precompiled-jsp-web.xml</webXmlFragment>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
<profiles> <profiles>

@ -139,7 +139,7 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter
// See: https://docs.spring.io/spring-security/site/docs/3.0.x/reference/remember-me.html // See: https://docs.spring.io/spring-security/site/docs/3.0.x/reference/remember-me.html
String rememberMeKey = settingsService.getRememberMeKey(); String rememberMeKey = settingsService.getRememberMeKey();
boolean development = settingsService.isDevelopmentMode(); boolean development = SettingsService.isDevelopmentMode();
if (StringUtils.isBlank(rememberMeKey) && !development) { if (StringUtils.isBlank(rememberMeKey) && !development) {
// ...if it is empty, generate a random key on startup (default). // ...if it is empty, generate a random key on startup (default).
logger.debug("Generating a new ephemeral 'remember me' key in a secure way."); logger.debug("Generating a new ephemeral 'remember me' key in a secure way.");

@ -791,7 +791,7 @@ public class SettingsService {
* *
* @return true if we are in Development mode. * @return true if we are in Development mode.
*/ */
public boolean isDevelopmentMode() { public static boolean isDevelopmentMode() {
return System.getProperty("airsonic.development") != null; return System.getProperty("airsonic.development") != null;
} }

@ -0,0 +1,73 @@
package org.airsonic.player.spring;
import org.airsonic.player.service.SettingsService;
import org.airsonic.player.spring.webxmldomain.ServletDef;
import org.airsonic.player.spring.webxmldomain.ServletMappingDef;
import org.airsonic.player.spring.webxmldomain.WebApp;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.stereotype.Component;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.nio.charset.Charset;
@Component
public class RegisterPrecompiledJSPInitializer implements ServletContextInitializer {
private static final Logger logger = LoggerFactory.getLogger(RegisterPrecompiledJSPInitializer.class);
@Override
public void onStartup(ServletContext servletContext) {
if(SettingsService.isDevelopmentMode()) {
logger.debug("Not registering precompiled jsps");
} else {
logger.debug("Registering precompiled jsps");
registerPrecompiledJSPs(servletContext);
}
}
private static void registerPrecompiledJSPs(ServletContext servletContext) {
WebApp webApp = parseXmlFragment();
for (ServletDef def : webApp.getServletDefs()) {
logger.trace("Registering precompiled JSP: {} -> {}", def.getName(), def.getSclass());
ServletRegistration.Dynamic reg = servletContext.addServlet(def.getName(), def.getSclass());
// Need to set loadOnStartup somewhere between 0 and 128. 0 is highest priority. 99 should be fine
reg.setLoadOnStartup(99);
}
for (ServletMappingDef mapping : webApp.getServletMappingDefs()) {
logger.trace("Mapping servlet: {} -> {}", mapping.getName(), mapping.getUrlPattern());
servletContext.getServletRegistration(mapping.getName()).addMapping(mapping.getUrlPattern());
}
}
private static WebApp parseXmlFragment() {
InputStream precompiledJspWebXml = RegisterPrecompiledJSPInitializer.class.getResourceAsStream("/precompiled-jsp-web.xml");
InputStream webXmlIS = new SequenceInputStream(
new SequenceInputStream(
IOUtils.toInputStream("<web-app>", Charset.defaultCharset()),
precompiledJspWebXml),
IOUtils.toInputStream("</web-app>", Charset.defaultCharset()));
JAXBContext jaxbContext;
try {
jaxbContext = new JAXBDataBinding(WebApp.class).getContext();
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
WebApp webapp = (WebApp) unmarshaller.unmarshal(webXmlIS);
return webapp;
} catch (JAXBException e) {
throw new RuntimeException("Could not parse precompiled-jsp-web.xml", e);
}
}
}

@ -0,0 +1,32 @@
package org.airsonic.player.spring.webxmldomain;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ServletDef {
@XmlElement(name="servlet-name")
private String name;
@XmlElement(name="servlet-class")
private String sclass;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSclass() {
return sclass;
}
public void setSclass(String sclass) {
this.sclass = sclass;
}
}

@ -0,0 +1,33 @@
package org.airsonic.player.spring.webxmldomain;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ServletMappingDef {
@XmlElement(name="servlet-name")
private String name;
@XmlElement(name="url-pattern")
private String urlPattern;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrlPattern() {
return urlPattern;
}
public void setUrlPattern(String urlPattern) {
this.urlPattern = urlPattern;
}
}

@ -0,0 +1,34 @@
package org.airsonic.player.spring.webxmldomain;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@XmlRootElement(name="web-app")
@XmlAccessorType(XmlAccessType.FIELD)
public class WebApp {
@XmlElement(name="servlet")
private List<ServletDef> servletDefs;
@XmlElement(name="servlet-mapping")
private List<ServletMappingDef> servletMappingDefs;
public List<ServletDef> getServletDefs() {
return servletDefs;
}
public void setServletDefs(List<ServletDef> servletDefs) {
this.servletDefs = servletDefs;
}
public List<ServletMappingDef> getServletMappingDefs() {
return servletMappingDefs;
}
public void setServletMappingDefs(List<ServletMappingDef> servletMappingDefs) {
this.servletMappingDefs = servletMappingDefs;
}
}

@ -381,6 +381,7 @@
<ignoredUsedUndeclaredDependency>org.springframework.boot:*</ignoredUsedUndeclaredDependency> <ignoredUsedUndeclaredDependency>org.springframework.boot:*</ignoredUsedUndeclaredDependency>
<ignoredUsedUndeclaredDependency>org.apache.tomcat.embed:tomcat-embed-core*</ignoredUsedUndeclaredDependency> <ignoredUsedUndeclaredDependency>org.apache.tomcat.embed:tomcat-embed-core*</ignoredUsedUndeclaredDependency>
<ignoredUsedUndeclaredDependency>org.apache.tomcat:tomcat-annotations-api:*</ignoredUsedUndeclaredDependency> <ignoredUsedUndeclaredDependency>org.apache.tomcat:tomcat-annotations-api:*</ignoredUsedUndeclaredDependency>
<ignoredUsedUndeclaredDependency>org.apache.tomcat.embed:tomcat-embed-el*</ignoredUsedUndeclaredDependency>
</ignoredUsedUndeclaredDependencies> </ignoredUsedUndeclaredDependencies>
<ignoredUnusedDeclaredDependencies> <ignoredUnusedDeclaredDependencies>
<ignoredUnusedDeclaredDependency>com.sun.mail:javax.mail*</ignoredUnusedDeclaredDependency> <ignoredUnusedDeclaredDependency>com.sun.mail:javax.mail*</ignoredUnusedDeclaredDependency>

Loading…
Cancel
Save