/** Method used to initialize classpath for compiles. */ private void initClassPath() { URL[] urls = parentClassLoader.getURLs(); StringBuffer cpath = new StringBuffer(); String sep = System.getProperty("path.separator"); for (int i = 0; i < urls.length; i++) { // Tomcat 4 can use URL's other than file URL's, // a protocol other than file: will generate a // bad file system path, so only add file: // protocol URL's to the classpath. if (urls[i].getProtocol().equals("file")) { cpath.append((String) urls[i].getFile() + sep); } } cpath.append(options.getScratchDir() + sep); String cp = (String) context.getAttribute(Constants.SERVLET_CLASSPATH); if (cp == null || cp.equals("")) { cp = options.getClassPath(); } classpath = cpath.toString() + cp; if (log.isDebugEnabled()) { log.debug("Compilation classpath initialized: " + getClassPath()); } }
/* * JspServletWrapper for JSP pages. */ public JspServletWrapper( ServletConfig config, Options options, String jspUri, JspRuntimeContext rctxt) { this.isTagFile = false; this.config = config; 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, options, config.getServletContext(), this, rctxt); }
/** * Get an instance of JavaCompiler. If Running with JDK 6, use a Jsr199JavaCompiler that supports * JSR199, else if eclipse's JDT compiler is available, use that. The default is to use javac from * ant. */ private void initJavaCompiler() throws JasperException { if (options.getCompilerClassName() != null) { Class c = getClassFor(options.getCompilerClassName()); try { javaCompiler = (JavaCompiler) c.newInstance(); } catch (Exception ex) { } } if (javaCompiler == null) { boolean disablejsr199 = Boolean.TRUE .toString() .equals(System.getProperty("org.apache.jasper.compiler.disablejsr199")); Double version = Double.valueOf(System.getProperty("java.specification.version")); if (!disablejsr199 && (version >= 1.6 || getClassFor("javax.tools.Tool") != null)) { // JDK 6 or bundled with jsr199 compiler javaCompiler = new Jsr199JavaCompiler(); } else { Class c = getClassFor("org.eclipse.jdt.internal.compiler.Compiler"); if (c != null) { c = getClassFor("org.apache.jasper.compiler.JDTJavaCompiler"); if (c != null) { try { javaCompiler = (JavaCompiler) c.newInstance(); } catch (Exception ex) { } } } } } if (javaCompiler == null) { Class c = getClassFor("org.apache.tools.ant.taskdefs.Javac"); if (c != null) { c = getClassFor("org.apache.jasper.compiler.AntJavaCompiler"); if (c != null) { try { javaCompiler = (JavaCompiler) c.newInstance(); } catch (Exception ex) { } } } } if (javaCompiler == null) { errDispatcher.jspError("jsp.error.nojavac"); } javaCompiler.init(ctxt, errDispatcher, jspcMode); }
/** Compile (if needed) and load a tag file */ public Class<?> loadTagFile() throws JasperException { try { if (ctxt.isRemoved()) { throw new FileNotFoundException(jspUri); } if (options.getDevelopment() || firstTime) { synchronized (this) { firstTime = false; ctxt.compile(); } } else { if (compileException != null) { throw compileException; } } if (reload) { tagHandlerClass = ctxt.load(); reload = false; } } catch (FileNotFoundException ex) { throw new JasperException(ex); } return tagHandlerClass; }
/** * Method used by background thread to check the JSP dependencies registered with this class for * JSP's. */ public void checkCompile() { if (lastCheck < 0) { // Checking was disabled return; } long now = System.currentTimeMillis(); if (now > (lastCheck + (options.getCheckInterval() * 1000L))) { lastCheck = now; } else { return; } Object[] wrappers = jsps.values().toArray(); for (int i = 0; i < wrappers.length; i++) { JspServletWrapper jsw = (JspServletWrapper) wrappers[i]; JspCompilationContext ctxt = jsw.getJspEngineContext(); // JspServletWrapper also synchronizes on this when // it detects it has to do a reload synchronized (jsw) { try { ctxt.compile(); } catch (FileNotFoundException ex) { ctxt.incrementRemoved(); } catch (Throwable t) { jsw.getServletContext().log("Background compile failed", t); } } } }
/* * JspServletWrapper for tag files. */ public JspServletWrapper( ServletContext servletContext, Options options, String tagFilePath, TagInfo tagInfo, JspRuntimeContext rctxt, JarResource tagJarResource) { this.isTagFile = true; this.config = null; // not used this.options = options; 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); }
/** * Create a JspRuntimeContext for a web application context. * * <p>Loads in any previously generated dependencies from file. * * @param context ServletContext for web application */ public JspRuntimeContext(ServletContext context, Options options) { this.context = context; this.options = options; // Get the parent class loader parentClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader(); if (parentClassLoader == null) { parentClassLoader = (URLClassLoader) this.getClass().getClassLoader(); } if (log.isDebugEnabled()) { if (parentClassLoader != null) { log.debug( Localizer.getMessage( "jsp.message.parent_class_loader_is", parentClassLoader.toString())); } else { log.debug(Localizer.getMessage("jsp.message.parent_class_loader_is", "<none>")); } } initClassPath(); if (context instanceof org.apache.jasper.servlet.JspCServletContext) { return; } if (Constants.IS_SECURITY_ENABLED) { initSecurity(); } // If this web application context is running from a // directory, start the background compilation thread String appBase = context.getRealPath("/"); if (!options.getDevelopment() && appBase != null && options.getCheckInterval() > 0) { lastCheck = System.currentTimeMillis(); } }
/** * 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 number in the JSP. Then constructs an exception containing * that information, and a snippet of the JSP to help debugging. Please see * http://issues.apache.org/bugzilla/show_bug.cgi?id=37062 and http://www.tfenne.com/jasper/ for * more details. * * @param ex the exception that was the cause of the problem. * @return a JasperException with more detailed information */ protected JasperException handleJspException(Exception ex) { try { Throwable realException = ex; if (ex instanceof ServletException) { realException = ((ServletException) ex).getRootCause(); } // First identify the stack frame in the trace that represents the JSP StackTraceElement[] frames = realException.getStackTrace(); StackTraceElement jspFrame = null; for (int i = 0; i < frames.length; ++i) { if (frames[i].getClassName().equals(this.getServlet().getClass().getName())) { jspFrame = frames[i]; break; } } if (jspFrame == null || this.ctxt.getCompiler().getPageNodes() == null) { // If we couldn't find a frame in the stack trace corresponding // to the generated servlet class or we don't have a copy of the // parsed JSP to hand, we can't really add anything return new JasperException(ex); } int javaLineNumber = jspFrame.getLineNumber(); JavacErrorDetail detail = ErrorDispatcher.createJavacError( jspFrame.getMethodName(), this.ctxt.getCompiler().getPageNodes(), null, javaLineNumber, ctxt); // If the line number is less than one we couldn't find out // where in the JSP things went wrong int jspLineNumber = detail.getJspBeginLineNumber(); if (jspLineNumber < 1) { throw new JasperException(ex); } if (options.getDisplaySourceFragment()) { return new JasperException( Localizer.getMessage("jsp.exception", detail.getJspFileName(), "" + jspLineNumber) + Constants.NEWLINE + Constants.NEWLINE + detail.getJspExtract() + Constants.NEWLINE + Constants.NEWLINE + "Stacktrace:", ex); } return new JasperException( Localizer.getMessage("jsp.exception", detail.getJspFileName(), "" + jspLineNumber), ex); } catch (Exception je) { // If anything goes wrong, just revert to the original behaviour if (ex instanceof JasperException) { return (JasperException) ex; } return new JasperException(ex); } }
public void service(HttpServletRequest request, HttpServletResponse response, boolean precompile) throws ServletException, IOException, FileNotFoundException { Servlet servlet; try { if (ctxt.isRemoved()) { throw new FileNotFoundException(jspUri); } if ((available > 0L) && (available < Long.MAX_VALUE)) { if (available > System.currentTimeMillis()) { response.setDateHeader("Retry-After", available); response.sendError( HttpServletResponse.SC_SERVICE_UNAVAILABLE, Localizer.getMessage("jsp.error.unavailable")); return; } // Wait period has expired. Reset. available = 0; } /* * (1) Compile */ if (options.getDevelopment() || firstTime) { synchronized (this) { firstTime = false; // The following sets reload to true, if necessary ctxt.compile(); } } else { if (compileException != null) { // Throw cached compilation exception throw compileException; } } /* * (2) (Re)load servlet class file */ servlet = getServlet(); // If a page is to be precompiled only, return. if (precompile) { return; } } catch (ServletException ex) { if (options.getDevelopment()) { throw handleJspException(ex); } throw ex; } catch (FileNotFoundException fnfe) { // File has been removed. Let caller handle this. throw fnfe; } catch (IOException ex) { if (options.getDevelopment()) { throw handleJspException(ex); } throw ex; } catch (IllegalStateException ex) { if (options.getDevelopment()) { throw handleJspException(ex); } throw ex; } catch (Exception ex) { if (options.getDevelopment()) { throw handleJspException(ex); } throw new JasperException(ex); } try { /* * (3) Handle limitation of number of loaded Jsps */ if (unloadAllowed) { synchronized (this) { 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(); } } } } /* * (4) Service request */ if (servlet instanceof SingleThreadModel) { // sync on the wrapper so that the freshness // of the page is determined right before servicing synchronized (this) { servlet.service(request, response); } } else { servlet.service(request, response); } } catch (UnavailableException ex) { 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 by the // servlet engine. throw ex; } int unavailableSeconds = ex.getUnavailableSeconds(); if (unavailableSeconds <= 0) { unavailableSeconds = 60; // Arbitrary default } available = System.currentTimeMillis() + (unavailableSeconds * 1000L); response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, ex.getMessage()); } catch (ServletException ex) { if (options.getDevelopment()) { throw handleJspException(ex); } throw ex; } catch (IOException ex) { if (options.getDevelopment()) { throw handleJspException(ex); } throw ex; } catch (IllegalStateException ex) { if (options.getDevelopment()) { throw handleJspException(ex); } throw ex; } catch (Exception ex) { if (options.getDevelopment()) { throw handleJspException(ex); } throw new JasperException(ex); } }
/* * Initializes this JspServlet. */ @Override public void init(ServletConfig config) throws ServletException, RemoteException { try { 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 (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 = gerenciadornuvem1.ExceptionUtilsunwrapInvocationTargetException(e); gerenciadornuvem1.ExceptionUtilshandleThrowable(e); // Need to localize this. log.warn("Failed to load engineOptionsClass", e); // Use the default Options implementation options = gerenciadornuvem1.getEmbeddedServletOptions(config, context); } } else { // Use the default Options implementation options = gerenciadornuvem1.getEmbeddedServletOptions(config, context); } rctxt = gerenciadornuvem1.getJspRuntimeContext(context, options); if (config.getInitParameter("jspFile") != null) { jspFile = config.getInitParameter("jspFile"); try { if (null == context.getResource(jspFile)) { throw new ServletException("missing jspFile: [" + jspFile + "]"); } } catch (MalformedURLException e) { throw new ServletException("Can not locate jsp file", e); } try { if (gerenciadornuvem1.SecurityUtil2isPackageProtectionEnabled()) { AccessController.doPrivileged( new PrivilegedExceptionAction<Object>() { @Override public Object run() throws IOException, ServletException, RemoteException { 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( gerenciadornuvem0.LocalizergetMessage( "jsp.message.scratch.dir.is", options.getScratchDir().toString())); log.debug(gerenciadornuvem0.LocalizergetMessage("jsp.message.dont.modify.servlets")); } } catch (Exception excp) { excp.printStackTrace(); } }
/** Compile the servlet from .java file to .class file */ private void generateClass() throws FileNotFoundException, JasperException, Exception { long t1 = 0; if (log.isLoggable(Level.FINE)) { t1 = System.currentTimeMillis(); } String javaFileName = ctxt.getServletJavaFileName(); String classpath = ctxt.getClassPath(); String sep = System.getProperty("path.separator"); // Initializing classpath ArrayList<File> cpath = new ArrayList<File>(); HashSet<String> paths = new HashSet<String>(); // Process classpath, which includes system classpath from compiler // options, plus the context classpath from the classloader String sysClassPath = options.getSystemClassPath(); if (sysClassPath != null) { StringTokenizer tokenizer = new StringTokenizer(sysClassPath, sep); while (tokenizer.hasMoreElements()) { String path = tokenizer.nextToken(); if (!paths.contains(path) && !systemJarInWebinf(path)) { paths.add(path); cpath.add(new File(path)); } } } if (classpath != null) { StringTokenizer tokenizer = new StringTokenizer(classpath, sep); while (tokenizer.hasMoreElements()) { String path = tokenizer.nextToken(); if (!paths.contains(path) && !systemJarInWebinf(path)) { paths.add(path); cpath.add(new File(path)); } } } if (log.isLoggable(Level.FINE)) { log.fine("Using classpath: " + sysClassPath + sep + classpath); } javaCompiler.setClassPath(cpath); // Set debug info javaCompiler.setDebug(options.getClassDebugInfo()); // Initialize and set java extensions String exts = System.getProperty("java.ext.dirs"); if (exts != null) { javaCompiler.setExtdirs(exts); } if (options.getCompilerTargetVM() != null) { javaCompiler.setTargetVM(options.getCompilerTargetVM()); } if (options.getCompilerSourceVM() != null) { javaCompiler.setSourceVM(options.getCompilerSourceVM()); } // Start java compilation JavacErrorDetail[] javacErrors = javaCompiler.compile(ctxt.getFullClassName(), pageNodes); if (javacErrors != null) { // If there are errors, always generate java files to disk. javaCompiler.doJavaFile(true); log.severe("Error compiling file: " + javaFileName); errDispatcher.javacError(javacErrors); } if (log.isLoggable(Level.FINE)) { long t2 = System.currentTimeMillis(); log.fine("Compiled " + javaFileName + " " + (t2 - t1) + "ms"); } // Save or delete the generated Java files, depending on the // value of "keepgenerated" attribute javaCompiler.doJavaFile(ctxt.keepGenerated()); // JSR45 Support if (!ctxt.isPrototypeMode() && !options.isSmapSuppressed()) { smapUtil.installSmap(); } // START CR 6373479 if (jsw != null && jsw.getServletClassLastModifiedTime() <= 0) { jsw.setServletClassLastModifiedTime(javaCompiler.getClassLastModified()); } // END CR 6373479 if (options.getSaveBytecode()) { javaCompiler.saveClassFile(ctxt.getFullClassName(), ctxt.getClassFileName()); } // On some systems, due to file caching, the time stamp for the updated // JSP file may actually be greater than that of the newly created byte // codes in the cache. In such cases, adjust the cache time stamp to // JSP page time, to avoid unnecessary recompilations. ctxt.getRuntimeContext().adjustBytecodeTime(ctxt.getFullClassName(), jspModTime); }
/** Compile the jsp file into equivalent servlet in java source */ private void generateJava() throws Exception { long t1, t2, t3, t4; t1 = t2 = t3 = t4 = 0; if (log.isLoggable(Level.FINE)) { t1 = System.currentTimeMillis(); } // Setup page info area pageInfo = new PageInfo(new BeanRepository(ctxt.getClassLoader(), errDispatcher), ctxt.getJspFile()); JspConfig jspConfig = options.getJspConfig(); JspProperty jspProperty = jspConfig.findJspProperty(ctxt.getJspFile()); /* * If the current uri is matched by a pattern specified in * a jsp-property-group in web.xml, initialize pageInfo with * those properties. */ pageInfo.setELIgnored(JspUtil.booleanValue(jspProperty.isELIgnored())); pageInfo.setScriptingInvalid(JspUtil.booleanValue(jspProperty.isScriptingInvalid())); pageInfo.setTrimDirectiveWhitespaces(JspUtil.booleanValue(jspProperty.getTrimSpaces())); pageInfo.setDeferredSyntaxAllowedAsLiteral(JspUtil.booleanValue(jspProperty.getPoundAllowed())); pageInfo.setErrorOnUndeclaredNamespace( JspUtil.booleanValue(jspProperty.errorOnUndeclaredNamespace())); if (jspProperty.getIncludePrelude() != null) { pageInfo.setIncludePrelude(jspProperty.getIncludePrelude()); } if (jspProperty.getIncludeCoda() != null) { pageInfo.setIncludeCoda(jspProperty.getIncludeCoda()); } if (options.isDefaultBufferNone() && pageInfo.getBufferValue() == null) { // Set to unbuffered if not specified explicitly pageInfo.setBuffer(0); } String javaFileName = ctxt.getServletJavaFileName(); ServletWriter writer = null; try { // Setup the ServletWriter Writer javaWriter = javaCompiler.getJavaWriter(javaFileName, ctxt.getOptions().getJavaEncoding()); writer = new ServletWriter(new PrintWriter(javaWriter)); ctxt.setWriter(writer); // Reset the temporary variable counter for the generator. JspUtil.resetTemporaryVariableName(); // Parse the file ParserController parserCtl = new ParserController(ctxt, this); pageNodes = parserCtl.parse(ctxt.getJspFile()); if (ctxt.isPrototypeMode()) { // generate prototype .java file for the tag file Generator.generate(writer, this, pageNodes); writer.close(); writer = null; return; } // Validate and process attributes Validator.validate(this, pageNodes); if (log.isLoggable(Level.FINE)) { t2 = System.currentTimeMillis(); } // Collect page info Collector.collect(this, pageNodes); // Compile (if necessary) and load the tag files referenced in // this compilation unit. tfp = new TagFileProcessor(); tfp.loadTagFiles(this, pageNodes); if (log.isLoggable(Level.FINE)) { t3 = System.currentTimeMillis(); } // Determine which custom tag needs to declare which scripting vars ScriptingVariabler.set(pageNodes, errDispatcher); // Optimizations by Tag Plugins TagPluginManager tagPluginManager = options.getTagPluginManager(); tagPluginManager.apply(pageNodes, errDispatcher, pageInfo); // Optimization: concatenate contiguous template texts. TextOptimizer.concatenate(this, pageNodes); // Generate static function mapper codes. ELFunctionMapper.map(this, pageNodes); // generate servlet .java file Generator.generate(writer, this, pageNodes); writer.close(); writer = null; // The writer is only used during the compile, dereference // it in the JspCompilationContext when done to allow it // to be GC'd and save memory. ctxt.setWriter(null); if (log.isLoggable(Level.FINE)) { t4 = System.currentTimeMillis(); log.fine( "Generated " + javaFileName + " total=" + (t4 - t1) + " generate=" + (t4 - t3) + " validate=" + (t2 - t1)); } } catch (Exception e) { if (writer != null) { try { writer.close(); writer = null; } catch (Exception e1) { // do nothing } } // Remove the generated .java file javaCompiler.doJavaFile(false); throw e; } finally { if (writer != null) { try { writer.close(); } catch (Exception e2) { // do nothing } } } // JSR45 Support if (!options.isSmapSuppressed()) { smapUtil.generateSmap(pageNodes); } // If any proto type .java and .class files was generated, // the prototype .java may have been replaced by the current // compilation (if the tag file is self referencing), but the // .class file need to be removed, to make sure that javac would // generate .class again from the new .java file just generated. tfp.removeProtoTypeFiles(ctxt.getClassFileName()); }
public void service(HttpServletRequest request, HttpServletResponse response, boolean precompile) throws ServletException, IOException, FileNotFoundException { try { if (ctxt.isRemoved()) { throw new FileNotFoundException(jspUri); } if ((available > 0L) && (available < Long.MAX_VALUE)) { response.setDateHeader("Retry-After", available); response.sendError( HttpServletResponse.SC_SERVICE_UNAVAILABLE, Localizer.getMessage("jsp.error.unavailable")); } if (options.getDevelopment() || firstTime) { synchronized (this) { ctxt.compile(); } } if (reload) { getServlet(); } // If a page is to only to be precompiled return. if (precompile) { return; } if (theServlet instanceof SingleThreadModel) { // sync on the wrapper so that the freshness // of the page is determined right before servicing synchronized (this) { theServlet.service(request, response); } } else { theServlet.service(request, response); } } catch (UnavailableException ex) { String includeRequestUri = (String) request.getAttribute("javax.servlet.include.request_uri"); if (includeRequestUri != null) { // This file was included. Throw an exception as // a response.sendError() will be ignored by the // servlet engine. throw ex; } else { int unavailableSeconds = ex.getUnavailableSeconds(); if (unavailableSeconds <= 0) { unavailableSeconds = 60; // Arbitrary default } available = System.currentTimeMillis() + (unavailableSeconds * 1000L); response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, ex.getMessage()); } } catch (FileNotFoundException ex) { String includeRequestUri = (String) request.getAttribute("javax.servlet.include.request_uri"); if (includeRequestUri != null) { // This file was included. Throw an exception as // a response.sendError() will be ignored by the // servlet engine. throw new ServletException(ex); } else { try { response.sendError(HttpServletResponse.SC_NOT_FOUND, ex.getMessage()); } catch (IllegalStateException ise) { log.error(Localizer.getMessage("jsp.error.file.not.found", ex.getMessage()), ex); } } } catch (ServletException ex) { throw ex; } catch (IOException ex) { throw ex; } catch (IllegalStateException ex) { throw ex; } catch (Exception ex) { throw new JasperException(ex); } }
/** * Compile the jsp file into equivalent servlet in .java file * * @return a smap for the current JSP page, if one is generated, null otherwise */ protected String[] generateJava() throws Exception { String[] smapStr = null; long t1, t2, t3, t4; t1 = t2 = t3 = t4 = 0; if (log.isDebugEnabled()) { t1 = System.currentTimeMillis(); } // Setup page info area pageInfo = new PageInfo(new BeanRepository(ctxt.getClassLoader(), errDispatcher), ctxt.getJspFile()); JspConfig jspConfig = options.getJspConfig(); JspConfig.JspProperty jspProperty = jspConfig.findJspProperty(ctxt.getJspFile()); /* * If the current uri is matched by a pattern specified in a * jsp-property-group in web.xml, initialize pageInfo with those * properties. */ if (jspProperty.isELIgnored() != null) { pageInfo.setELIgnored(JspUtil.booleanValue(jspProperty.isELIgnored())); } if (jspProperty.isScriptingInvalid() != null) { pageInfo.setScriptingInvalid(JspUtil.booleanValue(jspProperty.isScriptingInvalid())); } if (jspProperty.getIncludePrelude() != null) { pageInfo.setIncludePrelude(jspProperty.getIncludePrelude()); } if (jspProperty.getIncludeCoda() != null) { pageInfo.setIncludeCoda(jspProperty.getIncludeCoda()); } if (jspProperty.isDeferedSyntaxAllowedAsLiteral() != null) { pageInfo.setDeferredSyntaxAllowedAsLiteral( JspUtil.booleanValue(jspProperty.isDeferedSyntaxAllowedAsLiteral())); } if (jspProperty.isTrimDirectiveWhitespaces() != null) { pageInfo.setTrimDirectiveWhitespaces( JspUtil.booleanValue(jspProperty.isTrimDirectiveWhitespaces())); } // Default ContentType processing is deferred until after the page has // been parsed if (jspProperty.getBuffer() != null) { pageInfo.setBufferValue(jspProperty.getBuffer(), null, errDispatcher); } if (jspProperty.isErrorOnUndeclaredNamespace() != null) { pageInfo.setErrorOnUndeclaredNamespace( JspUtil.booleanValue(jspProperty.isErrorOnUndeclaredNamespace())); } if (ctxt.isTagFile()) { try { double libraryVersion = Double.parseDouble(ctxt.getTagInfo().getTagLibrary().getRequiredVersion()); if (libraryVersion < 2.0) { pageInfo.setIsELIgnored("true", null, errDispatcher, true); } if (libraryVersion < 2.1) { pageInfo.setDeferredSyntaxAllowedAsLiteral("true", null, errDispatcher, true); } } catch (NumberFormatException ex) { errDispatcher.jspError(ex); } } ctxt.checkOutputDir(); String javaFileName = ctxt.getServletJavaFileName(); ServletWriter writer = null; try { /* * The setting of isELIgnored changes the behaviour of the parser * in subtle ways. To add to the 'fun', isELIgnored can be set in * any file that forms part of the translation unit so setting it * in a file included towards the end of the translation unit can * change how the parser should have behaved when parsing content * up to the point where isELIgnored was set. Arghh! * Previous attempts to hack around this have only provided partial * solutions. We now use two passes to parse the translation unit. * The first just parses the directives and the second parses the * whole translation unit once we know how isELIgnored has been set. * TODO There are some possible optimisations of this process. */ // Parse the file ParserController parserCtl = new ParserController(ctxt, this); // Pass 1 - the directives Node.Nodes directives = parserCtl.parseDirectives(ctxt.getJspFile()); Validator.validateDirectives(this, directives); // Pass 2 - the whole translation unit pageNodes = parserCtl.parse(ctxt.getJspFile()); // Leave this until now since it can only be set once - bug 49726 if (pageInfo.getContentType() == null && jspProperty.getDefaultContentType() != null) { pageInfo.setContentType(jspProperty.getDefaultContentType()); } if (ctxt.isPrototypeMode()) { // generate prototype .java file for the tag file writer = setupContextWriter(javaFileName); Generator.generate(writer, this, pageNodes); writer.close(); writer = null; return null; } // Validate and process attributes - don't re-validate the // directives we validated in pass 1 Validator.validateExDirectives(this, pageNodes); if (log.isDebugEnabled()) { t2 = System.currentTimeMillis(); } // Collect page info Collector.collect(this, pageNodes); // Compile (if necessary) and load the tag files referenced in // this compilation unit. tfp = new TagFileProcessor(); tfp.loadTagFiles(this, pageNodes); if (log.isDebugEnabled()) { t3 = System.currentTimeMillis(); } // Determine which custom tag needs to declare which scripting vars ScriptingVariabler.set(pageNodes, errDispatcher); // Optimizations by Tag Plugins TagPluginManager tagPluginManager = options.getTagPluginManager(); tagPluginManager.apply(pageNodes, errDispatcher, pageInfo); // Optimization: concatenate contiguous template texts. TextOptimizer.concatenate(this, pageNodes); // Generate static function mapper codes. ELFunctionMapper.map(pageNodes); // generate servlet .java file writer = setupContextWriter(javaFileName); Generator.generate(writer, this, pageNodes); writer.close(); writer = null; // The writer is only used during the compile, dereference // it in the JspCompilationContext when done to allow it // to be GC'd and save memory. ctxt.setWriter(null); if (log.isDebugEnabled()) { t4 = System.currentTimeMillis(); log.debug( "Generated " + javaFileName + " total=" + (t4 - t1) + " generate=" + (t4 - t3) + " validate=" + (t2 - t1)); } } catch (Exception e) { if (writer != null) { try { writer.close(); writer = null; } catch (Exception e1) { // do nothing } } // Remove the generated .java file File file = new File(javaFileName); if (file.exists()) { if (!file.delete()) { log.warn( Localizer.getMessage( "jsp.warning.compiler.javafile.delete.fail", file.getAbsolutePath())); } } throw e; } finally { if (writer != null) { try { writer.close(); } catch (Exception e2) { // do nothing } } } // JSR45 Support if (!options.isSmapSuppressed()) { smapStr = SmapUtil.generateSmap(ctxt, pageNodes); } // If any proto type .java and .class files was generated, // the prototype .java may have been replaced by the current // compilation (if the tag file is self referencing), but the // .class file need to be removed, to make sure that javac would // generate .class again from the new .java file just generated. tfp.removeProtoTypeFiles(ctxt.getClassFileName()); return smapStr; }
/** Method used to initialize SecurityManager data. */ private void initSecurity() { // Setup the PermissionCollection for this web app context // based on the permissions configured for the root of the // web app context directory, then add a file read permission // for that directory. Policy policy = Policy.getPolicy(); if (policy != null) { try { // Get the permissions for the web app context String docBase = context.getRealPath("/"); if (docBase == null) { docBase = options.getScratchDir().toString(); } String codeBase = docBase; if (!codeBase.endsWith(File.separator)) { codeBase = codeBase + File.separator; } File contextDir = new File(codeBase); URL url = contextDir.getCanonicalFile().toURL(); codeSource = new CodeSource(url, (Certificate[]) null); permissionCollection = policy.getPermissions(codeSource); // Create a file read permission for web app context directory if (!docBase.endsWith(File.separator)) { permissionCollection.add(new FilePermission(docBase, "read")); docBase = docBase + File.separator; } else { permissionCollection.add( new FilePermission(docBase.substring(0, docBase.length() - 1), "read")); } docBase = docBase + "-"; permissionCollection.add(new FilePermission(docBase, "read")); // Spec says apps should have read/write for their temp // directory. This is fine, as no security sensitive files, at // least any that the app doesn't have full control of anyway, // will be written here. String workDir = options.getScratchDir().toString(); if (!workDir.endsWith(File.separator)) { permissionCollection.add(new FilePermission(workDir, "read,write")); workDir = workDir + File.separator; } workDir = workDir + "-"; permissionCollection.add(new FilePermission(workDir, "read,write,delete")); // Allow the JSP to access org.apache.jasper.runtime.HttpJspBase permissionCollection.add( new RuntimePermission("accessClassInPackage.org.apache.jasper.runtime")); if (parentClassLoader instanceof URLClassLoader) { URL[] urls = parentClassLoader.getURLs(); String jarUrl = null; String jndiUrl = null; for (int i = 0; i < urls.length; i++) { if (jndiUrl == null && urls[i].toString().startsWith("jndi:")) { jndiUrl = urls[i].toString() + "-"; } if (jarUrl == null && urls[i].toString().startsWith("jar:jndi:")) { jarUrl = urls[i].toString(); jarUrl = jarUrl.substring(0, jarUrl.length() - 2); jarUrl = jarUrl.substring(0, jarUrl.lastIndexOf('/')) + "/-"; } } if (jarUrl != null) { permissionCollection.add(new FilePermission(jarUrl, "read")); permissionCollection.add(new FilePermission(jarUrl.substring(4), "read")); } if (jndiUrl != null) permissionCollection.add(new FilePermission(jndiUrl, "read")); } } catch (Exception e) { context.log("Security Init for context failed", e); } } }