/**
   * 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);
        }
      }
    }
  }
Example #2
0
  /**
   * Adds servlet declaration and mapping for the JSP page servlet to the generated web.xml
   * fragment.
   *
   * @param file Context-relative path to the JSP file, e.g. <code>/index.jsp</code>
   * @param clctxt Compilation context of the servlet
   */
  public void generateWebMapping(String file, JspCompilationContext clctxt) throws IOException {
    if (log.isDebugEnabled()) {
      log.debug("Generating web mapping for file " + file + " using compilation context " + clctxt);
    }

    String className = clctxt.getServletClassName();
    String packageName = clctxt.getServletPackageName();

    String thisServletName;
    if ("".equals(packageName)) {
      thisServletName = className;
    } else {
      thisServletName = packageName + '.' + className;
    }

    if (servletout != null) {
      servletout.write("\n    <servlet>\n        <servlet-name>");
      servletout.write(thisServletName);
      servletout.write("</servlet-name>\n        <servlet-class>");
      servletout.write(thisServletName);
      servletout.write("</servlet-class>\n    </servlet>\n");
    }
    if (mappingout != null) {
      mappingout.write("\n    <servlet-mapping>\n        <servlet-name>");
      mappingout.write(thisServletName);
      mappingout.write("</servlet-name>\n        <url-pattern>");
      mappingout.write(file.replace('\\', '/'));
      mappingout.write("</url-pattern>\n    </servlet-mapping>\n");
    }
  }
Example #3
0
  /** 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;
  }
Example #4
0
  /*
   * @param uri The uri of the TLD @param ctxt The compilation context
   *
   * @return String array whose first element denotes the path to the TLD. If
   * the path to the TLD points to a jar file, then the second element denotes
   * the name of the TLD entry in the jar file, which is hardcoded to
   * META-INF/taglib.tld.
   */
  private String[] generateTLDLocation(String uri, JspCompilationContext ctxt)
      throws JasperException {

    int uriType = TldLocationsCache.uriType(uri);
    if (uriType == TldLocationsCache.ABS_URI) {
      err.jspError("jsp.error.taglibDirective.absUriCannotBeResolved", uri);
    } else if (uriType == TldLocationsCache.NOROOT_REL_URI) {
      uri = ctxt.resolveRelativeUri(uri);
    }

    String[] location = new String[2];
    location[0] = uri;
    if (location[0].endsWith("jar")) {
      URL url = null;
      try {
        url = ctxt.getResource(location[0]);
      } catch (Exception ex) {
        err.jspError("jsp.error.tld.unable_to_get_jar", location[0], ex.toString());
      }
      if (url == null) {
        err.jspError("jsp.error.tld.missing_jar", location[0]);
      }
      location[0] = url.toString();
      location[1] = "META-INF/taglib.tld";
    }

    return location;
  }
 /** Remove generated files */
 public void removeGeneratedFiles() {
   try {
     String classFileName = ctxt.getClassFileName();
     if (classFileName != null) {
       File classFile = new File(classFileName);
       if (log.isDebugEnabled()) log.debug("Deleting " + classFile);
       if (classFile.exists()) {
         if (!classFile.delete()) {
           log.warn(
               Localizer.getMessage(
                   "jsp.warning.compiler.classfile.delete.fail", classFile.getAbsolutePath()));
         }
       }
     }
   } catch (Exception e) {
     // Remove as much as possible, ignore possible exceptions
   }
   try {
     String javaFileName = ctxt.getServletJavaFileName();
     if (javaFileName != null) {
       File javaFile = new File(javaFileName);
       if (log.isDebugEnabled()) log.debug("Deleting " + javaFile);
       if (javaFile.exists()) {
         if (!javaFile.delete()) {
           log.warn(
               Localizer.getMessage(
                   "jsp.warning.compiler.javafile.delete.fail", javaFile.getAbsolutePath()));
         }
       }
     }
   } catch (Exception e) {
     // Remove as much as possible, ignore possible exceptions
   }
 }
Example #6
0
  /**
   * Compile and load a prototype for the Tag file. This is needed when compiling tag files with
   * circular dependencies. A prototype (skeleton) with no dependencies on other other tag files is
   * generated and compiled.
   */
  public Class<?> loadTagFilePrototype() throws JasperException {

    ctxt.setPrototypeMode(true);
    try {
      return loadTagFile();
    } finally {
      ctxt.setPrototypeMode(false);
    }
  }
 protected JspCompilationContext createJspCompilationContext(
     String name,
     boolean isErrPage,
     Options opt,
     ServletContext sctx,
     JspRuntimeContext jrctx,
     ClassLoader cl) {
   JspCompilationContext jcctx = new JspCompilationContext(name, opt, sctx, null, jrctx);
   jcctx.setClassLoader(cl);
   return jcctx;
 }
