閱讀245 返回首頁    go 技術社區[雲棲]


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

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 變量 

set JAVA_HOME= 

然後設置 JRE_HOME 變量 

set JRE_HOME=D:/JRE/1.6.0 

再啟動,就可以順利開啟了。。。。 
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 所在的路徑,想來試試,就會報錯。 

set JAVA_HOME=D:/JRE/1.6.0 

然後 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 路徑了事 
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
 

可能會有疑問,不是明明文檔裏說隻需要JRE 6.0的嗎? 
Apache Tomcat 7.0 requires the Java 2 Standard Edition Runtime Environment (JRE) version 6.0 or later. 

但是,正如前麵設置 JRE_HOME 變量所說的,不信,再翻開文檔去看一下,裏麵說得很清楚是設置 JRE_HOME 變量,當然去看 setclasspath.bat 的腳本的具體內容可能更加能夠了解清楚它 
Set an environment variable named JRE_HOME to the pathname of the directory into which you installed the JRE 

如果直接將 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,看會有什麼情況 

set JAVA_HOME=D:/JRE/1.5.0 

然後 startup.bat 想啟動之 
cd /d D:/OpenSource/Tomcat/7.0.0-RC4/bin 
D:/OpenSource/Tomcat/7.0.0-RC4/bin>startup.bat 
並加上 -verbose 進行跟蹤,可以得到如下詳細的錯誤信息 

Java代碼 
  1. [Loaded java.io.IOException from shared objects file]  
  2. Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file  
  3.         at java.lang.ClassLoader.defineClass1(Native Method)  
  4.         at java.lang.ClassLoader.defineClass(Unknown Source)  
  5.         at java.security.SecureClassLoader.defineClass(Unknown Source)  
  6.         at java.net.URLClassLoader.defineClass(Unknown Source)  
  7.         at java.net.URLClassLoader.access$100(Unknown Source)  
  8.         at java.net.URLClassLoader$1.run(Unknown Source)  
  9.         at java.security.AccessController.doPrivileged(Native Method)  
  10.         at java.net.URLClassLoader.findClass(Unknown Source)  
  11.         at java.lang.ClassLoader.loadClass(Unknown Source)  
  12.         at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)  
  13.         at java.lang.ClassLoader.loadClass(Unknown Source)  
  14.         at java.lang.ClassLoader.loadClassInternal(Unknown Source)  
  15. [Loaded java.lang.Shutdown from shared objects file]  
  16. [Loaded java.lang.Shutdown$Lock from shared objects file]  

實際上,啟動腳本先會認 JAVA_HOME 變量,在找到 JAVA_HOME 的情況下,會將 JAVA_HOME 賦值給 JRE_HOME,如果有定義 JRE_HOME 變量的話,則 JRE_HOME 變量是最優先的,比如,你定義 
Java代碼 
  1. JAVA_HOME=D:/JDK/1.6.0  
  2. JRE_HOME=D:/JRE/1.5.0  

是運行不起來的。 

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

為了後麵的試驗方便,首先配置個管理用戶,編輯 conf/tomcat-users.xml 配置文件, 
由於Tomcat 7重新定義了四個不同的角色來管理應用程序,而不是原來單一個manager角色,為此增加了角色為manager-gui的gui_admin用戶,密碼password 
Java代碼 
  1. <role rolename="manager-gui"/>  
  2. <user username="gui_admin" password="password" roles="manager-gui"/>  

為此,你需要設置不同的角色處理不同的管理內容,具體如下: 
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
 

這樣gui_admin可以訪問進行管理 
Java代碼 
  1. http://localhost:8080/manager/status  
  2. http://localhost:8080/manager/html  


測試一下無需web.xml配置文件來創建一個Web應用程序項目 Tomcat7 
通過注解編寫一個Servlet,名為 AnnotationServlet.java 
Java代碼 
  1. @WebServlet("/AnnotationServlet")  
  2. public class AnnotationServlet extends HttpServlet   
  3. {  
  4.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException   
  5.     {  
  6.         PrintWriter out = response.getWriter();  
  7.         out.println("Annotation Servlet in Tomcat 7");  
  8.         }  
  9.     }  
  10. }  

如果你用JDK 1.5來編譯則會出錯 
Java代碼 
  1. javac -cp D:/OpenSource/Tomcat/7.0.0-RC4/lib/servlet-api.jar *.java  
  2. AnnotationServlet.java:4: 無法訪問 javax.servlet.ServletException  
  3. 錯誤的類文件: D:/OpenSource/Tomcat/7.0.0-RC4/lib/servlet-api.jar(javax/servlet/ServletException.class)  
  4. 類文件具有錯誤的版本 50.0,應為 49.0  
  5. 請刪除該文件或確保該文件位於正確的類路徑子目錄中。  
  6. import javax.servlet.ServletException;  
  7.                      ^  
  8. 1 錯誤  

用1.6編譯後,直接部署,啟動,整個項目就一個 AnnotationServlet.class,啟動後照樣訪問 
Java代碼 
  1. http://localhost:8080/Tomcat7/AnnotationServlet  


當然一個Web項目,少了web.xml文件估計也是玩不轉的,試一下通過注解與沒有注解的Servlet共同工作的場景,創建一個NoneAnnotationServlet.java 
並在web.xml裏配置之 
Java代碼 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns="https://java.sun.com/xml/ns/javaee"  
  3.   xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"  
  4.   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
  5.                       http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
  6.   version="3.0">    
  7.     <display-name>Web Application Tomcat 7 Servlet 3.0 JSP 2.2</display-name>  
  8.     <description>Web Application Tomcat 7 Servlet 3.0 JSP 2.2</description>  
  9.     <servlet>  
  10.         <servlet-name>NoneAnnotationServlet</servlet-name>  
  11.         <servlet-class>NoneAnnotationServlet</servlet-class>  
  12.     </servlet>  
  13.   
  14.     <servlet-mapping>  
  15.         <servlet-name>NoneAnnotationServlet</servlet-name>  
  16.         <url-pattern>/NoneAnnotationServlet</url-pattern>  
  17.     </servlet-mapping>  
  18. </web-app>  

編譯、部署後,都可以正常工作。 
Java代碼 
  1. http://localhost:8080/Tomcat7/AnnotationServlet  
  2. http://localhost:8080/Tomcat7/NoneAnnotationServlet  


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

最後更新:2017-04-02 06:51:19

  上一篇:go myEclipe的一個bug 缺少引用的包時出現不能生成編譯後的class文件的解決辦法
  下一篇:go magento 1.4-- 推薦插件 -- 新的圖片放大鏡插件 -- Cloudzoom