2 // ========================================================================
3 // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.servlet;
22 import java.io.IOException;
23 import java.lang.reflect.Method;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.List;
33 import java.util.Stack;
35 import javax.servlet.MultipartConfigElement;
36 import javax.servlet.Servlet;
37 import javax.servlet.ServletConfig;
38 import javax.servlet.ServletContext;
39 import javax.servlet.ServletException;
40 import javax.servlet.ServletRegistration;
41 import javax.servlet.ServletRequest;
42 import javax.servlet.ServletResponse;
43 import javax.servlet.ServletSecurityElement;
44 import javax.servlet.SingleThreadModel;
45 import javax.servlet.UnavailableException;
47 import org.eclipse.jetty.security.IdentityService;
48 import org.eclipse.jetty.security.RunAsToken;
49 import org.eclipse.jetty.server.Request;
50 import org.eclipse.jetty.server.UserIdentity;
51 import org.eclipse.jetty.server.handler.ContextHandler;
52 import org.eclipse.jetty.util.Loader;
53 import org.eclipse.jetty.util.annotation.ManagedAttribute;
54 import org.eclipse.jetty.util.annotation.ManagedObject;
55 import org.eclipse.jetty.util.log.Log;
56 import org.eclipse.jetty.util.log.Logger;
61 /* --------------------------------------------------------------------- */
62 /** Servlet Instance and Context Holder.
63 * Holds the name, params and some state of a javax.servlet.Servlet
64 * instance. It implements the ServletConfig interface.
65 * This class will organise the loading of the servlet when needed or
70 @ManagedObject("Servlet Holder")
71 public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope, Comparable<ServletHolder>
74 /* ---------------------------------------------------------------- */
75 private static final Logger LOG = Log.getLogger(ServletHolder.class);
76 private int _initOrder = -1;
77 private boolean _initOnStartup=false;
78 private boolean _initialized = false;
79 private Map<String, String> _roleMap;
80 private String _forcedPath;
81 private String _runAsRole;
82 private RunAsToken _runAsToken;
83 private IdentityService _identityService;
84 private ServletRegistration.Dynamic _registration;
85 private JspContainer _jspContainer;
87 private transient Servlet _servlet;
88 private transient Config _config;
89 private transient long _unavailable;
90 private transient boolean _enabled = true;
91 private transient UnavailableException _unavailableEx;
93 public static final String GLASSFISH_SENTINEL_CLASS = "org.glassfish.jsp.api.ResourceInjector";
94 public static final String APACHE_SENTINEL_CLASS = "org.apache.tomcat.InstanceManager";
95 public static final String JSP_GENERATED_PACKAGE_NAME = "org.eclipse.jetty.servlet.jspPackagePrefix";
96 public static final Map<String,String> NO_MAPPED_ROLES = Collections.emptyMap();
97 public static enum JspContainer {GLASSFISH, APACHE, OTHER};
99 /* ---------------------------------------------------------------- */
102 public ServletHolder()
104 this(Source.EMBEDDED);
107 /* ---------------------------------------------------------------- */
110 public ServletHolder(Holder.Source creator)
115 /* ---------------------------------------------------------------- */
116 /** Constructor for existing servlet.
118 public ServletHolder(Servlet servlet)
120 this(Source.EMBEDDED);
124 /* ---------------------------------------------------------------- */
125 /** Constructor for servlet class.
127 public ServletHolder(String name, Class<? extends Servlet> servlet)
129 this(Source.EMBEDDED);
131 setHeldClass(servlet);
134 /* ---------------------------------------------------------------- */
135 /** Constructor for servlet class.
137 public ServletHolder(String name, Servlet servlet)
139 this(Source.EMBEDDED);
144 /* ---------------------------------------------------------------- */
145 /** Constructor for servlet class.
147 public ServletHolder(Class<? extends Servlet> servlet)
149 this(Source.EMBEDDED);
150 setHeldClass(servlet);
153 /* ---------------------------------------------------------------- */
155 * @return The unavailable exception or null if not unavailable
157 public UnavailableException getUnavailableException()
159 return _unavailableEx;
162 /* ------------------------------------------------------------ */
163 public synchronized void setServlet(Servlet servlet)
165 if (servlet==null || servlet instanceof SingleThreadModel)
166 throw new IllegalArgumentException();
170 setHeldClass(servlet.getClass());
172 setName(servlet.getClass().getName()+"-"+super.hashCode());
175 /* ------------------------------------------------------------ */
176 @ManagedAttribute(value="initialization order", readonly=true)
177 public int getInitOrder()
182 /* ------------------------------------------------------------ */
183 /** Set the initialize order.
184 * Holders with order<0, are initialized on use. Those with
185 * order>=0 are initialized in increasing order when the handler
188 public void setInitOrder(int order)
190 _initOnStartup=order>=0;
194 /* ------------------------------------------------------------ */
195 /** Comparitor by init order.
198 public int compareTo(ServletHolder sh)
202 if (sh._initOrder<_initOrder)
204 if (sh._initOrder>_initOrder)
207 int c=(_className!=null && sh._className!=null)?_className.compareTo(sh._className):0;
209 c=_name.compareTo(sh._name);
213 /* ------------------------------------------------------------ */
214 public boolean equals(Object o)
216 return o instanceof ServletHolder && compareTo((ServletHolder)o)==0;
219 /* ------------------------------------------------------------ */
220 public int hashCode()
222 return _name==null?System.identityHashCode(this):_name.hashCode();
225 /* ------------------------------------------------------------ */
226 /** Link a user role.
227 * Translate the role name used by a servlet, to the link name
228 * used by the container.
229 * @param name The role name as used by the servlet
230 * @param link The role name as used by the container.
232 public synchronized void setUserRoleLink(String name,String link)
235 _roleMap=new HashMap<String, String>();
236 _roleMap.put(name,link);
239 /* ------------------------------------------------------------ */
240 /** get a user role link.
241 * @param name The name of the role
242 * @return The name as translated by the link. If no link exists,
243 * the name is returned.
245 public String getUserRoleLink(String name)
249 String link= _roleMap.get(name);
250 return (link==null)?name:link;
253 /* ------------------------------------------------------------ */
255 * @return Returns the forcedPath.
257 @ManagedAttribute(value="forced servlet path", readonly=true)
258 public String getForcedPath()
263 /* ------------------------------------------------------------ */
265 * @param forcedPath The forcedPath to set.
267 public void setForcedPath(String forcedPath)
269 _forcedPath = forcedPath;
272 public boolean isEnabled()
278 public void setEnabled(boolean enabled)
284 /* ------------------------------------------------------------ */
285 public void doStart()
292 // Handle JSP file forced paths
293 if (_forcedPath != null)
295 // Look for a precompiled JSP Servlet
296 String precompiled=getClassNameForJsp(_forcedPath);
297 if (LOG.isDebugEnabled())
298 LOG.debug("Checking for precompiled servlet {} for jsp {}", precompiled, _forcedPath);
299 ServletHolder jsp=getServletHandler().getServlet(precompiled);
300 if (jsp!=null && jsp.getClassName() != null)
302 if (LOG.isDebugEnabled())
303 LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
304 // set the className for this servlet to the precompiled one
305 setClassName(jsp.getClassName());
309 if (getClassName() == null)
311 // Look for normal JSP servlet
312 jsp=getServletHandler().getServlet("jsp");
315 if (LOG.isDebugEnabled())
316 LOG.debug("JSP file {} for {} mapped to Servlet class {}",_forcedPath, getName(),jsp.getClassName());
317 setClassName(jsp.getClassName());
318 //copy jsp init params that don't exist for this servlet
319 for (Map.Entry<String, String> entry:jsp.getInitParameters().entrySet())
321 if (!_initParams.containsKey(entry.getKey()))
322 setInitParameter(entry.getKey(), entry.getValue());
324 //jsp specific: set up the jsp-file on the JspServlet. If load-on-startup is >=0 and the jsp container supports
325 //precompilation, the jsp will be compiled when this holder is initialized. If not load on startup, or the
326 //container does not support startup precompilation, it will be compiled at runtime when handling a request for this jsp.
327 //See also adaptForcedPathToJspContainer
328 setInitParameter("jspFile", _forcedPath);
335 //check servlet has a class (ie is not a preliminary registration). If preliminary, fail startup.
340 catch (UnavailableException ue)
343 if (_servletHandler.isStartWithUnavailable())
353 //servlet is not an instance of javax.servlet.Servlet
358 catch (UnavailableException ue)
361 if (_servletHandler.isStartWithUnavailable())
370 //check if we need to forcibly set load-on-startup
371 checkInitOnStartup();
373 _identityService = _servletHandler.getIdentityService();
374 if (_identityService!=null && _runAsRole!=null)
375 _runAsToken=_identityService.newRunAsToken(_runAsRole);
377 _config=new Config();
379 if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
380 _servlet = new SingleThreadedWrapper();
385 /* ------------------------------------------------------------ */
387 public void initialize ()
392 if (_extInstance || _initOnStartup)
400 if (_servletHandler.isStartWithUnavailable())
411 /* ------------------------------------------------------------ */
415 Object old_run_as = null;
420 if (_identityService!=null)
421 old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
423 destroyInstance(_servlet);
431 if (_identityService!=null)
432 _identityService.unsetRunAs(old_run_as);
440 _initialized = false;
443 /* ------------------------------------------------------------ */
445 public void destroyInstance (Object o)
450 Servlet servlet = ((Servlet)o);
451 getServletHandler().destroyServlet(servlet);
455 /* ------------------------------------------------------------ */
457 * @return The servlet
459 public synchronized Servlet getServlet()
460 throws ServletException
462 // Handle previous unavailability
465 if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
466 throw _unavailableEx;
476 /* ------------------------------------------------------------ */
477 /** Get the servlet instance (no initialization done).
478 * @return The servlet or null
480 public Servlet getServletInstance()
485 /* ------------------------------------------------------------ */
487 * Check to ensure class of servlet is acceptable.
488 * @throws UnavailableException
490 public void checkServletType ()
491 throws UnavailableException
493 if (_class==null || !javax.servlet.Servlet.class.isAssignableFrom(_class))
495 throw new UnavailableException("Servlet "+_class+" is not a javax.servlet.Servlet");
499 /* ------------------------------------------------------------ */
501 * @return true if the holder is started and is not unavailable
503 public boolean isAvailable()
505 if (isStarted()&& _unavailable==0)
516 return isStarted()&& _unavailable==0;
519 /* ------------------------------------------------------------ */
521 * Check if there is a javax.servlet.annotation.ServletSecurity
522 * annotation on the servlet class. If there is, then we force
523 * it to be loaded on startup, because all of the security
524 * constraints must be calculated as the container starts.
527 private void checkInitOnStartup()
532 if ((_class.getAnnotation(javax.servlet.annotation.ServletSecurity.class) != null) && !_initOnStartup)
533 setInitOrder(Integer.MAX_VALUE);
536 /* ------------------------------------------------------------ */
537 private void makeUnavailable(UnavailableException e)
539 if (_unavailableEx==e && _unavailable!=0)
542 _servletHandler.getServletContext().log("unavailable",e);
550 if (_unavailableEx.getUnavailableSeconds()>0)
551 _unavailable=System.currentTimeMillis()+1000*_unavailableEx.getUnavailableSeconds();
553 _unavailable=System.currentTimeMillis()+5000; // TODO configure
557 /* ------------------------------------------------------------ */
559 private void makeUnavailable(final Throwable e)
561 if (e instanceof UnavailableException)
562 makeUnavailable((UnavailableException)e);
565 ServletContext ctx = _servletHandler.getServletContext();
567 LOG.info("unavailable",e);
569 ctx.log("unavailable",e);
570 _unavailableEx=new UnavailableException(String.valueOf(e),-1)
580 /* ------------------------------------------------------------ */
581 private void initServlet()
582 throws ServletException
584 Object old_run_as = null;
588 _servlet=newInstance();
590 _config=new Config();
595 if (_identityService!=null)
597 old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
600 // Handle configuring servlets that implement org.apache.jasper.servlet.JspServlet
604 detectJspContainer();
609 if (_forcedPath != null && _jspContainer == null)
611 detectJspContainer();
614 if (LOG.isDebugEnabled())
615 LOG.debug("Servlet.init {} for {}",_servlet,getName());
616 _servlet.init(_config);
618 catch (UnavailableException e)
625 catch (ServletException e)
627 makeUnavailable(e.getCause()==null?e:e.getCause());
637 throw new ServletException(this.toString(),e);
642 if (_identityService!=null)
643 _identityService.unsetRunAs(old_run_as);
648 /* ------------------------------------------------------------ */
652 protected void initJspServlet () throws Exception
654 ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
656 /* Set the webapp's classpath for Jasper */
657 ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
659 /* Set the system classpath for Jasper */
660 setInitParameter("com.sun.appserv.jsp.classpath", Loader.getClassPath(ch.getClassLoader().getParent()));
662 /* Set up other classpath attribute */
663 if ("?".equals(getInitParameter("classpath")))
665 String classpath = ch.getClassPath();
666 if (LOG.isDebugEnabled())
667 LOG.debug("classpath=" + classpath);
668 if (classpath != null)
669 setInitParameter("classpath", classpath);
672 /* ensure scratch dir */
674 if (getInitParameter("scratchdir") == null)
676 File tmp = (File)getServletHandler().getServletContext().getAttribute(ServletContext.TEMPDIR);
677 scratch = new File(tmp, "jsp");
678 setInitParameter("scratchdir", scratch.getAbsolutePath());
681 scratch = new File (getInitParameter("scratchdir"));
682 if (!scratch.exists()) scratch.mkdir();
685 /* ------------------------------------------------------------ */
687 * Register a ServletRequestListener that will ensure tmp multipart
688 * files are deleted when the request goes out of scope.
692 protected void initMultiPart () throws Exception
694 //if this servlet can handle multipart requests, ensure tmp files will be
695 //cleaned up correctly
696 if (((Registration)getRegistration()).getMultipartConfig() != null)
698 //Register a listener to delete tmp files that are created as a result of this
699 //servlet calling Request.getPart() or Request.getParts()
701 ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
702 ch.addEventListener(new Request.MultiPartCleanerListener());
706 /* ------------------------------------------------------------ */
708 * @see org.eclipse.jetty.server.UserIdentity.Scope#getContextPath()
711 public String getContextPath()
713 return _config.getServletContext().getContextPath();
716 /* ------------------------------------------------------------ */
718 * @see org.eclipse.jetty.server.UserIdentity.Scope#getRoleRefMap()
721 public Map<String, String> getRoleRefMap()
726 /* ------------------------------------------------------------ */
727 @ManagedAttribute(value="role to run servlet as", readonly=true)
728 public String getRunAsRole()
733 /* ------------------------------------------------------------ */
734 public void setRunAsRole(String role)
739 /* ------------------------------------------------------------ */
741 * Prepare to service a request.
746 * @throws ServletException
747 * @throws UnavailableException
749 protected void prepare (Request baseRequest, ServletRequest request, ServletResponse response)
750 throws ServletException, UnavailableException
753 MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
755 baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
758 public synchronized Servlet ensureInstance()
759 throws ServletException, UnavailableException
762 throw new UnavailableException("Servlet Not Initialized");
763 Servlet servlet=_servlet;
765 throw new UnavailableException("Servlet not initialized", -1);
766 if (_unavailable!=0 || (!_initOnStartup && servlet==null))
767 servlet=getServlet();
769 throw new UnavailableException("Could not instantiate "+_class);
774 /* ------------------------------------------------------------ */
775 /** Service a request with this servlet.
779 * @throws ServletException
780 * @throws UnavailableException
781 * @throws IOException
783 public void handle(Request baseRequest,
784 ServletRequest request,
785 ServletResponse response)
786 throws ServletException,
787 UnavailableException,
791 throw new UnavailableException("Servlet Not Initialized");
793 Servlet servlet = ensureInstance();
795 // Service the request
796 boolean servlet_error=true;
797 Object old_run_as = null;
798 boolean suspendable = baseRequest.isAsyncSupported();
801 // Handle aliased path
802 if (_forcedPath!=null)
803 adaptForcedPathToJspContainer(request);
806 if (_identityService!=null)
807 old_run_as=_identityService.setRunAs(baseRequest.getResolvedUserIdentity(),_runAsToken);
809 if (!isAsyncSupported())
810 baseRequest.setAsyncSupported(false);
812 servlet.service(request,response);
815 catch(UnavailableException e)
818 throw _unavailableEx;
822 baseRequest.setAsyncSupported(suspendable);
825 if (_identityService!=null)
826 _identityService.unsetRunAs(old_run_as);
828 // Handle error params.
830 request.setAttribute("javax.servlet.error.servlet_name",getName());
835 /* ------------------------------------------------------------ */
836 private boolean isJspServlet ()
838 if (_servlet == null)
841 Class<?> c = _servlet.getClass();
843 boolean result = false;
844 while (c != null && !result)
846 result = isJspServlet(c.getName());
847 c = c.getSuperclass();
854 /* ------------------------------------------------------------ */
855 private boolean isJspServlet (String classname)
857 if (classname == null)
859 return ("org.apache.jasper.servlet.JspServlet".equals(classname));
862 /* ------------------------------------------------------------ */
863 private void adaptForcedPathToJspContainer (ServletRequest request)
865 if (_forcedPath != null && _jspContainer != null && JspContainer.GLASSFISH.equals(_jspContainer))
867 //if container is glassfish, set the request attribute org.apache.catalina.jsp_file to
868 //ensure the delegate jsp will be compiled
870 request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
874 /* ------------------------------------------------------------ */
875 private void detectJspContainer ()
877 if (_jspContainer == null)
879 //check for glassfish
882 //if container is glassfish, set the request attribute org.apache.catalina.jsp_file to
883 //ensure the delegate jsp will be compiled
884 Loader.loadClass(Holder.class, GLASSFISH_SENTINEL_CLASS);
885 if (LOG.isDebugEnabled())LOG.debug("Glassfish jasper detected");
886 _jspContainer = JspContainer.GLASSFISH;
888 catch (ClassNotFoundException e)
893 Loader.loadClass(Holder.class, APACHE_SENTINEL_CLASS);
894 if (LOG.isDebugEnabled())LOG.debug("Apache jasper detected");
895 _jspContainer = JspContainer.APACHE;
897 catch (ClassNotFoundException x)
899 if (LOG.isDebugEnabled())LOG.debug("Other jasper detected");
900 _jspContainer = JspContainer.OTHER;
906 /* ------------------------------------------------------------ */
907 private String getNameOfJspClass (String jsp)
912 int i = jsp.lastIndexOf('/') + 1;
913 jsp = jsp.substring(i);
916 Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
917 Method makeJavaIdentifier = jspUtil.getMethod("makeJavaIdentifier", String.class);
918 return (String)makeJavaIdentifier.invoke(null, jsp);
922 String tmp = jsp.replace('.','_');
923 LOG.warn("Unable to make identifier for jsp "+jsp +" trying "+tmp+" instead");
924 if (LOG.isDebugEnabled())
931 /* ------------------------------------------------------------ */
932 private String getPackageOfJspClass (String jsp)
937 int i = jsp.lastIndexOf('/');
942 Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
943 Method makeJavaPackage = jspUtil.getMethod("makeJavaPackage", String.class);
944 return (String)makeJavaPackage.invoke(null, jsp.substring(0,i));
948 String tmp = jsp.substring(1).replace('/','.');
949 LOG.warn("Unable to make package for jsp "+jsp +" trying "+tmp+" instead");
950 if (LOG.isDebugEnabled())
957 /* ------------------------------------------------------------ */
958 private String getJspPackagePrefix ()
960 String jspPackageName = (String)getServletHandler().getServletContext().getInitParameter(JSP_GENERATED_PACKAGE_NAME );
961 if (jspPackageName == null)
962 jspPackageName = "org.apache.jsp";
964 return jspPackageName;
968 /* ------------------------------------------------------------ */
969 private String getClassNameForJsp (String jsp)
974 return getJspPackagePrefix() + "." +getPackageOfJspClass(jsp) + "." + getNameOfJspClass(jsp);
978 /* ------------------------------------------------------------ */
979 /* ------------------------------------------------------------ */
980 /* ------------------------------------------------------------ */
981 protected class Config extends HolderConfig implements ServletConfig
983 /* -------------------------------------------------------- */
985 public String getServletName()
992 /* -------------------------------------------------------- */
993 /* -------------------------------------------------------- */
994 /* -------------------------------------------------------- */
995 public class Registration extends HolderRegistration implements ServletRegistration.Dynamic
997 protected MultipartConfigElement _multipartConfig;
1000 public Set<String> addMapping(String... urlPatterns)
1002 illegalStateIfContextStarted();
1003 Set<String> clash=null;
1004 for (String pattern : urlPatterns)
1006 ServletMapping mapping = _servletHandler.getServletMapping(pattern);
1009 //if the servlet mapping was from a default descriptor, then allow it to be overridden
1010 if (!mapping.isDefault())
1013 clash=new HashSet<String>();
1019 //if there were any clashes amongst the urls, return them
1023 //otherwise apply all of them
1024 ServletMapping mapping = new ServletMapping();
1025 mapping.setServletName(ServletHolder.this.getName());
1026 mapping.setPathSpecs(urlPatterns);
1027 _servletHandler.addServletMapping(mapping);
1029 return Collections.emptySet();
1033 public Collection<String> getMappings()
1035 ServletMapping[] mappings =_servletHandler.getServletMappings();
1036 List<String> patterns=new ArrayList<String>();
1039 for (ServletMapping mapping : mappings)
1041 if (!mapping.getServletName().equals(getName()))
1043 String[] specs=mapping.getPathSpecs();
1044 if (specs!=null && specs.length>0)
1045 patterns.addAll(Arrays.asList(specs));
1052 public String getRunAsRole()
1058 public void setLoadOnStartup(int loadOnStartup)
1060 illegalStateIfContextStarted();
1061 ServletHolder.this.setInitOrder(loadOnStartup);
1064 public int getInitOrder()
1066 return ServletHolder.this.getInitOrder();
1070 public void setMultipartConfig(MultipartConfigElement element)
1072 _multipartConfig = element;
1075 public MultipartConfigElement getMultipartConfig()
1077 return _multipartConfig;
1081 public void setRunAsRole(String role)
1087 public Set<String> setServletSecurity(ServletSecurityElement securityElement)
1089 return _servletHandler.setServletSecurity(this, securityElement);
1093 public ServletRegistration.Dynamic getRegistration()
1095 if (_registration == null)
1096 _registration = new Registration();
1097 return _registration;
1100 /* -------------------------------------------------------- */
1101 /* -------------------------------------------------------- */
1102 /* -------------------------------------------------------- */
1103 private class SingleThreadedWrapper implements Servlet
1105 Stack<Servlet> _stack=new Stack<Servlet>();
1108 public void destroy()
1112 while(_stack.size()>0)
1113 try { (_stack.pop()).destroy(); } catch (Exception e) { LOG.warn(e); }
1118 public ServletConfig getServletConfig()
1124 public String getServletInfo()
1130 public void init(ServletConfig config) throws ServletException
1134 if(_stack.size()==0)
1138 Servlet s = newInstance();
1142 catch (ServletException e)
1148 throw new ServletException(e);
1155 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
1161 s=(Servlet)_stack.pop();
1169 catch (ServletException e)
1175 throw new ServletException(e);
1194 /* ------------------------------------------------------------ */
1196 * @return the newly created Servlet instance
1197 * @throws ServletException
1198 * @throws IllegalAccessException
1199 * @throws InstantiationException
1201 protected Servlet newInstance() throws ServletException, IllegalAccessException, InstantiationException
1205 ServletContext ctx = getServletHandler().getServletContext();
1206 if (ctx instanceof ServletContextHandler.Context)
1207 return ((ServletContextHandler.Context)ctx).createServlet(getHeldClass());
1208 return getHeldClass().newInstance();
1210 catch (ServletException se)
1212 Throwable cause = se.getRootCause();
1213 if (cause instanceof InstantiationException)
1214 throw (InstantiationException)cause;
1215 if (cause instanceof IllegalAccessException)
1216 throw (IllegalAccessException)cause;
1222 /* ------------------------------------------------------------ */
1224 public String toString()
1226 return String.format("%s@%x==%s,%d,%b",_name,hashCode(),_className,_initOrder,_servlet!=null);