Example #8
0
 // XXX FIXME
 // resolveRelativeUri and/or getResourceAsStream don't seem to properly
 // handle relative paths when dealing when home and getDocBase are set
 // the following is a workaround until these problems are resolved.
 private InputStream getResourceAsStream(String uri) throws FileNotFoundException {
   try {
     // see if file exists on the filesystem first
     String real = ctxt.getRealPath(uri);
     if (real == null) {
       return ctxt.getResourceAsStream(uri);
     } else {
       return new FileInputStream(real);
     }
   } catch (FileNotFoundException ex) {
     // if file not found on filesystem, get the resource through
     // the context
     return ctxt.getResourceAsStream(uri);
   }
 }
  public Servlet getServlet() throws ServletException, IOException, FileNotFoundException {
    if (reload) {
      synchronized (this) {
        // Synchronizing on jsw enables simultaneous loading
        // of different pages, but not the same page.
        if (reload) {
          // This is to maintain the original protocol.
          destroy();

          try {
            servletClass = ctxt.load();
            theServlet = (Servlet) servletClass.newInstance();
          } catch (IllegalAccessException ex1) {
            throw new JasperException(ex1);
          } catch (InstantiationException ex) {
            throw new JasperException(ex);
          }

          theServlet.init(config);
          firstTime = false;
          reload = false;
        }
      }
    }
    return theServlet;
  }
  /**
   * Compile the jsp file from the current engine context. As an side- effect, tag files that are
   * referenced by this page are also compiled.
   *
   * @param compileClass If true, generate both .java and .class file If false, generate only .java
   *     file
   * @param jspcMode true if invoked from JspC, false otherwise
   */
  public void compile(boolean compileClass, boolean jspcMode)
      throws FileNotFoundException, JasperException, Exception {
    if (errDispatcher == null) {
      this.errDispatcher = new ErrorDispatcher(jspcMode);
    }

    try {
      String[] smap = generateJava();
      if (compileClass) {
        generateClass(smap);
        // Fix for bugzilla 41606
        // Set JspServletWrapper.servletClassLastModifiedTime after successful compile
        String targetFileName = ctxt.getClassFileName();
        if (targetFileName != null) {
          File targetFile = new File(targetFileName);
          if (targetFile.exists() && jsw != null) {
            jsw.setServletClassLastModifiedTime(targetFile.lastModified());
          }
        }
      }
    } finally {
      if (tfp != null && ctxt.isPrototypeMode()) {
        tfp.removeProtoTypeFiles(null);
      }
      // Make sure these object which are only used during the
      // generation and compilation of the JSP page get
      // dereferenced so that they can be GC'd and reduce the
      // memory footprint.
      tfp = null;
      errDispatcher = null;
      pageInfo = null;

      // Only get rid of the pageNodes if in production.
      // In development mode, they are used for detailed
      // error messages.
      // http://issues.apache.org/bugzilla/show_bug.cgi?id=37062
      if (!this.options.getDevelopment()) {
        pageNodes = null;
      }

      if (ctxt.getWriter() != null) {
        ctxt.getWriter().close();
        ctxt.setWriter(null);
      }
    }
  }
  private ServletWriter setupContextWriter(String javaFileName)
      throws FileNotFoundException, JasperException {
    ServletWriter writer;
    // Setup the ServletWriter
    String javaEncoding = ctxt.getOptions().getJavaEncoding();
    OutputStreamWriter osw = null;

    try {
      osw = new OutputStreamWriter(new FileOutputStream(javaFileName), javaEncoding);
    } catch (UnsupportedEncodingException ex) {
      errDispatcher.jspError("jsp.error.needAlternateJavaEncoding", javaEncoding);
    }

    writer = new ServletWriter(new PrintWriter(osw));
    ctxt.setWriter(writer);
    return writer;
  }
