問題重現(xiàn):
今天一剛開始學(xué)Java的同學(xué)在接觸Jsp的時候遇到了一個比較詭異的問題,他在JSP中始終無法使用自己寫的類。簡單的演示問題代碼:
//沒有定義包名
public class MyDefaultClass {
}
//index.jsp文件
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%
MyDefaultClass cls = new MyDefaultClass();
%>
Load successful
</body>
</html>
出現(xiàn)的錯誤提示:
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: Unable to compile class for JSP:
An error occurred at line: 12 in the jsp file: /index.jsp
MyDefaultClass cannot be resolved to a type
9: <body>
10:
11: <%
12: MyDefaultClass cls = new MyDefaultClass();
13: %>
14:
15: Load successful
An error occurred at line: 12 in the jsp file: /index.jsp
MyDefaultClass cannot be resolved to a type
9: <body>
10:
11: <%
12: MyDefaultClass cls = new MyDefaultClass();
13: %>
14:
15: Load successful
Stacktrace:
org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:92)
org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:330)
org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:439)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:349)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:327)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:314)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:592)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
解決方案:
為什么要特別提示他是剛開始接觸Java呢?因為我是想強(qiáng)調(diào)一下他沒有定義包名的習(xí)慣,所以才會出現(xiàn)這個問題,而在Java中不定義包名是一個非常不好的編程習(xí)慣。這個問題本身是可以通過定義自己的包名,然后在JSP文件中導(dǎo)入自己的包解決。
問題原因:
由于JSP文件在請求時動態(tài)的生成Servlet類,然后動態(tài)的編譯新生成的Servlet類,并加載新編譯出的Servlet的class文件,運行相應(yīng)的service方法,返回結(jié)果給客戶端。根據(jù)棧信息可以知道問題出在了動態(tài)編譯Servlet類的時候,而且是說MyDefaultClass無法被解析。
所以我猜測,可能是Tomcat在解析JSP文件的時候,沒有發(fā)現(xiàn)有用戶導(dǎo)入的類型(沒有使用命名空間,因而無法導(dǎo)入包,也不需要加包名的前綴,導(dǎo)致Tomcat在解析JSP文件的時候無法自動感知到當(dāng)前是引用了用戶自定義的類的;也導(dǎo)致在編譯的時候卻能通過),所以在動態(tài)編譯的時候沒有設(shè)置ClassPath的值,然后導(dǎo)致了這個問題。然而對于這個“Bug”,Tomcat本身應(yīng)該不會想不到,何況從邏輯上,默認(rèn)的把/classes和/lib的目錄加入到ClassPath中去編譯動態(tài)生成的Servlet類也是合理的,那么Tomcat為什么要這樣做呢?我的猜測可能會有兩點吧:1. Tomcat也認(rèn)為不定義包名是非常不好的習(xí)慣,因而故意留下這個缺陷,以驚醒編程人員。2. 也有可能是出于性能的考慮,如果不加ClassPath應(yīng)該是可以提升編譯動態(tài)生成的Servlet類的速度的,因而只要不需要ClassPath的情況下,默認(rèn)就不加。
2010-09-22
posted on 2011-07-20 23:08
DLevin 閱讀(888)
評論(0) 編輯 收藏 所屬分類:
Core Java