Tomcat 7之無需JDK只需JRE與無需web.xm及J2SE 6.0之真實與謊言?

阿敏總司令發表於2010-06-14
Tomcat 7之無需JDK只需JRE與無需web.xm及J2SE 6.0之真實與謊言?

當然首先是確定一下,是真實的,吃個定心丸先,不是謊言:)

下載了Tomcat 7 RC4,解壓到 D:\OpenSource\Tomcat\7.0.0-RC4 目錄下後
先將 JAVA_HOME 變數清除,如果你原先有設定 JAVA_HOME 變數的話,免得產生干擾
在命令列下,先取消 JAVA_HOME 變數

[color=red]set JAVA_HOME=[/color]

然後設定 JRE_HOME 變數

[color=red]set JRE_HOME=D:\JRE\1.6.0[/color]

再啟動,就可以順利開啟了。。。。
cd /d D:\OpenSource\Tomcat\7.0.0-RC4\bin
D:\OpenSource\Tomcat\7.0.0-RC4\bin>startup.bat

當然,也可以順利地停止
D:\OpenSource\Tomcat\7.0.0-RC4\bin>shutdown.bat

對於習慣性設定 JAVA_HOME 變數的開發者來說,如果僅是將它改為 JRE 所在的路徑,想來試試,就會報錯。

[color=red]set JAVA_HOME=D:\JRE\1.6.0[/color]

然後 startup.bat 想啟動之
cd /d D:\OpenSource\Tomcat\7.0.0-RC4\bin
D:\OpenSource\Tomcat\7.0.0-RC4\bin>startup.bat

嘿嘿,啟不來了,呵呵,報告 JAVA_HOME 變數設定不對,應當指向JDK,而不是直接指向 JRE 路徑了事
[color=red]The JAVA_HOME environment variable is not defined correctly
This environment variable is needed to run this program
NB: JAVA_HOME should point to a JDK not a JRE[/color]

可能會有疑問,不是明明文件裡說只需要JRE 6.0的嗎?
[color=red]Apache Tomcat 7.0 requires the Java 2 Standard Edition Runtime Environment (JRE) version 6.0 or later.[/color]

但是,正如前面設定 JRE_HOME 變數所說的,不信,再翻開文件去看一下,裡面說得很清楚是設定 JRE_HOME 變數,當然去看 setclasspath.bat 的指令碼的具體內容可能更加能夠了解清楚它
[color=red]Set an environment variable named JRE_HOME to the pathname of the directory into which you installed the JRE[/color]

如果直接將 JRE 路徑當作 JAVA_HOME,那則是習慣惹得錯了,呵呵。不過話說回來,僅是配置 JRE_HOME 的情況比較少;都是設定過 JAVA_HOME 變數,然後 JRE_HOME 自己掛之,然後 PATH 里加上個 .;%JAVA_HOME%\bin 之類的。。。

真實謊言,其實自從 Tomcat 5.5 開始,都說明只需要 JRE 就可以執行了。只不過 Tomcat 5.0 時候還是需要 JDK 1.3 才可以執行的。

由於Tomcat 7必須是J2SE 6以上版本才可以執行,那就試一下J2SE 5,看會有什麼情況

[color=red]set JAVA_HOME=D:\JRE\1.5.0[/color]

然後 startup.bat 想啟動之
cd /d D:\OpenSource\Tomcat\7.0.0-RC4\bin
D:\OpenSource\Tomcat\7.0.0-RC4\bin>startup.bat
並加上 -verbose 進行跟蹤,可以得到如下詳細的錯誤資訊
[code]
[Loaded java.io.IOException from shared objects file]
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]
[/code]
實際上,啟動指令碼先會認 JAVA_HOME 變數,在找到 JAVA_HOME 的情況下,會將 JAVA_HOME 賦值給 JRE_HOME,如果有定義 JRE_HOME 變數的話,則 JRE_HOME 變數是最優先的,比如,你定義
[code]
JAVA_HOME=D:\JDK\1.6.0
JRE_HOME=D:\JRE\1.5.0
[/code]
是執行不起來的。

其實從Tomcat 5.5開始就不通過JDK去編譯JSP了,而是通過Eclipse JDT Java編譯器來編譯JSP檔案。

為了後面的試驗方便,首先配置個管理使用者,編輯 conf\tomcat-users.xml 配置檔案,
由於Tomcat 7重新定義了四個不同的角色來管理應用程式,而不是原來單一個manager角色,為此增加了角色為manager-gui的gui_admin使用者,密碼password
[code]
<role rolename="manager-gui"/>
<user username="gui_admin" password="password" roles="manager-gui"/>
[/code]
為此,你需要設定不同的角色處理不同的管理內容,具體如下:
[color=red]manager-gui - allows access to the HTML GUI and the status pages
manager-script - allows access to the text interface and the status pages
manager-jmx - allows access to the JMX proxy and the status pages
manager-status - allows access to the status pages only[/color]

這樣gui_admin可以訪問進行管理
[code]
http://localhost:8080/manager/status
http://localhost:8080/manager/html
[/code]

測試一下無需web.xml配置檔案來建立一個Web應用程式專案 Tomcat7
通過註解編寫一個Servlet,名為 AnnotationServlet.java
[code]
@WebServlet("/AnnotationServlet")
public class AnnotationServlet extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException
{
PrintWriter out = response.getWriter();
out.println("Annotation Servlet in Tomcat 7");
}
}
}
[/code]
如果你用JDK 1.5來編譯則會出錯
[code]
javac -cp D:\OpenSource\Tomcat\7.0.0-RC4\lib\servlet-api.jar *.java
AnnotationServlet.java:4: 無法訪問 javax.servlet.ServletException
錯誤的類檔案: D:\OpenSource\Tomcat\7.0.0-RC4\lib\servlet-api.jar(javax/servlet/ServletException.class)
類檔案具有錯誤的版本 50.0,應為 49.0
請刪除該檔案或確保該檔案位於正確的類路徑子目錄中。
import javax.servlet.ServletException;
^
1 錯誤
[/code]
用1.6編譯後,直接部署,啟動,整個專案就一個 AnnotationServlet.class,啟動後照樣訪問
[code]
http://localhost:8080/Tomcat7/AnnotationServlet
[/code]

當然一個Web專案,少了web.xml檔案估計也是玩不轉的,試一下通過註解與沒有註解的Servlet共同工作的場景,建立一個NoneAnnotationServlet.java
並在web.xml裡配置之
[code]
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Web Application Tomcat 7 Servlet 3.0 JSP 2.2</display-name>
<description>Web Application Tomcat 7 Servlet 3.0 JSP 2.2</description>
<servlet>
<servlet-name>NoneAnnotationServlet</servlet-name>
<servlet-class>NoneAnnotationServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>NoneAnnotationServlet</servlet-name>
<url-pattern>/NoneAnnotationServlet</url-pattern>
</servlet-mapping>
</web-app>
[/code]
編譯、部署後,都可以正常工作。
[code]
http://localhost:8080/Tomcat7/AnnotationServlet
http://localhost:8080/Tomcat7/NoneAnnotationServlet
[/code]

蒽哪,很和諧的說。Tomcat還有很多新的Servlet 3.0與Java EE 6規範的特性,慢慢測試之。

相關文章