Example #12
0
 // Compiler for parsing only, needed by netbeans
 public Compiler(JspCompilationContext ctxt, JspServletWrapper jsw) {
   this.jsw = jsw;
   this.ctxt = ctxt;
   this.jspcMode = false;
   this.options = ctxt.getOptions();
   this.log = Logger.getLogger(Compiler.class.getName());
   this.smapUtil = new SmapUtil(ctxt);
   this.errDispatcher = new ErrorDispatcher(jspcMode);
   this.javaCompiler = new NullJavaCompiler();
   javaCompiler.init(ctxt, errDispatcher, jspcMode);
 }
Example #13
0
 public void removeGeneratedClassFiles() {
   try {
     String classFileName = ctxt.getClassFileName();
     if (classFileName != null) {
       File classFile = new File(classFileName);
       if (log.isLoggable(Level.FINE)) log.fine("Deleting " + classFile);
       classFile.delete();
     }
   } catch (Exception e) {
     // Remove as much as possible, ignore possible exceptions
   }
 }
Example #14
0
  public Servlet getServlet() throws ServletException {
    // DCL on 'reload' requires that 'reload' be volatile
    // (this also forces a read memory barrier, ensuring the
    // new servlet object is read consistently)
    if (reload) {
      synchronized (this) {
        // Synchronizing on jsw enables simultaneous loading
        // of different pages, but not the same page.
        if (reload) {
          // This is to maintain the original protocol.
          destroy();

          final Servlet servlet;

          try {
            InstanceManager instanceManager = InstanceManagerFactory.getInstanceManager(config);
            servlet = (Servlet) instanceManager.newInstance(ctxt.getFQCN(), ctxt.getJspLoader());
          } catch (IllegalAccessException e) {
            throw new JasperException(e);
          } catch (InstantiationException e) {
            throw new JasperException(e);
          } catch (Exception e) {
            throw new JasperException(e);
          }

          servlet.init(config);

          if (!firstTime) {
            ctxt.getRuntimeContext().incrementJspReloadCount();
          }

          theServlet = servlet;
          reload = false;
          // Volatile 'reload' forces in order write of 'theServlet' and new servlet object
        }
      }
    }
    return theServlet;
  }
Example #15
0
 public Compiler(JspCompilationContext ctxt, JspServletWrapper jsw, boolean jspcMode)
     throws JasperException {
   this.jsw = jsw;
   this.ctxt = ctxt;
   this.jspcMode = jspcMode;
   this.options = ctxt.getOptions();
   this.log = Logger.getLogger(Compiler.class.getName());
   if (jspcMode) {
     log.setLevel(Level.OFF);
   }
   this.smapUtil = new SmapUtil(ctxt);
   this.errDispatcher = new ErrorDispatcher(jspcMode);
   initJavaCompiler();
 }
 /** Get a list of files that the current page has source dependency on. */
 public java.util.List getDependants() {
   try {
     Object target;
     if (isTagFile) {
       if (reload) {
         tagHandlerClass = ctxt.load();
       }
       target = tagHandlerClass.newInstance();
     } else {
       target = getServlet();
     }
     if (target != null && target instanceof JspSourceDependent) {
       return ((JspSourceDependent) target).getDependants();
     }
   } catch (Throwable ex) {
   }
   return null;
 }
Example #17
0
  /*
   * Parses the tag file directives of the given TagFile and turns them into a
   * TagInfo.
   *
   * @param elem The <tag-file> element in the TLD @param uri The location of
   * the TLD, in case the tag file is specified relative to it @param jarFile
   * The JAR file, in case the tag file is packaged in a JAR
   *
   * @return TagInfo correspoding to tag file directives
   */
  private TagFileInfo createTagFileInfo(TreeNode elem, String uri, URL jarFileUrl)
      throws JasperException {

    String name = null;
    String path = null;

    Iterator list = elem.findChildren();
    while (list.hasNext()) {
      TreeNode child = (TreeNode) list.next();
      String tname = child.getName();
      if ("name".equals(tname)) {
        name = child.getBody();
      } else if ("path".equals(tname)) {
        path = child.getBody();
      } else if ("example".equals(tname)) {
        // Ignore <example> element: Bugzilla 33538
      } else if ("tag-extension".equals(tname)) {
        // Ignore <tag-extension> element: Bugzilla 33538
      } else if ("icon".equals(tname)
          || "display-name".equals(tname)
          || "description".equals(tname)) {
        // Ignore these elements: Bugzilla 38015
      } else {
        if (log.isWarnEnabled()) {
          log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.tagfile", tname));
        }
      }
    }

    if (path.startsWith("/META-INF/tags")) {
      // Tag file packaged in JAR
      // See https://issues.apache.org/bugzilla/show_bug.cgi?id=46471
      // This needs to be removed once all the broken code that depends on
      // it has been removed
      ctxt.setTagFileJarUrl(path, jarFileUrl);
    } else if (!path.startsWith("/WEB-INF/tags")) {
      err.jspError("jsp.error.tagfile.illegalPath", path);
    }

    TagInfo tagInfo =
        TagFileProcessor.parseTagFileDirectives(parserController, name, path, jarFileUrl, this);
    return new TagFileInfo(name, path, tagInfo);
  }
