init
This commit is contained in:
120
java/org/apache/jasper/servlet/JasperInitializer.java
Normal file
120
java/org/apache/jasper/servlet/JasperInitializer.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.jasper.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContainerInitializer;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.jsp.JspFactory;
|
||||
|
||||
import org.apache.jasper.Constants;
|
||||
import org.apache.jasper.compiler.Localizer;
|
||||
import org.apache.jasper.compiler.TldCache;
|
||||
import org.apache.jasper.runtime.JspFactoryImpl;
|
||||
import org.apache.jasper.security.SecurityClassLoad;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
import org.apache.tomcat.InstanceManager;
|
||||
import org.apache.tomcat.SimpleInstanceManager;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Initializer for the Jasper JSP Engine.
|
||||
*/
|
||||
public class JasperInitializer implements ServletContainerInitializer {
|
||||
|
||||
private static final String MSG = "org.apache.jasper.servlet.JasperInitializer";
|
||||
private final Log log = LogFactory.getLog(JasperInitializer.class); // must not be static
|
||||
|
||||
/**
|
||||
* Preload classes required at runtime by a JSP servlet so that
|
||||
* we don't get a defineClassInPackage security exception.
|
||||
*/
|
||||
static {
|
||||
JspFactoryImpl factory = new JspFactoryImpl();
|
||||
SecurityClassLoad.securityClassLoad(factory.getClass().getClassLoader());
|
||||
if( System.getSecurityManager() != null ) {
|
||||
String basePackage = "org.apache.jasper.";
|
||||
try {
|
||||
factory.getClass().getClassLoader().loadClass( basePackage +
|
||||
"runtime.JspFactoryImpl$PrivilegedGetPageContext");
|
||||
factory.getClass().getClassLoader().loadClass( basePackage +
|
||||
"runtime.JspFactoryImpl$PrivilegedReleasePageContext");
|
||||
factory.getClass().getClassLoader().loadClass( basePackage +
|
||||
"runtime.JspRuntimeLibrary");
|
||||
factory.getClass().getClassLoader().loadClass( basePackage +
|
||||
"runtime.ServletResponseWrapperInclude");
|
||||
factory.getClass().getClassLoader().loadClass( basePackage +
|
||||
"servlet.JspServletWrapper");
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (JspFactory.getDefaultFactory() == null) {
|
||||
JspFactory.setDefaultFactory(factory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(Set<Class<?>> types, ServletContext context) throws ServletException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage(MSG + ".onStartup", context.getServletContextName()));
|
||||
}
|
||||
|
||||
// Setup a simple default Instance Manager
|
||||
if (context.getAttribute(InstanceManager.class.getName())==null) {
|
||||
context.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager());
|
||||
}
|
||||
|
||||
boolean validate = Boolean.parseBoolean(
|
||||
context.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM));
|
||||
String blockExternalString = context.getInitParameter(
|
||||
Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
|
||||
boolean blockExternal;
|
||||
if (blockExternalString == null) {
|
||||
blockExternal = true;
|
||||
} else {
|
||||
blockExternal = Boolean.parseBoolean(blockExternalString);
|
||||
}
|
||||
|
||||
// scan the application for TLDs
|
||||
TldScanner scanner = newTldScanner(context, true, validate, blockExternal);
|
||||
try {
|
||||
scanner.scan();
|
||||
} catch (IOException | SAXException e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
|
||||
// add any listeners defined in TLDs
|
||||
for (String listener : scanner.getListeners()) {
|
||||
context.addListener(listener);
|
||||
}
|
||||
|
||||
context.setAttribute(TldCache.SERVLET_CONTEXT_ATTRIBUTE_NAME,
|
||||
new TldCache(context, scanner.getUriTldResourcePathMap(),
|
||||
scanner.getTldResourcePathTaglibXmlMap()));
|
||||
}
|
||||
|
||||
protected TldScanner newTldScanner(ServletContext context, boolean namespaceAware,
|
||||
boolean validate, boolean blockExternal) {
|
||||
return new TldScanner(context, namespaceAware, validate, blockExternal);
|
||||
}
|
||||
}
|
||||
168
java/org/apache/jasper/servlet/JasperLoader.java
Normal file
168
java/org/apache/jasper/servlet/JasperLoader.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.jasper.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.CodeSource;
|
||||
import java.security.PermissionCollection;
|
||||
|
||||
import org.apache.jasper.Constants;
|
||||
|
||||
/**
|
||||
* Class loader for loading servlet class files (corresponding to JSP files)
|
||||
* and tag handler class files (corresponding to tag files).
|
||||
*
|
||||
* @author Anil K. Vijendran
|
||||
* @author Harish Prabandham
|
||||
*/
|
||||
public class JasperLoader extends URLClassLoader {
|
||||
|
||||
private final PermissionCollection permissionCollection;
|
||||
private final SecurityManager securityManager;
|
||||
|
||||
public JasperLoader(URL[] urls, ClassLoader parent,
|
||||
PermissionCollection permissionCollection) {
|
||||
super(urls, parent);
|
||||
this.permissionCollection = permissionCollection;
|
||||
this.securityManager = System.getSecurityManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the class with the specified name. This method searches for
|
||||
* classes in the same manner as <code>loadClass(String, boolean)</code>
|
||||
* with <code>false</code> as the second argument.
|
||||
*
|
||||
* @param name Name of the class to be loaded
|
||||
*
|
||||
* @exception ClassNotFoundException if the class was not found
|
||||
*/
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
return loadClass(name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the class with the specified name, searching using the following
|
||||
* algorithm until it finds and returns the class. If the class cannot
|
||||
* be found, returns <code>ClassNotFoundException</code>.
|
||||
* <ul>
|
||||
* <li>Call <code>findLoadedClass(String)</code> to check if the
|
||||
* class has already been loaded. If it has, the same
|
||||
* <code>Class</code> object is returned.</li>
|
||||
* <li>If the <code>delegate</code> property is set to <code>true</code>,
|
||||
* call the <code>loadClass()</code> method of the parent class
|
||||
* loader, if any.</li>
|
||||
* <li>Call <code>findClass()</code> to find this class in our locally
|
||||
* defined repositories.</li>
|
||||
* <li>Call the <code>loadClass()</code> method of our parent
|
||||
* class loader, if any.</li>
|
||||
* </ul>
|
||||
* If the class was found using the above steps, and the
|
||||
* <code>resolve</code> flag is <code>true</code>, this method will then
|
||||
* call <code>resolveClass(Class)</code> on the resulting Class object.
|
||||
*
|
||||
* @param name Name of the class to be loaded
|
||||
* @param resolve If <code>true</code> then resolve the class
|
||||
*
|
||||
* @exception ClassNotFoundException if the class was not found
|
||||
*/
|
||||
@Override
|
||||
public synchronized Class<?> loadClass(final String name, boolean resolve)
|
||||
throws ClassNotFoundException {
|
||||
|
||||
Class<?> clazz = null;
|
||||
|
||||
// (0) Check our previously loaded class cache
|
||||
clazz = findLoadedClass(name);
|
||||
if (clazz != null) {
|
||||
if (resolve)
|
||||
resolveClass(clazz);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
// (.5) Permission to access this class when using a SecurityManager
|
||||
if (securityManager != null) {
|
||||
int dot = name.lastIndexOf('.');
|
||||
if (dot >= 0) {
|
||||
try {
|
||||
// Do not call the security manager since by default, we grant that package.
|
||||
if (!"org.apache.jasper.runtime".equalsIgnoreCase(name.substring(0,dot))){
|
||||
securityManager.checkPackageAccess(name.substring(0,dot));
|
||||
}
|
||||
} catch (SecurityException se) {
|
||||
String error = "Security Violation, attempt to use " +
|
||||
"Restricted Class: " + name;
|
||||
se.printStackTrace();
|
||||
throw new ClassNotFoundException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !name.startsWith(Constants.JSP_PACKAGE_NAME + '.') ) {
|
||||
// Class is not in org.apache.jsp, therefore, have our
|
||||
// parent load it
|
||||
clazz = getParent().loadClass(name);
|
||||
if( resolve )
|
||||
resolveClass(clazz);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
return findClass(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delegate to parent
|
||||
*
|
||||
* @see java.lang.ClassLoader#getResourceAsStream(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public InputStream getResourceAsStream(String name) {
|
||||
InputStream is = getParent().getResourceAsStream(name);
|
||||
if (is == null) {
|
||||
URL url = findResource(name);
|
||||
if (url != null) {
|
||||
try {
|
||||
is = url.openStream();
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Permissions for a CodeSource.
|
||||
*
|
||||
* Since this ClassLoader is only used for a JSP page in
|
||||
* a web application context, we just return our preset
|
||||
* PermissionCollection for the web app context.
|
||||
*
|
||||
* @param codeSource Code source where the code was loaded from
|
||||
* @return PermissionCollection for CodeSource
|
||||
*/
|
||||
@Override
|
||||
public final PermissionCollection getPermissions(CodeSource codeSource) {
|
||||
return permissionCollection;
|
||||
}
|
||||
}
|
||||
785
java/org/apache/jasper/servlet/JspCServletContext.java
Normal file
785
java/org/apache/jasper/servlet/JspCServletContext.java
Normal file
File diff suppressed because it is too large
Load Diff
422
java/org/apache/jasper/servlet/JspServlet.java
Normal file
422
java/org/apache/jasper/servlet/JspServlet.java
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.jasper.servlet;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.jasper.Constants;
|
||||
import org.apache.jasper.EmbeddedServletOptions;
|
||||
import org.apache.jasper.Options;
|
||||
import org.apache.jasper.compiler.JspRuntimeContext;
|
||||
import org.apache.jasper.compiler.Localizer;
|
||||
import org.apache.jasper.runtime.ExceptionUtils;
|
||||
import org.apache.jasper.security.SecurityUtil;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
import org.apache.tomcat.PeriodicEventListener;
|
||||
import org.apache.tomcat.util.security.Escape;
|
||||
|
||||
/**
|
||||
* The JSP engine (a.k.a Jasper).
|
||||
*
|
||||
* The servlet container is responsible for providing a
|
||||
* URLClassLoader for the web application context Jasper
|
||||
* is being used in. Jasper will try get the Tomcat
|
||||
* ServletContext attribute for its ServletContext class
|
||||
* loader, if that fails, it uses the parent class loader.
|
||||
* In either case, it must be a URLClassLoader.
|
||||
*
|
||||
* @author Anil K. Vijendran
|
||||
* @author Harish Prabandham
|
||||
* @author Remy Maucherat
|
||||
* @author Kin-man Chung
|
||||
* @author Glenn Nielsen
|
||||
*/
|
||||
public class JspServlet extends HttpServlet implements PeriodicEventListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// Logger
|
||||
private final transient Log log = LogFactory.getLog(JspServlet.class);
|
||||
|
||||
private transient ServletContext context;
|
||||
private ServletConfig config;
|
||||
private transient Options options;
|
||||
private transient JspRuntimeContext rctxt;
|
||||
// jspFile for a jsp configured explicitly as a servlet, in environments where this
|
||||
// configuration is translated into an init-param for this servlet.
|
||||
private String jspFile;
|
||||
|
||||
|
||||
/*
|
||||
* Initializes this JspServlet.
|
||||
*/
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
|
||||
super.init(config);
|
||||
this.config = config;
|
||||
this.context = config.getServletContext();
|
||||
|
||||
// Initialize the JSP Runtime Context
|
||||
// Check for a custom Options implementation
|
||||
String engineOptionsName = config.getInitParameter("engineOptionsClass");
|
||||
if (Constants.IS_SECURITY_ENABLED && engineOptionsName != null) {
|
||||
log.info(Localizer.getMessage(
|
||||
"jsp.info.ignoreSetting", "engineOptionsClass", engineOptionsName));
|
||||
engineOptionsName = null;
|
||||
}
|
||||
if (engineOptionsName != null) {
|
||||
// Instantiate the indicated Options implementation
|
||||
try {
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
Class<?> engineOptionsClass = loader.loadClass(engineOptionsName);
|
||||
Class<?>[] ctorSig = { ServletConfig.class, ServletContext.class };
|
||||
Constructor<?> ctor = engineOptionsClass.getConstructor(ctorSig);
|
||||
Object[] args = { config, context };
|
||||
options = (Options) ctor.newInstance(args);
|
||||
} catch (Throwable e) {
|
||||
e = ExceptionUtils.unwrapInvocationTargetException(e);
|
||||
ExceptionUtils.handleThrowable(e);
|
||||
// Need to localize this.
|
||||
log.warn("Failed to load engineOptionsClass", e);
|
||||
// Use the default Options implementation
|
||||
options = new EmbeddedServletOptions(config, context);
|
||||
}
|
||||
} else {
|
||||
// Use the default Options implementation
|
||||
options = new EmbeddedServletOptions(config, context);
|
||||
}
|
||||
rctxt = new JspRuntimeContext(context, options);
|
||||
if (config.getInitParameter("jspFile") != null) {
|
||||
jspFile = config.getInitParameter("jspFile");
|
||||
try {
|
||||
if (null == context.getResource(jspFile)) {
|
||||
return;
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
throw new ServletException("cannot locate jsp file", e);
|
||||
}
|
||||
try {
|
||||
if (SecurityUtil.isPackageProtectionEnabled()){
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>(){
|
||||
@Override
|
||||
public Object run() throws IOException, ServletException {
|
||||
serviceJspFile(null, null, jspFile, true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
serviceJspFile(null, null, jspFile, true);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ServletException("Could not precompile jsp: " + jspFile, e);
|
||||
} catch (PrivilegedActionException e) {
|
||||
Throwable t = e.getCause();
|
||||
if (t instanceof ServletException) throw (ServletException)t;
|
||||
throw new ServletException("Could not precompile jsp: " + jspFile, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage("jsp.message.scratch.dir.is",
|
||||
options.getScratchDir().toString()));
|
||||
log.debug(Localizer.getMessage("jsp.message.dont.modify.servlets"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of JSPs for which JspServletWrappers exist, i.e.,
|
||||
* the number of JSPs that have been loaded into the webapp with which
|
||||
* this JspServlet is associated.
|
||||
*
|
||||
* <p>This info may be used for monitoring purposes.
|
||||
*
|
||||
* @return The number of JSPs that have been loaded into the webapp with
|
||||
* which this JspServlet is associated
|
||||
*/
|
||||
public int getJspCount() {
|
||||
return this.rctxt.getJspCount();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resets the JSP reload counter.
|
||||
*
|
||||
* @param count Value to which to reset the JSP reload counter
|
||||
*/
|
||||
public void setJspReloadCount(int count) {
|
||||
this.rctxt.setJspReloadCount(count);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of JSPs that have been reloaded.
|
||||
*
|
||||
* <p>This info may be used for monitoring purposes.
|
||||
*
|
||||
* @return The number of JSPs (in the webapp with which this JspServlet is
|
||||
* associated) that have been reloaded
|
||||
*/
|
||||
public int getJspReloadCount() {
|
||||
return this.rctxt.getJspReloadCount();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of JSPs that are in the JSP limiter queue
|
||||
*
|
||||
* <p>This info may be used for monitoring purposes.
|
||||
*
|
||||
* @return The number of JSPs (in the webapp with which this JspServlet is
|
||||
* associated) that are in the JSP limiter queue
|
||||
*/
|
||||
public int getJspQueueLength() {
|
||||
return this.rctxt.getJspQueueLength();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of JSPs that have been unloaded.
|
||||
*
|
||||
* <p>This info may be used for monitoring purposes.
|
||||
*
|
||||
* @return The number of JSPs (in the webapp with which this JspServlet is
|
||||
* associated) that have been unloaded
|
||||
*/
|
||||
public int getJspUnloadCount() {
|
||||
return this.rctxt.getJspUnloadCount();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Look for a <em>precompilation request</em> as described in
|
||||
* Section 8.4.2 of the JSP 1.2 Specification. <strong>WARNING</strong> -
|
||||
* we cannot use <code>request.getParameter()</code> for this, because
|
||||
* that will trigger parsing all of the request parameters, and not give
|
||||
* a servlet the opportunity to call
|
||||
* <code>request.setCharacterEncoding()</code> first.</p>
|
||||
*
|
||||
* @param request The servlet request we are processing
|
||||
*
|
||||
* @exception ServletException if an invalid parameter value for the
|
||||
* <code>jsp_precompile</code> parameter name is specified
|
||||
*/
|
||||
boolean preCompile(HttpServletRequest request) throws ServletException {
|
||||
|
||||
String queryString = request.getQueryString();
|
||||
if (queryString == null) {
|
||||
return false;
|
||||
}
|
||||
int start = queryString.indexOf(Constants.PRECOMPILE);
|
||||
if (start < 0) {
|
||||
return false;
|
||||
}
|
||||
queryString =
|
||||
queryString.substring(start + Constants.PRECOMPILE.length());
|
||||
if (queryString.length() == 0) {
|
||||
return true; // ?jsp_precompile
|
||||
}
|
||||
if (queryString.startsWith("&")) {
|
||||
return true; // ?jsp_precompile&foo=bar...
|
||||
}
|
||||
if (!queryString.startsWith("=")) {
|
||||
return false; // part of some other name or value
|
||||
}
|
||||
int limit = queryString.length();
|
||||
int ampersand = queryString.indexOf('&');
|
||||
if (ampersand > 0) {
|
||||
limit = ampersand;
|
||||
}
|
||||
String value = queryString.substring(1, limit);
|
||||
if (value.equals("true")) {
|
||||
return true; // ?jsp_precompile=true
|
||||
} else if (value.equals("false")) {
|
||||
// Spec says if jsp_precompile=false, the request should not
|
||||
// be delivered to the JSP page; the easiest way to implement
|
||||
// this is to set the flag to true, and precompile the page anyway.
|
||||
// This still conforms to the spec, since it says the
|
||||
// precompilation request can be ignored.
|
||||
return true; // ?jsp_precompile=false
|
||||
} else {
|
||||
throw new ServletException("Cannot have request parameter " +
|
||||
Constants.PRECOMPILE + " set to " +
|
||||
value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void service (HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
// jspFile may be configured as an init-param for this servlet instance
|
||||
String jspUri = jspFile;
|
||||
|
||||
if (jspUri == null) {
|
||||
/*
|
||||
* Check to see if the requested JSP has been the target of a
|
||||
* RequestDispatcher.include()
|
||||
*/
|
||||
jspUri = (String) request.getAttribute(
|
||||
RequestDispatcher.INCLUDE_SERVLET_PATH);
|
||||
if (jspUri != null) {
|
||||
/*
|
||||
* Requested JSP has been target of
|
||||
* RequestDispatcher.include(). Its path is assembled from the
|
||||
* relevant javax.servlet.include.* request attributes
|
||||
*/
|
||||
String pathInfo = (String) request.getAttribute(
|
||||
RequestDispatcher.INCLUDE_PATH_INFO);
|
||||
if (pathInfo != null) {
|
||||
jspUri += pathInfo;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Requested JSP has not been the target of a
|
||||
* RequestDispatcher.include(). Reconstruct its path from the
|
||||
* request's getServletPath() and getPathInfo()
|
||||
*/
|
||||
jspUri = request.getServletPath();
|
||||
String pathInfo = request.getPathInfo();
|
||||
if (pathInfo != null) {
|
||||
jspUri += pathInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("JspEngine --> " + jspUri);
|
||||
log.debug("\t ServletPath: " + request.getServletPath());
|
||||
log.debug("\t PathInfo: " + request.getPathInfo());
|
||||
log.debug("\t RealPath: " + context.getRealPath(jspUri));
|
||||
log.debug("\t RequestURI: " + request.getRequestURI());
|
||||
log.debug("\t QueryString: " + request.getQueryString());
|
||||
}
|
||||
|
||||
try {
|
||||
boolean precompile = preCompile(request);
|
||||
serviceJspFile(request, response, jspUri, precompile);
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (ServletException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
ExceptionUtils.handleThrowable(e);
|
||||
throw new ServletException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("JspServlet.destroy()");
|
||||
}
|
||||
|
||||
rctxt.destroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void periodicEvent() {
|
||||
rctxt.checkUnload();
|
||||
rctxt.checkCompile();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------- Private Methods
|
||||
|
||||
private void serviceJspFile(HttpServletRequest request,
|
||||
HttpServletResponse response, String jspUri,
|
||||
boolean precompile)
|
||||
throws ServletException, IOException {
|
||||
|
||||
JspServletWrapper wrapper = rctxt.getWrapper(jspUri);
|
||||
if (wrapper == null) {
|
||||
synchronized(this) {
|
||||
wrapper = rctxt.getWrapper(jspUri);
|
||||
if (wrapper == null) {
|
||||
// Check if the requested JSP page exists, to avoid
|
||||
// creating unnecessary directories and files.
|
||||
if (null == context.getResource(jspUri)) {
|
||||
handleMissingResource(request, response, jspUri);
|
||||
return;
|
||||
}
|
||||
wrapper = new JspServletWrapper(config, options, jspUri,
|
||||
rctxt);
|
||||
rctxt.addWrapper(jspUri,wrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
wrapper.service(request, response, precompile);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
handleMissingResource(request, response, jspUri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void handleMissingResource(HttpServletRequest request,
|
||||
HttpServletResponse response, String jspUri)
|
||||
throws ServletException, IOException {
|
||||
|
||||
String includeRequestUri =
|
||||
(String)request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);
|
||||
|
||||
if (includeRequestUri != null) {
|
||||
// This file was included. Throw an exception as
|
||||
// a response.sendError() will be ignored
|
||||
String msg =
|
||||
Localizer.getMessage("jsp.error.file.not.found",jspUri);
|
||||
// Strictly, filtering this is an application
|
||||
// responsibility but just in case...
|
||||
throw new ServletException(Escape.htmlElementContent(msg));
|
||||
} else {
|
||||
try {
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND,
|
||||
request.getRequestURI());
|
||||
} catch (IllegalStateException ise) {
|
||||
log.error(Localizer.getMessage("jsp.error.file.not.found",
|
||||
jspUri));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
637
java/org/apache/jasper/servlet/JspServletWrapper.java
Normal file
637
java/org/apache/jasper/servlet/JspServletWrapper.java
Normal file
File diff suppressed because it is too large
Load Diff
55
java/org/apache/jasper/servlet/TldPreScanned.java
Normal file
55
java/org/apache/jasper/servlet/TldPreScanned.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.jasper.servlet;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.tomcat.util.descriptor.tld.TldResourcePath;
|
||||
|
||||
public class TldPreScanned extends TldScanner {
|
||||
|
||||
private final Collection<URL> preScannedURLs;
|
||||
|
||||
public TldPreScanned (ServletContext context, boolean namespaceAware, boolean validation,
|
||||
boolean blockExternal, Collection<URL> preScannedTlds) {
|
||||
super(context, namespaceAware, validation, blockExternal);
|
||||
preScannedURLs = preScannedTlds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scanJars() {
|
||||
for (URL url : preScannedURLs){
|
||||
String str = url.toExternalForm();
|
||||
int a = str.indexOf("jar:");
|
||||
int b = str.indexOf("!/");
|
||||
if (a >= 0 && b> 0) {
|
||||
String fileUrl = str.substring(a + 4, b);
|
||||
String path = str.substring(b + 2);
|
||||
try {
|
||||
parseTld(new TldResourcePath(new URL(fileUrl), null, path));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Bad tld url: "+str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
414
java/org/apache/jasper/servlet/TldScanner.java
Normal file
414
java/org/apache/jasper/servlet/TldScanner.java
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.jasper.servlet;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.descriptor.JspConfigDescriptor;
|
||||
import javax.servlet.descriptor.TaglibDescriptor;
|
||||
|
||||
import org.apache.jasper.compiler.JarScannerFactory;
|
||||
import org.apache.jasper.compiler.Localizer;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
import org.apache.tomcat.Jar;
|
||||
import org.apache.tomcat.JarScanType;
|
||||
import org.apache.tomcat.JarScanner;
|
||||
import org.apache.tomcat.JarScannerCallback;
|
||||
import org.apache.tomcat.util.descriptor.tld.TaglibXml;
|
||||
import org.apache.tomcat.util.descriptor.tld.TldParser;
|
||||
import org.apache.tomcat.util.descriptor.tld.TldResourcePath;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Scans for and loads Tag Library Descriptors contained in a web application.
|
||||
*/
|
||||
public class TldScanner {
|
||||
private final Log log = LogFactory.getLog(TldScanner.class); // must not be static
|
||||
private static final String MSG = "org.apache.jasper.servlet.TldScanner";
|
||||
private static final String TLD_EXT = ".tld";
|
||||
private static final String WEB_INF = "/WEB-INF/";
|
||||
private final ServletContext context;
|
||||
private final TldParser tldParser;
|
||||
private final Map<String, TldResourcePath> uriTldResourcePathMap = new HashMap<>();
|
||||
private final Map<TldResourcePath, TaglibXml> tldResourcePathTaglibXmlMap = new HashMap<>();
|
||||
private final List<String> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Initialise with the application's ServletContext.
|
||||
*
|
||||
* @param context the application's servletContext
|
||||
* @param namespaceAware should the XML parser used to parse TLD files be
|
||||
* configured to be name space aware
|
||||
* @param validation should the XML parser used to parse TLD files be
|
||||
* configured to use validation
|
||||
* @param blockExternal should the XML parser used to parse TLD files be
|
||||
* configured to be block references to external
|
||||
* entities
|
||||
*/
|
||||
public TldScanner(ServletContext context,
|
||||
boolean namespaceAware,
|
||||
boolean validation,
|
||||
boolean blockExternal) {
|
||||
this.context = context;
|
||||
|
||||
this.tldParser = new TldParser(namespaceAware, validation, blockExternal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for TLDs in all places defined by the specification:
|
||||
* <ol>
|
||||
* <li>Tag libraries defined by the platform</li>
|
||||
* <li>Entries from <jsp-config> in web.xml</li>
|
||||
* <li>A resources under /WEB-INF</li>
|
||||
* <li>In jar files from /WEB-INF/lib</li>
|
||||
* <li>Additional entries from the container</li>
|
||||
* </ol>
|
||||
*
|
||||
* @throws IOException if there was a problem scanning for or loading a TLD
|
||||
* @throws SAXException if there was a problem parsing a TLD
|
||||
*/
|
||||
public void scan() throws IOException, SAXException {
|
||||
scanPlatform();
|
||||
scanJspConfig();
|
||||
scanResourcePaths(WEB_INF);
|
||||
scanJars();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of URI to TldResourcePath built by this scanner.
|
||||
*
|
||||
* @return the map of URI to TldResourcePath
|
||||
*/
|
||||
public Map<String, TldResourcePath> getUriTldResourcePathMap() {
|
||||
return uriTldResourcePathMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of TldResourcePath to parsed XML files built by this
|
||||
* scanner.
|
||||
*
|
||||
* @return the map of TldResourcePath to parsed XML files
|
||||
*/
|
||||
public Map<TldResourcePath,TaglibXml> getTldResourcePathTaglibXmlMap() {
|
||||
return tldResourcePathTaglibXmlMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all listeners declared by scanned TLDs.
|
||||
*
|
||||
* @return a list of listener class names
|
||||
*/
|
||||
public List<String> getListeners() {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class loader used by the digester to create objects as a result
|
||||
* of this scan. Normally this only needs to be set when using JspC.
|
||||
*
|
||||
* @param classLoader Class loader to use when creating new objects while
|
||||
* parsing TLDs
|
||||
*/
|
||||
public void setClassLoader(ClassLoader classLoader) {
|
||||
tldParser.setClassLoader(classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for TLDs required by the platform specification.
|
||||
*/
|
||||
protected void scanPlatform() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for TLDs defined in <jsp-config>.
|
||||
* @throws IOException Error reading resources
|
||||
* @throws SAXException XML parsing error
|
||||
*/
|
||||
protected void scanJspConfig() throws IOException, SAXException {
|
||||
JspConfigDescriptor jspConfigDescriptor = context.getJspConfigDescriptor();
|
||||
if (jspConfigDescriptor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<TaglibDescriptor> descriptors = jspConfigDescriptor.getTaglibs();
|
||||
for (TaglibDescriptor descriptor : descriptors) {
|
||||
String taglibURI = descriptor.getTaglibURI();
|
||||
String resourcePath = descriptor.getTaglibLocation();
|
||||
// Note: Whilst the Servlet 2.4 DTD implies that the location must
|
||||
// be a context-relative path starting with '/', JSP.7.3.6.1 states
|
||||
// explicitly how paths that do not start with '/' should be
|
||||
// handled.
|
||||
if (!resourcePath.startsWith("/")) {
|
||||
resourcePath = WEB_INF + resourcePath;
|
||||
}
|
||||
if (uriTldResourcePathMap.containsKey(taglibURI)) {
|
||||
log.warn(Localizer.getMessage(MSG + ".webxmlSkip",
|
||||
resourcePath,
|
||||
taglibURI));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace(Localizer.getMessage(MSG + ".webxmlAdd",
|
||||
resourcePath,
|
||||
taglibURI));
|
||||
}
|
||||
|
||||
URL url = context.getResource(resourcePath);
|
||||
if (url != null) {
|
||||
TldResourcePath tldResourcePath;
|
||||
if (resourcePath.endsWith(".jar")) {
|
||||
// if the path points to a jar file, the TLD is presumed to be
|
||||
// inside at META-INF/taglib.tld
|
||||
tldResourcePath = new TldResourcePath(url, resourcePath, "META-INF/taglib.tld");
|
||||
} else {
|
||||
tldResourcePath = new TldResourcePath(url, resourcePath);
|
||||
}
|
||||
// parse TLD but store using the URI supplied in the descriptor
|
||||
TaglibXml tld = tldParser.parse(tldResourcePath);
|
||||
uriTldResourcePathMap.put(taglibURI, tldResourcePath);
|
||||
tldResourcePathTaglibXmlMap.put(tldResourcePath, tld);
|
||||
if (tld.getListeners() != null) {
|
||||
listeners.addAll(tld.getListeners());
|
||||
}
|
||||
} else {
|
||||
log.warn(Localizer.getMessage(MSG + ".webxmlFailPathDoesNotExist",
|
||||
resourcePath,
|
||||
taglibURI));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan web application resources for TLDs, recursively.
|
||||
*
|
||||
* @param startPath the directory resource to scan
|
||||
* @throws IOException if there was a problem scanning for or loading a TLD
|
||||
* @throws SAXException if there was a problem parsing a TLD
|
||||
*/
|
||||
protected void scanResourcePaths(String startPath)
|
||||
throws IOException, SAXException {
|
||||
|
||||
boolean found = false;
|
||||
Set<String> dirList = context.getResourcePaths(startPath);
|
||||
if (dirList != null) {
|
||||
for (String path : dirList) {
|
||||
if (path.startsWith("/WEB-INF/classes/")) {
|
||||
// Skip: JSP.7.3.1
|
||||
} else if (path.startsWith("/WEB-INF/lib/")) {
|
||||
// Skip: JSP.7.3.1
|
||||
} else if (path.endsWith("/")) {
|
||||
scanResourcePaths(path);
|
||||
} else if (path.startsWith("/WEB-INF/tags/")) {
|
||||
// JSP 7.3.1: in /WEB-INF/tags only consider implicit.tld
|
||||
if (path.endsWith("/implicit.tld")) {
|
||||
found = true;
|
||||
parseTld(path);
|
||||
}
|
||||
} else if (path.endsWith(TLD_EXT)) {
|
||||
found = true;
|
||||
parseTld(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage("jsp.tldCache.tldInResourcePath", startPath));
|
||||
}
|
||||
} else {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage("jsp.tldCache.noTldInResourcePath", startPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for TLDs in JARs in /WEB-INF/lib.
|
||||
*/
|
||||
public void scanJars() {
|
||||
JarScanner scanner = JarScannerFactory.getJarScanner(context);
|
||||
TldScannerCallback callback = new TldScannerCallback();
|
||||
scanner.scan(JarScanType.TLD, context, callback);
|
||||
if (callback.scanFoundNoTLDs()) {
|
||||
log.info(Localizer.getMessage("jsp.tldCache.noTldSummary"));
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseTld(String resourcePath) throws IOException, SAXException {
|
||||
TldResourcePath tldResourcePath =
|
||||
new TldResourcePath(context.getResource(resourcePath), resourcePath);
|
||||
parseTld(tldResourcePath);
|
||||
}
|
||||
|
||||
protected void parseTld(TldResourcePath path) throws IOException, SAXException {
|
||||
if (tldResourcePathTaglibXmlMap.containsKey(path)) {
|
||||
// TLD has already been parsed as a result of processing web.xml
|
||||
return;
|
||||
}
|
||||
TaglibXml tld = tldParser.parse(path);
|
||||
String uri = tld.getUri();
|
||||
if (uri != null) {
|
||||
if (!uriTldResourcePathMap.containsKey(uri)) {
|
||||
uriTldResourcePathMap.put(uri, path);
|
||||
}
|
||||
}
|
||||
tldResourcePathTaglibXmlMap.put(path, tld);
|
||||
if (tld.getListeners() != null) {
|
||||
listeners.addAll(tld.getListeners());
|
||||
}
|
||||
}
|
||||
|
||||
class TldScannerCallback implements JarScannerCallback {
|
||||
private boolean foundJarWithoutTld = false;
|
||||
private boolean foundFileWithoutTld = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void scan(Jar jar, String webappPath, boolean isWebapp) throws IOException {
|
||||
boolean found = false;
|
||||
URL jarFileUrl = jar.getJarFileURL();
|
||||
jar.nextEntry();
|
||||
for (String entryName = jar.getEntryName();
|
||||
entryName != null;
|
||||
jar.nextEntry(), entryName = jar.getEntryName()) {
|
||||
if (!(entryName.startsWith("META-INF/") &&
|
||||
entryName.endsWith(TLD_EXT))) {
|
||||
continue;
|
||||
}
|
||||
found = true;
|
||||
TldResourcePath tldResourcePath =
|
||||
new TldResourcePath(jarFileUrl, webappPath, entryName);
|
||||
try {
|
||||
parseTld(tldResourcePath);
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage("jsp.tldCache.tldInJar", jarFileUrl.toString()));
|
||||
}
|
||||
} else {
|
||||
foundJarWithoutTld = true;
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage(
|
||||
"jsp.tldCache.noTldInJar", jarFileUrl.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scan(File file, final String webappPath, boolean isWebapp)
|
||||
throws IOException {
|
||||
File metaInf = new File(file, "META-INF");
|
||||
if (!metaInf.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
foundFileWithoutTld = false;
|
||||
final Path filePath = file.toPath();
|
||||
Files.walkFileTree(metaInf.toPath(), new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file,
|
||||
BasicFileAttributes attrs)
|
||||
throws IOException {
|
||||
Path fileName = file.getFileName();
|
||||
if (fileName == null || !fileName.toString().toLowerCase(
|
||||
Locale.ENGLISH).endsWith(TLD_EXT)) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
foundFileWithoutTld = true;
|
||||
String resourcePath;
|
||||
if (webappPath == null) {
|
||||
resourcePath = null;
|
||||
} else {
|
||||
String subPath = file.subpath(
|
||||
filePath.getNameCount(), file.getNameCount()).toString();
|
||||
if ('/' != File.separatorChar) {
|
||||
subPath = subPath.replace(File.separatorChar, '/');
|
||||
}
|
||||
resourcePath = webappPath + "/" + subPath;
|
||||
}
|
||||
|
||||
try {
|
||||
URL url = file.toUri().toURL();
|
||||
TldResourcePath path = new TldResourcePath(url, resourcePath);
|
||||
parseTld(path);
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
if (foundFileWithoutTld) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage("jsp.tldCache.tldInDir",
|
||||
file.getAbsolutePath()));
|
||||
}
|
||||
} else {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage("jsp.tldCache.noTldInDir",
|
||||
file.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scanWebInfClasses() throws IOException {
|
||||
// This is used when scanAllDirectories is enabled and one or more
|
||||
// JARs have been unpacked into WEB-INF/classes as happens with some
|
||||
// IDEs.
|
||||
|
||||
Set<String> paths = context.getResourcePaths(WEB_INF + "classes/META-INF");
|
||||
if (paths == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String path : paths) {
|
||||
if (path.endsWith(TLD_EXT)) {
|
||||
try {
|
||||
parseTld(path);
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean scanFoundNoTLDs() {
|
||||
return foundJarWithoutTld;
|
||||
}
|
||||
}
|
||||
}
|
||||
45
java/org/apache/jasper/servlet/mbeans-descriptors.xml
Normal file
45
java/org/apache/jasper/servlet/mbeans-descriptors.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<mbeans-descriptors>
|
||||
|
||||
<mbean name="JspMonitor"
|
||||
description="JSP Monitoring"
|
||||
domain="Catalina"
|
||||
group="Monitoring"
|
||||
type="org.apache.jasper.servlet.JspServlet">
|
||||
|
||||
<attribute name="jspCount"
|
||||
description="The number of JSPs that have been loaded into a webapp"
|
||||
type="int"
|
||||
writeable="false"/>
|
||||
|
||||
<attribute name="jspReloadCount"
|
||||
description="The number of JSPs that have been reloaded"
|
||||
type="int"/>
|
||||
|
||||
<attribute name="jspUnloadCount"
|
||||
description="The number of JSPs that have been unloaded"
|
||||
type="int"/>
|
||||
|
||||
<attribute name="jspQueueLength"
|
||||
description="The length of the JSP queue (if enabled via maxLoadedJsps)"
|
||||
type="int"/>
|
||||
|
||||
</mbean>
|
||||
|
||||
</mbeans-descriptors>
|
||||
Reference in New Issue
Block a user