//
// ========================================================================
-// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
package org.eclipse.jetty.servlet;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@ManagedObject("Servlet Holder")
public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope, Comparable<ServletHolder>
{
- private static final Logger LOG = Log.getLogger(ServletHolder.class);
/* ---------------------------------------------------------------- */
+ private static final Logger LOG = Log.getLogger(ServletHolder.class);
private int _initOrder = -1;
private boolean _initOnStartup=false;
+ private boolean _initialized = false;
private Map<String, String> _roleMap;
private String _forcedPath;
private String _runAsRole;
private RunAsToken _runAsToken;
private IdentityService _identityService;
private ServletRegistration.Dynamic _registration;
-
+ private JspContainer _jspContainer;
private transient Servlet _servlet;
private transient Config _config;
private transient boolean _enabled = true;
private transient UnavailableException _unavailableEx;
+ public static final String GLASSFISH_SENTINEL_CLASS = "org.glassfish.jsp.api.ResourceInjector";
+ public static final String APACHE_SENTINEL_CLASS = "org.apache.tomcat.InstanceManager";
public static final String JSP_GENERATED_PACKAGE_NAME = "org.eclipse.jetty.servlet.jspPackagePrefix";
public static final Map<String,String> NO_MAPPED_ROLES = Collections.emptyMap();
+ public static enum JspContainer {GLASSFISH, APACHE, OTHER};
/* ---------------------------------------------------------------- */
/** Constructor .
{
// Look for a precompiled JSP Servlet
String precompiled=getClassNameForJsp(_forcedPath);
- LOG.debug("Checking for precompiled servlet {} for jsp {}", precompiled, _forcedPath);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Checking for precompiled servlet {} for jsp {}", precompiled, _forcedPath);
ServletHolder jsp=getServletHandler().getServlet(precompiled);
- if (jsp!=null)
+ if (jsp!=null && jsp.getClassName() != null)
{
- LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
+ if (LOG.isDebugEnabled())
+ LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
// set the className for this servlet to the precompiled one
setClassName(jsp.getClassName());
}
jsp=getServletHandler().getServlet("jsp");
if (jsp!=null)
{
- LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
+ if (LOG.isDebugEnabled())
+ LOG.debug("JSP file {} for {} mapped to Servlet class {}",_forcedPath, getName(),jsp.getClassName());
setClassName(jsp.getClassName());
//copy jsp init params that don't exist for this servlet
for (Map.Entry<String, String> entry:jsp.getInitParameters().entrySet())
if (!_initParams.containsKey(entry.getKey()))
setInitParameter(entry.getKey(), entry.getValue());
}
- //jsp specific: set up the jsp-file on the JspServlet so it can precompile iff load-on-startup is >=0
- if (_initOnStartup)
- setInitParameter("jspFile", _forcedPath);
+ //jsp specific: set up the jsp-file on the JspServlet. If load-on-startup is >=0 and the jsp container supports
+ //precompilation, the jsp will be compiled when this holder is initialized. If not load on startup, or the
+ //container does not support startup precompilation, it will be compiled at runtime when handling a request for this jsp.
+ //See also adaptForcedPathToJspContainer
+ setInitParameter("jspFile", _forcedPath);
}
}
}
if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
_servlet = new SingleThreadedWrapper();
-
+
}
public void initialize ()
throws Exception
{
- super.initialize();
- if (_extInstance || _initOnStartup)
- {
- try
- {
- initServlet();
- }
- catch(Exception e)
+ if(!_initialized){
+ super.initialize();
+ if (_extInstance || _initOnStartup)
{
- if (_servletHandler.isStartWithUnavailable())
- LOG.ignore(e);
- else
- throw e;
+ try
+ {
+ initServlet();
+ }
+ catch(Exception e)
+ {
+ if (_servletHandler.isStartWithUnavailable())
+ LOG.ignore(e);
+ else
+ throw e;
+ }
}
}
+ _initialized = true;
}
_servlet=null;
_config=null;
+ _initialized = false;
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
private void initServlet()
- throws ServletException
+ throws ServletException
{
Object old_run_as = null;
try
if (isJspServlet())
{
initJspServlet();
+ detectJspContainer();
}
initMultiPart();
- LOG.debug("Filter.init {}",_servlet);
+ if (_forcedPath != null && _jspContainer == null)
+ {
+ detectJspContainer();
+ }
+
+ if (LOG.isDebugEnabled())
+ LOG.debug("Servlet.init {} for {}",_servlet,getName());
_servlet.init(_config);
}
catch (UnavailableException e)
if ("?".equals(getInitParameter("classpath")))
{
String classpath = ch.getClassPath();
- LOG.debug("classpath=" + classpath);
+ if (LOG.isDebugEnabled())
+ LOG.debug("classpath=" + classpath);
if (classpath != null)
setInitParameter("classpath", classpath);
}
+
+ /* ensure scratch dir */
+ File scratch = null;
+ if (getInitParameter("scratchdir") == null)
+ {
+ File tmp = (File)getServletHandler().getServletContext().getAttribute(ServletContext.TEMPDIR);
+ scratch = new File(tmp, "jsp");
+ setInitParameter("scratchdir", scratch.getAbsolutePath());
+ }
+
+ scratch = new File (getInitParameter("scratchdir"));
+ if (!scratch.exists()) scratch.mkdir();
}
/* ------------------------------------------------------------ */
{
_runAsRole = role;
}
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Prepare to service a request.
+ *
+ * @param baseRequest
+ * @param request
+ * @param response
+ * @throws ServletException
+ * @throws UnavailableException
+ */
+ protected void prepare (Request baseRequest, ServletRequest request, ServletResponse response)
+ throws ServletException, UnavailableException
+ {
+ ensureInstance();
+ MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
+ if (mpce != null)
+ baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
+ }
+
+ public synchronized Servlet ensureInstance()
+ throws ServletException, UnavailableException
+ {
+ if (_class==null)
+ throw new UnavailableException("Servlet Not Initialized");
+ Servlet servlet=_servlet;
+ if (!isStarted())
+ throw new UnavailableException("Servlet not initialized", -1);
+ if (_unavailable!=0 || (!_initOnStartup && servlet==null))
+ servlet=getServlet();
+ if (servlet==null)
+ throw new UnavailableException("Could not instantiate "+_class);
+
+ return servlet;
+ }
/* ------------------------------------------------------------ */
/** Service a request with this servlet.
+ * @param baseRequest
+ * @param request
+ * @param response
+ * @throws ServletException
+ * @throws UnavailableException
+ * @throws IOException
*/
public void handle(Request baseRequest,
ServletRequest request,
if (_class==null)
throw new UnavailableException("Servlet Not Initialized");
- Servlet servlet=_servlet;
- synchronized(this)
- {
- if (!isStarted())
- throw new UnavailableException("Servlet not initialized", -1);
- if (_unavailable!=0 || (!_initOnStartup && servlet==null))
- servlet=getServlet();
- if (servlet==null)
- throw new UnavailableException("Could not instantiate "+_class);
- }
+ Servlet servlet = ensureInstance();
// Service the request
boolean servlet_error=true;
{
// Handle aliased path
if (_forcedPath!=null)
- // TODO complain about poor naming to the Jasper folks
- request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
+ adaptForcedPathToJspContainer(request);
// Handle run as
if (_identityService!=null)
if (!isAsyncSupported())
baseRequest.setAsyncSupported(false);
- MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
- if (mpce != null)
- request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
-
servlet.service(request,response);
servlet_error=false;
}
if (_servlet == null)
return false;
- Class c = _servlet.getClass();
+ Class<?> c = _servlet.getClass();
boolean result = false;
while (c != null && !result)
return false;
return ("org.apache.jasper.servlet.JspServlet".equals(classname));
}
-
-
+
+ /* ------------------------------------------------------------ */
+ private void adaptForcedPathToJspContainer (ServletRequest request)
+ {
+ if (_forcedPath != null && _jspContainer != null && JspContainer.GLASSFISH.equals(_jspContainer))
+ {
+ //if container is glassfish, set the request attribute org.apache.catalina.jsp_file to
+ //ensure the delegate jsp will be compiled
+
+ request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ private void detectJspContainer ()
+ {
+ if (_jspContainer == null)
+ {
+ //check for glassfish
+ try
+ {
+ //if container is glassfish, set the request attribute org.apache.catalina.jsp_file to
+ //ensure the delegate jsp will be compiled
+ Loader.loadClass(Holder.class, GLASSFISH_SENTINEL_CLASS);
+ if (LOG.isDebugEnabled())LOG.debug("Glassfish jasper detected");
+ _jspContainer = JspContainer.GLASSFISH;
+ }
+ catch (ClassNotFoundException e)
+ {
+ try
+ {
+ //check for apache
+ Loader.loadClass(Holder.class, APACHE_SENTINEL_CLASS);
+ if (LOG.isDebugEnabled())LOG.debug("Apache jasper detected");
+ _jspContainer = JspContainer.APACHE;
+ }
+ catch (ClassNotFoundException x)
+ {
+ if (LOG.isDebugEnabled())LOG.debug("Other jasper detected");
+ _jspContainer = JspContainer.OTHER;
+ }
+ }
+ }
+ }
+
/* ------------------------------------------------------------ */
private String getNameOfJspClass (String jsp)
{
jsp = jsp.substring(i);
try
{
- Class jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
+ Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
Method makeJavaIdentifier = jspUtil.getMethod("makeJavaIdentifier", String.class);
return (String)makeJavaIdentifier.invoke(null, jsp);
}
return "";
try
{
- Class jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
+ Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
Method makeJavaPackage = jspUtil.getMethod("makeJavaPackage", String.class);
return (String)makeJavaPackage.invoke(null, jsp.substring(0,i));
}