/**
- * The maxim number of loaded jsps per web-application. If there are more
+ * The maximum number of loaded jsps per web-application. If there are more
* jsps loaded, they will be unloaded.
*/
private int maxLoadedJsps = -1;
+ /**
+ * The idle time after which a JSP is unloaded.
+ * If unset or less or equal than 0, no jsps are unloaded.
+ */
+ private int jspIdleTimeout = -1;
+
public String getProperty(String name ) {
return settings.getProperty( name );
}
}
/**
- * Should any jsps be unloaded? If set to a value greater than 0 eviction of jsps
- * is started. Default: -1
- * */
+ * Should jsps be unloaded if to many are loaded?
+ * If set to a value greater than 0 eviction of jsps is started. Default: -1
+ */
public int getMaxLoadedJsps() {
return maxLoadedJsps;
}
/**
+ * Should any jsps be unloaded when being idle for to long?
+ * If set to a value greater than 0 eviction of jsps is started. Default: -1
+ */
+ public int getJspIdleTimeout() {
+ return jspIdleTimeout;
+ }
+
+ /**
* Create an EmbeddedServletOptions object using data available from
* ServletConfig and ServletContext.
*/
}
}
}
+
+ String jspIdleTimeout = config.getInitParameter("jspIdleTimeout");
+ if (jspIdleTimeout != null) {
+ try {
+ this.jspIdleTimeout = Integer.parseInt(jspIdleTimeout);
+ } catch(NumberFormatException ex) {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.jspIdleTimeout", ""+this.jspIdleTimeout));
+ }
+ }
+ }
// Setup the global Tag Libraries location cache for this
// web-application.
return -1;
}
+ public int getJspIdleTimeout() {
+ return -1;
+ }
+
/**
* {@inheritDoc}
*/
public Map<String, TagLibraryInfo> getCache();
/**
- * The maxim number of loaded jsps per web-application. If there are more
+ * The maximum number of loaded jsps per web-application. If there are more
* jsps loaded, they will be unloaded. If unset or less than 0, no jsps
* are unloaded.
*/
public int getMaxLoadedJsps();
+
+ /**
+ * The idle time after which a JSP is unloaded.
+ * If unset or less or equal than 0, no jsps are unloaded.
+ */
+ public int getJspIdleTimeout();
}
jspQueue = new FastRemovalDequeue<JspServletWrapper>(options.getMaxLoadedJsps());
}
+ jspIdleTimeout = options.getJspIdleTimeout() * 1000;
}
// ----------------------------------------------------- Instance Variables
private final String classpath;
private volatile long lastCompileCheck = -1L;
private volatile long lastJspQueueUpdate = System.currentTimeMillis();
+ private long jspIdleTimeout;
/**
* Maps JSP pages to their JspServletWrapper's
*/
public void checkUnload() {
- lastJspQueueUpdate = System.currentTimeMillis();
+ long now = System.currentTimeMillis();
+ if (jspIdleTimeout > 0) {
+ long unloadBefore = now - jspIdleTimeout;
+ Object [] wrappers = jsps.values().toArray();
+ for (int i = 0; i < wrappers.length; i++ ) {
+ JspServletWrapper jsw = (JspServletWrapper)wrappers[i];
+ synchronized(jsw) {
+ if (jsw.getLastUsageTime() < unloadBefore) {
+ if (jspQueue != null) {
+ jspQueue.remove(jsw.getUnloadHandle());
+ }
+ unloadJspServletWrapper(jsw);
+ }
+ }
+ }
+ }
+ lastJspQueueUpdate = now;
}
}
jsp.warning.suppressSmap=Warning: Invalid value for the initParam suppressSmap. Will use the default value of \"false\"
jsp.warning.displaySourceFragment=Warning: Invalid value for the initParam displaySourceFragment. Will use the default value of \"true\"
jsp.warning.maxLoadedJsps=Warning: Invalid value for the initParam maxLoadedJsps. Will use the default value of \"-1\"
+jsp.warning.jspIdleTimeout=Warning: Invalid value for the initParam jspIdleTimeout. Will use the default value of \"-1\"
jsp.error.badtaglib=Unable to open taglibrary {0} : {1}
jsp.error.badGetReader=Cannot create a reader when the stream is not buffered
jsp.warning.unknown.element.in.taglib=Unknown element ({0}) in taglib
jsp.error.bug48498=Unable to display JSP extract. Probably due to an XML parser bug (see Tomcat bug 48498 for details).
# UniqueAttributesImpl
-jsp.error.duplicateqname=An attribute with duplicate qualified name [{0}] was found. Attribute qualified names must be unique within an element.
\ No newline at end of file
+jsp.error.duplicateqname=An attribute with duplicate qualified name [{0}] was found. Attribute qualified names must be unique within an element.
private long lastModificationTest = 0L;
private long lastUsageTime = System.currentTimeMillis();
private FastRemovalDequeue<JspServletWrapper>.Entry unloadHandle;
+ private final boolean unloadAllowed;
private final boolean unloadByCount;
+ private final boolean unloadByIdle;
/*
* JspServletWrapper for JSP pages.
this.options = options;
this.jspUri = jspUri;
unloadByCount = options.getMaxLoadedJsps() > 0 ? true : false;
+ unloadByIdle = options.getJspIdleTimeout() > 0 ? true : false;
+ unloadAllowed = unloadByCount || unloadByIdle ? true : false;
ctxt = new JspCompilationContext(jspUri, isErrorPage, options,
config.getServletContext(),
this, rctxt);
this.jspUri = tagFilePath;
this.tripCount = 0;
unloadByCount = options.getMaxLoadedJsps() > 0 ? true : false;
+ unloadByIdle = options.getJspIdleTimeout() > 0 ? true : false;
+ unloadAllowed = unloadByCount || unloadByIdle ? true : false;
ctxt = new JspCompilationContext(jspUri, tagInfo, options,
servletContext, this, rctxt,
tagJarResource);
return jspUri;
}
+ public FastRemovalDequeue<JspServletWrapper>.Entry getUnloadHandle() {
+ return unloadHandle;
+ }
+
public void service(HttpServletRequest request,
HttpServletResponse response,
boolean precompile)
/*
* (3) Handle limitation of number of loaded Jsps
*/
- if (unloadByCount) {
+ if (unloadAllowed) {
synchronized(this) {
- if (unloadHandle == null) {
- unloadHandle = ctxt.getRuntimeContext().push(this);
- } else if (lastUsageTime < ctxt.getRuntimeContext().getLastJspQueueUpdate()) {
- ctxt.getRuntimeContext().makeYoungest(unloadHandle);
- lastUsageTime = System.currentTimeMillis();
+ if (unloadByCount) {
+ if (unloadHandle == null) {
+ unloadHandle = ctxt.getRuntimeContext().push(this);
+ } else if (lastUsageTime < ctxt.getRuntimeContext().getLastJspQueueUpdate()) {
+ ctxt.getRuntimeContext().makeYoungest(unloadHandle);
+ lastUsageTime = System.currentTimeMillis();
+ }
+ } else {
+ if (lastUsageTime < ctxt.getRuntimeContext().getLastJspQueueUpdate()) {
+ lastUsageTime = System.currentTimeMillis();
+ }
}
}
}
}
/**
+ * @return the lastUsageTime.
+ */
+ public long getLastUsageTime() {
+ return lastUsageTime;
+ }
+
+ /**
* <p>Attempts to construct a JasperException that contains helpful information
* about what went wrong. Uses the JSP compiler system to translate the line
* number in the generated servlet that originated the exception to a line