Example #18
0
  private TagLibraryValidator createValidator(TreeNode elem) throws JasperException {

    String validatorClass = null;
    Map initParams = new Hashtable();

    Iterator list = elem.findChildren();
    while (list.hasNext()) {
      TreeNode element = (TreeNode) list.next();
      String tname = element.getName();
      if ("validator-class".equals(tname)) validatorClass = element.getBody();
      else if ("init-param".equals(tname)) {
        String[] initParam = createInitParam(element);
        initParams.put(initParam[0], initParam[1]);
      } else if ("description".equals(tname)
          || // Ignored elements
          false) {
      } else {
        if (log.isWarnEnabled()) {
          log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.validator", tname));
        }
      }
    }

    TagLibraryValidator tlv = null;
    if (validatorClass != null && !validatorClass.equals("")) {
      try {
        Class tlvClass = ctxt.getClassLoader().loadClass(validatorClass);
        tlv = (TagLibraryValidator) tlvClass.newInstance();
      } catch (Exception e) {
        err.jspError("jsp.error.tlvclass.instantiation", validatorClass, e);
      }
    }
    if (tlv != null) {
      tlv.setInitParameters(initParams);
    }
    return tlv;
  }
Example #19
0
 /** Get a list of files that the current page has source dependency on. */
 public java.util.Map<String, Long> getDependants() {
   try {
     Object target;
     if (isTagFile) {
       if (reload) {
         tagHandlerClass = ctxt.load();
         reload = false;
       }
       target = tagHandlerClass.newInstance();
     } else {
       target = getServlet();
     }
     if (target != null && target instanceof JspSourceDependent) {
       return ((JspSourceDependent) target).getDependants();
     }
   } catch (AbstractMethodError ame) {
     // Almost certainly a pre Tomcat 7.0.17 compiled JSP using the old
     // version of the interface. Force a re-compile.
     return ALWAYS_OUTDATED_DEPENDENCIES;
   } catch (Throwable ex) {
     ExceptionUtils.handleThrowable(ex);
   }
   return null;
 }
Example #20
0
  /** Return true if the path refers to a jar file in WEB-INF and is a system jar. */
  private boolean systemJarInWebinf(String path) {

    if (path.indexOf("/WEB-INF/") < 0) {
      return false;
    }

    Boolean useMyFaces =
        (Boolean) ctxt.getServletContext().getAttribute("com.sun.faces.useMyFaces");

    if (useMyFaces == null || !useMyFaces) {
      for (String jar : systemJsfJars) {
        if (path.indexOf(jar) > 0) {
          return true;
        }
      }
    }

    for (String jar : systemJars) {
      if (path.indexOf(jar) > 0) {
        return true;
      }
    }
    return false;
  }
Example #21
0
  /**
   * Compile the jsp file from the current engine context. As an side- effect, tag files that are
   * referenced by this page are also compiled.
   *
   * @param compileClass If true, generate both .java and .class file If false, generate only .java
   *     file
   */
  public void compile(boolean compileClass)
      throws FileNotFoundException, JasperException, Exception {

    try {
      // Create the output directory for the generated files
      // Always try and create the directory tree, in case the generated
      // directories were deleted after the server was started.
      ctxt.makeOutputDir(ctxt.getOutputDir());

      // If errDispatcher is nulled from a previous compilation of the
      // same page, instantiate one here.
      if (errDispatcher == null) {
        errDispatcher = new ErrorDispatcher(jspcMode);
      }
      generateJava();
      if (compileClass) {
        generateClass();
      } else {
        // If called from jspc to only compile to .java files,
        // make sure that .java files are written to disk.
        javaCompiler.doJavaFile(ctxt.keepGenerated());
      }
    } finally {
      if (tfp != null) {
        tfp.removeProtoTypeFiles(null);
      }
      // Make sure these object which are only used during the
      // generation and compilation of the JSP page get
      // dereferenced so that they can be GC'd and reduce the
      // memory footprint.
      tfp = null;
      errDispatcher = null;
      if (!jspcMode) {
        pageInfo = null;
      }
      pageNodes = null;
      if (ctxt.getWriter() != null) {
        ctxt.getWriter().close();
        ctxt.setWriter(null);
      }
    }
  }
