tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Petr Jiricka <petr.jiri...@netbeans.com>
Subject RE: [PATCH] Jasper compiler errors now show JSP line numbers
Date Wed, 19 Jul 2000 18:11:20 GMT
Hi,

I apologize I didn't have time to study the proposed code in detail, but my
opinion is that it should be configurable whether servlet or JSP line
numbers are reported. Even better would probably be extending the
appropriate exception classes so that both the servlet and the JSP positions
are present.

Speaking of exception classes, it would probably be useful to make
org.apache.jasper.compiler.CompileException extend
org.apache.jasper.compiler.ParseException.

Petr

> -----Original Message-----
> From: Alex Chaffee [mailto:guru@edamame.stinky.com]
> Sent: Wednesday, July 19, 2000 1:44 AM
> To: tomcat-dev@jakarta.apache.org
> Cc: jhunter@collab.net
> Subject: [PATCH] Jasper compiler errors now show JSP line numbers
> 
> 
> I've implemented an addition to Jasper's Compiler class that, 
> when it gets 
> a compiler error in an intermediate .java file, shows the 
> line number from 
> the original JSP file.  (I did this following an argument 
> with Jason Hunter 
> where I had to admit that JSP does indeed suck for debugging, 
> due partly to 
> the dissociation between JSP-source and Java-source).
> 
> I'm reluctant to check it in until someone else tests it for 
> robustness -- 
> and/or implements regular expressions and code for -- 
> compilers other than 
> the standard JDK 1.2 javac. Any volunteers?
> 
> It uses jakarta regexp, so check that out and put it in your 
> classpath. On 
> my system, I've modified some build files to (a) make the 
> regexp package 
> build regexp.jar into the dist directory, and (b) copy that 
> into the Tomcat 
> lib directory.  You may have to do some tweaking to make sure 
> it's in the 
> right place at the right time, until I (again) am convinced 
> it's robust 
> enough to check in.
> 
> Sample output:
> Error: 500
> Location:/purple/bad.jsp
> Internal Servlet Error:
> org.apache.jasper.JasperException: Unable to compile class for JSP
> Compile error: Class foo not found.
> Source file: /bad.jsp:3
> Intermediate file: 
> D:\jakarta-tomcat\work\localhost_8080%2Fpurple\_0002fbad_0002e
> jspbad_jsp_0.java:82
>                   foo
>                   ^
> Compile error: Invalid declaration.
> Source file: /bad.jsp:3
> Intermediate file: 
> D:\jakarta-tomcat\work\localhost_8080%2Fpurple\_0002fbad_0002e
> jspbad_jsp_0.java:85
>                  out.write("\r\n");
>                           ^
> 
>          at 
> org.apache.jasper.compiler.Compiler.compile(Compiler.java:251)
>          at 
> org.apache.jasper.servlet.JspServlet.doLoadJSP(JspServlet.java:442)
> ....
> 
>   - Alex
> 
> 
> ------
> 
> jakarta-tomcat/src/share/org/apache/jasper/compiler/ErrorFinder.java:
> 
> package org.apache.jasper.compiler;
> 
> import java.io.*;
> import org.apache.jasper.*;
> import org.apache.regexp.*;
> import org.apache.tomcat.logging.*;
> 
> /**
>   * Tries to backtrack a compile error to the original JSP file
>   *
>   * @author Alex Chaffee (alex@jguru.com)
>   **/
> 
> public class ErrorFinder extends Logger.Helper {
> 
>      RE reCompiler;
>      RE reBegin;
>      RE reEnd;
>      RE reWindows;
>      RE reMac;
> 
>      public static String newline = 
> System.getProperty("line.separator", "\n");
> 
>      public ErrorFinder() {
>          super("JASPER_LOG");
> 
>          try {
>              reCompiler = new RE(":(\\d+): (.*)\\n(.*?)\\n(\\s*\\^)");
>              reBegin = new RE("^\\s*// begin 
> \\[file=\"(.*)\";from=\\((\\d+),(\\d+)\\);to=\\((\\d+),(\\d+)\\)\\]");
>              reEnd = new RE("^\\s*// end");
> 
>              reWindows = new RE("\r\n");
>              reMac = new RE("\r");
> 
>          }
>          catch (RESyntaxException res) {
>              log("Initializing", res);
>          }
>      }
> 
>      /**
>       * @param ctx pointers to the various files
>       * @param msg message from the compiler
>       * @return string describing original error location, or null
>       **/
>      public String findError(JspCompilationContext ctx,
>                                     String msg)
>      {
>          StringBuffer error = new StringBuffer();
>          boolean hasError = false;
>          msg = reWindows.subst(msg, "\n", RE.REPLACE_ALL);
>          msg = reMac.subst(msg, "\n", RE.REPLACE_ALL);
>          try {
>              // for each error line in the msg
>              int i=0;
>              boolean match;
>              do {
>                  match = reCompiler.match(msg, i);
>                  if (match) {
>                      String lineStr = reCompiler.getParen(1);
>                      String errStr = reCompiler.getParen(2);
>                      String codeStr = reCompiler.getParen(3) 
> + newline +
>                          reCompiler.getParen(4);
>                      i = reCompiler.getParenEnd(0);
>                      System.err.println("lineStr="+lineStr+
>                                         "\t errStr="+errStr+
>                                         "\t i=" + i +
>                                         "\n" + codeStr );
> 
>                      // found an error match, now go to 
> compiled source
>                      String javaSource = ctx.getServletJavaFileName();
>                      BufferedReader in = new BufferedReader
>                          (new FileReader(javaSource));
>                      int lineTarget = Integer.parseInt(lineStr);
>                      int lineCurrent = 0;
>                      String line;
>                      String file = null,
>                          fromLine = null, toLine = null,
>                          fromChar = null, toChar = null;
>                      while ((line = in.readLine())!=null) {
>                          lineCurrent++;
>                          if (lineCurrent == lineTarget) {
>                              // found the Java source line
>                              if (file == null) {
>                                  // never got a begin, so abort
>                                  log("Never got a begin", 
> Logger.DEBUG);
>                                  break;  // stop reading file
>                              }
>                              else {
>                                  // got the line of the JSP, 
> now go parse 
> the JSP
>                                  String jspSource = ctx.getJspFile();
> 
>                                  // TODO: get the line referred to (if
>                                  // it's only one line) -- if it spans
>                                  // multiple lines, do we want to show
>                                  // them all?
> 
>                                  /*
>                                    String jspFile = 
> ctx.getRequest().getRealPath(jspFile);
>                                    String lineJsp = getLine(jspFile, 
> Integer.parseInt(lineFrom), Integer.parseInt(toLine));
>                                  */
> 
>                                  // we finally have it, make 
> an output message
>                                  String desc =
>                                      "Compile error: " + 
> errStr + newline +
>                                      "Source file: " + 
> jspSource + ":" + 
> fromLine +
>                                      (fromLine.equals(toLine) 
> ? "" : ("-" + 
> toLine)) +
>                                      newline +
>                                      // insert JSP source lines here
>                                      "Intermediate file: " + 
> javaSource + 
> ":" + lineStr + newline +
>                                      codeStr + newline;
> 
>                                  System.err.println(desc);
> 
>                                  error.append(desc);
>                                  hasError = true;
>                                  break; // stop reading file
>                              }
>                          }
>                          if (reBegin.match(line)) {
>                              file = reBegin.getParen(1);
>                              fromLine = reBegin.getParen(2);
>                              fromChar = 
> reBegin.getParen(3);
>                              toLine = reBegin.getParen(4);
>                              toChar = reBegin.getParen(5);
>                          }
>                          /*
>                          else if (reEnd.match(line)) {
>                          }
>                          */
>                      } // read file
>                      in.close();
>                  } // if match (error line number)
>              }
>              while (match);
>          }
>          catch (Throwable t) {
>              log("Trying to backtrack error from " + msg, t, 
> Logger.DEBUG);
>          }
>          if (hasError)
>              return error.toString();
>          else
>              return null;
>      }
> }
> 
> 
> 
> 
> Index: Compiler.java
> ===================================================================
> RCS file: 
> /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/
> Compiler.java,v
> retrieving revision 1.19
> diff -u -r1.19 Compiler.java
> --- Compiler.java       2000/06/27 20:59:40     1.19
> +++ Compiler.java       2000/07/19 11:35:04
> @@ -237,17 +237,30 @@
>            */
>           boolean status = javac.compile(javaFileName);
> 
> -        if (!ctxt.keepGenerated()) {
> -            File javaFile = new File(javaFileName);
> -            javaFile.delete();
> -        }
> -
> -        if (status == false) {
> -            String msg = out.toString ();
> -            throw new 
> JasperException(Constants.getString("jsp.error.unable.compile")
> -                                      + msg);
> -        }
> -
> +       try {
> +           if (status == false) {
> +               String msg = out.toString ();
> +               ErrorFinder finder = new ErrorFinder();
> +               String lineerror = finder.findError(ctxt, msg);
> +               if (lineerror == null) {
> +                   throw new 
> JasperException(Constants.getString("jsp.error.unable.compile")
> +                                             + msg);
> +               }
> +               else {
> +                   throw new 
> JasperException(Constants.getString("jsp.error.unable.compile")
> +                                             + ErrorFinder.newline
> +                                             + lineerror );
> +               }
> +
> +           }
> +       } // try error
> +       finally {       // always kill file if necessary
> +           if (!ctxt.keepGenerated()) {
> +               File javaFile = new File(javaFileName);
> +               javaFile.delete();
> +           }
> +       }
> +
>           String classFile = ctxt.getOutputDir() + File.separatorChar;
>           if (pkgName != null && !pkgName.equals(""))
>               classFile = classFile + pkgName.replace('.', 
> File.separatorChar) +
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org
> 

Mime
View raw message