Example #22
0
  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);
    }
  }
  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);
    }
  }
Example #24
0
 public ServletContext getServletContext() {
   return ctxt.getServletContext();
 }
Example #25
0
  /** Constructor. */
  public TagLibraryInfoImpl(
      JspCompilationContext ctxt,
      ParserController pc,
      PageInfo pi,
      String prefix,
      String uriIn,
      String[] location,
      ErrorDispatcher err)
      throws JasperException {
    super(prefix, uriIn);

    this.ctxt = ctxt;
    this.parserController = pc;
    this.pi = pi;
    this.err = err;
    InputStream in = null;
    JarFile jarFile = null;

    if (location == null) {
      // The URI points to the TLD itself or to a JAR file in which the
      // TLD is stored
      location = generateTLDLocation(uri, ctxt);
    }

    try {
      if (!location[0].endsWith("jar")) {
        // Location points to TLD file
        try {
          in = getResourceAsStream(location[0]);
          if (in == null) {
            throw new FileNotFoundException(location[0]);
          }
        } catch (FileNotFoundException ex) {
          err.jspError("jsp.error.file.not.found", location[0]);
        }

        parseTLD(ctxt, location[0], in, null);
        // Add TLD to dependency list
        PageInfo pageInfo = ctxt.createCompiler().getPageInfo();
        if (pageInfo != null) {
          pageInfo.addDependant(location[0]);
        }
      } else {
        // Tag library is packaged in JAR file
        try {
          URL jarFileUrl = new URL("jar:" + location[0] + "!/");
          JarURLConnection conn = (JarURLConnection) jarFileUrl.openConnection();
          conn.setUseCaches(false);
          conn.connect();
          jarFile = conn.getJarFile();
          ZipEntry jarEntry = jarFile.getEntry(location[1]);
          in = jarFile.getInputStream(jarEntry);
          parseTLD(ctxt, location[0], in, jarFileUrl);
        } catch (Exception ex) {
          err.jspError("jsp.error.tld.unable_to_read", location[0], location[1], ex.toString());
        }
      }
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (Throwable t) {
        }
      }
      if (jarFile != null) {
        try {
          jarFile.close();
        } catch (Throwable t) {
        }
      }
    }
  }
Example #26
0
  private TagInfo createTagInfo(TreeNode elem, String jspVersion) throws JasperException {

    String tagName = null;
    String tagClassName = null;
    String teiClassName = null;

    /*
     * Default body content for JSP 1.2 tag handlers (<body-content> has
     * become mandatory in JSP 2.0, because the default would be invalid for
     * simple tag handlers)
     */
    String bodycontent = "JSP";

    String info = null;
    String displayName = null;
    String smallIcon = null;
    String largeIcon = null;
    boolean dynamicAttributes = false;

    Vector attributeVector = new Vector();
    Vector variableVector = new Vector();
    Iterator list = elem.findChildren();
    while (list.hasNext()) {
      TreeNode element = (TreeNode) list.next();
      String tname = element.getName();

      if ("name".equals(tname)) {
        tagName = element.getBody();
      } else if ("tagclass".equals(tname) || "tag-class".equals(tname)) {
        tagClassName = element.getBody();
      } else if ("teiclass".equals(tname) || "tei-class".equals(tname)) {
        teiClassName = element.getBody();
      } else if ("bodycontent".equals(tname) || "body-content".equals(tname)) {
        bodycontent = element.getBody();
      } else if ("display-name".equals(tname)) {
        displayName = element.getBody();
      } else if ("small-icon".equals(tname)) {
        smallIcon = element.getBody();
      } else if ("large-icon".equals(tname)) {
        largeIcon = element.getBody();
      } else if ("icon".equals(tname)) {
        TreeNode icon = element.findChild("small-icon");
        if (icon != null) {
          smallIcon = icon.getBody();
        }
        icon = element.findChild("large-icon");
        if (icon != null) {
          largeIcon = icon.getBody();
        }
      } else if ("info".equals(tname) || "description".equals(tname)) {
        info = element.getBody();
      } else if ("variable".equals(tname)) {
        variableVector.addElement(createVariable(element));
      } else if ("attribute".equals(tname)) {
        attributeVector.addElement(createAttribute(element, jspVersion));
      } else if ("dynamic-attributes".equals(tname)) {
        dynamicAttributes = JspUtil.booleanValue(element.getBody());
      } else if ("example".equals(tname)) {
        // Ignored elements
      } else if ("tag-extension".equals(tname)) {
        // Ignored
      } else {
        if (log.isWarnEnabled()) {
          log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.tag", tname));
        }
      }
    }

    TagExtraInfo tei = null;
    if (teiClassName != null && !teiClassName.equals("")) {
      try {
        Class teiClass = ctxt.getClassLoader().loadClass(teiClassName);
        tei = (TagExtraInfo) teiClass.newInstance();
      } catch (Exception e) {
        err.jspError("jsp.error.teiclass.instantiation", teiClassName, e);
      }
    }

    TagAttributeInfo[] tagAttributeInfo = new TagAttributeInfo[attributeVector.size()];
    attributeVector.copyInto(tagAttributeInfo);

    TagVariableInfo[] tagVariableInfos = new TagVariableInfo[variableVector.size()];
    variableVector.copyInto(tagVariableInfos);

    TagInfo taginfo =
        new TagInfo(
            tagName,
            tagClassName,
            bodycontent,
            info,
            this,
            tei,
            tagAttributeInfo,
            displayName,
            smallIcon,
            largeIcon,
            tagVariableInfos,
            dynamicAttributes);
    return taginfo;
  }
Example #27
0
  protected void processFile(String file) throws JasperException {
    if (log.isDebugEnabled()) {
      log.debug("Processing file: " + file);
    }

    ClassLoader originalClassLoader = null;

    try {
      // set up a scratch/output dir if none is provided
      if (scratchDir == null) {
        String temp = System.getProperty("java.io.tmpdir");
        if (temp == null) {
          temp = "";
        }
        scratchDir = new File(new File(temp).getAbsolutePath());
      }

      String jspUri = file.replace('\\', '/');
      JspCompilationContext clctxt = new JspCompilationContext(jspUri, this, context, null, rctxt);

      /* Override the defaults */
      if ((targetClassName != null) && (targetClassName.length() > 0)) {
        clctxt.setServletClassName(targetClassName);
        targetClassName = null;
      }
      if (targetPackage != null) {
        clctxt.setServletPackageName(targetPackage);
      }

      originalClassLoader = Thread.currentThread().getContextClassLoader();
      Thread.currentThread().setContextClassLoader(loader);

      clctxt.setClassLoader(loader);
      clctxt.setClassPath(classPath);

      Compiler clc = clctxt.createCompiler();

      // If compile is set, generate both .java and .class, if
      // .jsp file is newer than .class file;
      // Otherwise only generate .java, if .jsp file is newer than
      // the .java file
      if (clc.isOutDated(compile)) {
        if (log.isDebugEnabled()) {
          log.debug(jspUri + " is out dated, compiling...");
        }

        clc.compile(compile, true);
      }

      // Generate mapping
      generateWebMapping(file, clctxt);
      if (showSuccess) {
        log.info("Built File: " + file);
      }

    } catch (JasperException je) {
      Throwable rootCause = je;
      while (rootCause instanceof JasperException
          && ((JasperException) rootCause).getRootCause() != null) {
        rootCause = ((JasperException) rootCause).getRootCause();
      }
      if (rootCause != je) {
        log.error(Localizer.getMessage("jspc.error.generalException", file), rootCause);
      }

      // Bugzilla 35114.
      if (getFailOnError()) {
        throw je;
      } else {
        log.error(je.getMessage());
      }

    } catch (Exception e) {
      if ((e instanceof FileNotFoundException) && log.isWarnEnabled()) {
        log.warn(Localizer.getMessage("jspc.error.fileDoesNotExist", e.getMessage()));
      }
      throw new JasperException(e);
    } finally {
      if (originalClassLoader != null) {
        Thread.currentThread().setContextClassLoader(originalClassLoader);
      }
    }
  }
Example #28
0
  /**
   * Determine if a compilation is necessary by checking the time stamp of the JSP page with that of
   * the corresponding .class or .java file. If the page has dependencies, the check is also
   * extended to its dependeants, and so on. This method can by overidden by a subclasses of
   * Compiler.
   *
   * @param checkClass If true, check against .class file, if false, check against .java file.
   */
  public boolean isOutDated(boolean checkClass) {

    String jsp = ctxt.getJspFile();

    if (jsw != null && (ctxt.getOptions().getModificationTestInterval() > 0)) {

      if (jsw.getLastModificationTest() + (ctxt.getOptions().getModificationTestInterval() * 1000)
          > System.currentTimeMillis()) {
        return false;
      } else {
        jsw.setLastModificationTest(System.currentTimeMillis());
      }
    }

    long jspRealLastModified = 0;
    // START PWC 6468930
    File targetFile;

    if (checkClass) {
      targetFile = new File(ctxt.getClassFileName());
    } else {
      targetFile = new File(ctxt.getServletJavaFileName());
    }

    // Get the target file's last modified time. File.lastModified()
    // returns 0 if the file does not exist.
    long targetLastModified = targetFile.lastModified();

    // Check cached class file
    if (checkClass) {
      JspRuntimeContext rtctxt = ctxt.getRuntimeContext();
      String className = ctxt.getFullClassName();
      long cachedTime = rtctxt.getBytecodeBirthTime(className);
      if (cachedTime > targetLastModified) {
        targetLastModified = cachedTime;
      } else {
        // Remove from cache, since the bytecodes from the file is more
        // current, so that JasperLoader won't load the cached version
        rtctxt.setBytecode(className, null);
      }
    }

    if (targetLastModified == 0L) return true;

    // Check if the jsp exists in the filesystem (instead of a jar
    // or a remote location). If yes, then do a File.lastModified()
    // to determine its last modified time. This is more performant
    // (fewer stat calls) than the ctxt.getResource() followed by
    // openConnection(). However, it only works for file system jsps.
    // If the file has indeed changed, then need to call URL.OpenConnection()
    // so that the cache loads the latest jsp file
    if (jsw != null) {
      File jspFile = jsw.getJspFile();
      if (jspFile != null) {
        jspRealLastModified = jspFile.lastModified();
      }
    }
    if (jspRealLastModified == 0 || targetLastModified < jspRealLastModified) {
      // END PWC 6468930
      try {
        URL jspUrl = ctxt.getResource(jsp);
        if (jspUrl == null) {
          ctxt.incrementRemoved();
          return false;
        }
        URLConnection uc = jspUrl.openConnection();
        jspRealLastModified = uc.getLastModified();
        uc.getInputStream().close();
      } catch (Exception e) {
        e.printStackTrace();
        return true;
      }
      // START PWC 6468930
    }
    // END PWC 6468930
    /* PWC 6468930
    long targetLastModified = 0;
    File targetFile;

    if( checkClass ) {
        targetFile = new File(ctxt.getClassFileName());
    } else {
        targetFile = new File(ctxt.getServletJavaFileName());
    }

    if (!targetFile.exists()) {
        return true;
    }

    targetLastModified = targetFile.lastModified();
    */
    if (checkClass && jsw != null) {
      jsw.setServletClassLastModifiedTime(targetLastModified);
    }

    if (targetLastModified < jspRealLastModified) {
      // Remember JSP mod time
      jspModTime = jspRealLastModified;
      if (log.isLoggable(Level.FINE)) {
        log.fine("Compiler: outdated: " + targetFile + " " + targetLastModified);
      }
      return true;
    }

    // determine if source dependent files (e.g. includes using include
    // directives) have been changed.
    if (jsw == null) {
      return false;
    }

    List depends = jsw.getDependants();
    if (depends == null) {
      return false;
    }

    Iterator it = depends.iterator();
    while (it.hasNext()) {
      String include = (String) it.next();
      try {
        URL includeUrl = ctxt.getResource(include);
        if (includeUrl == null) {
          return true;
        }

        URLConnection includeUconn = includeUrl.openConnection();
        long includeLastModified = includeUconn.getLastModified();
        includeUconn.getInputStream().close();

        if (includeLastModified > targetLastModified) {
          // START GlassFish 750
          if (include.endsWith(".tld")) {
            ctxt.clearTaglibs();
            ctxt.clearTagFileJarUrls();
          }
          // END GlassFish 750
          return true;
        }
      } catch (Exception e) {
        e.printStackTrace();
        return true;
      }
    }

    return false;
  }
Example #29
0
  /** 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);
  }
Example #30
0
  /** 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());
  }