亚洲精选国产,北岛玲日韩精品一区二区三区,国产精品久久久久久久久久99 http://www.aygfsteel.com/freeman1984/category/46243.html STANDING ON THE SHOULDERS OF GIANTSzh-cnMon, 24 Dec 2012 20:15:47 GMTMon, 24 Dec 2012 20:15:47 GMT60關于tomcat和sessionCookieName和SESSION_PARAMETER_NAME以及disableURLRewriting參數原理和使用http://www.aygfsteel.com/freeman1984/archive/2012/12/24/393402.html瘋狂瘋狂Mon, 24 Dec 2012 07:16:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2012/12/24/393402.htmlhttp://www.aygfsteel.com/freeman1984/comments/393402.htmlhttp://www.aygfsteel.com/freeman1984/archive/2012/12/24/393402.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/393402.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/393402.html閱讀全文

瘋狂 2012-12-24 15:16 發表評論
]]>
jmeter 相關參數介紹http://www.aygfsteel.com/freeman1984/archive/2011/12/14/366359.html瘋狂瘋狂Wed, 14 Dec 2011 09:30:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/12/14/366359.htmlhttp://www.aygfsteel.com/freeman1984/comments/366359.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/12/14/366359.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/366359.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/366359.htmlJmeter測試報表相關參數說明

采用Jmeter測試工具對web系統作的負載測試,得出的響應報表,數據比較難懂,現作一具體說明。
以下是在一次具體負載測試中得出的具體數值,測試線程設置情況為:線程數:200,等待時間(ramp-up):0秒,循環次數為永遠,另:
線程組——這些元件用于指定運行的線程數和等候周期。每個線程模擬一個用戶,而等候周期用于指定創建全部線程的時間。例如,線程數為5,等候時間為10秒,則創建每個線程之間的時間間隔為2秒。循環數定義了線程的運行時間。使用調度器,還可以設置運行的起始時間。
取樣器——對于服務器HTTPFTPLDAP請求,這些元件是可配置請求。該教程僅側重于Web Services請求。
監聽器——這些元件用于請求數據的后期處理。例如,可以將數據保存到文件或用圖表來說明結果。此時JMeter圖表并沒有提供許多配置選項;然而它是可擴展的,它始終可以添加額外的可視化效果或數據處理模塊。
得出的圖形報表和聚合報告如下所示:

 

一、圖形報表

圖表底部參數的含義如下:
樣本數目是總共發送到服務器的請求數。
最新樣本是代表時間的數字,是服務器響應最后一個請求的時間。
吞吐量是服務器每分鐘處理的請求數。
平均值是總運行時間除以發送到服務器的請求數。
中間值是代表時間的數字,有一半的服務器響應時間低于該值而另一半高于該值。
偏離表示服務器響應時間變化、離散程度測量值的大小,或者,換句話說,就是數據的分布。

二、 聚合報告

圖表含義說明如下:
Label
:說明是請求類型,如Http,FTP等請求。
#Samples
:也就是圖形報表中的樣本數目,總共發送到服務器的樣本數目。
Average
:也就是圖形報表中的平均值,是總運行時間除以發送到服務器的請求數。
Median
:也就是圖形報表中的中間值,是代表時間的數字,有一半的服務器響應時間低于該值而另一半高于該值。
90%line
:是指90%請求的響應時間比所得數值還要小。
Min
:是代表時間的數字,是服務器響應的最短時間。
Max:
是代表時間的數字,是服務器響應的最長時間。
Error%:
請求的錯誤百分比。
Throughput:
也就是圖形報表中的吞吐量,這里是服務器每單位時間處理的請求數,注意查看是秒或是分鐘。
KB/sec:
是每秒鐘請求的字節數。

三、 使用分析
在測試過程中,平均響應時間是我們性能測試的一個重要衡量指標,但是在測試中,特別是在聚合報告中,得出的90%Line,我這里參考《《LoadRunner 沒有告訴你的》之一——描述性統計與性能結果分析》,我認為90%Line等同于該文作者提出的90%響應時間,這個數值對我們性能測試分析也很有參考價值。90%響應時間是說在發送的請求中,90%的用戶響應時間都比得到的數值上要短,同時說明,一個系統在應用時,90%的用戶響應時間都能達到這個數值,那么就為系統性能分析提供了很好的參考價值。

 轉自:百度文庫



瘋狂 2011-12-14 17:30 發表評論
]]>
apache性能測試工具abhttp://www.aygfsteel.com/freeman1984/archive/2011/12/13/366235.html瘋狂瘋狂Tue, 13 Dec 2011 06:36:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/12/13/366235.htmlhttp://www.aygfsteel.com/freeman1984/comments/366235.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/12/13/366235.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/366235.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/366235.html使用格式: ./ab [options] [http://]hostname[:port]/path
參數說明:
    -n requests     Number of requests to perform
    //在測試會話中所執行的請求個數。默認時,僅執行一個請求
    -c concurrency Number of multiple requests to make
    //一次產生的請求個數。默認是一次一個。
    -t timelimit    Seconds to max. wait for responses
    //測試所進行的最大秒數。其內部隱含值是-n 50000。它可以使對服務器的測試限制在一個固定的總時間以內。默認時,沒有時間限制。
    -p postfile     File containing data to POST
    //包含了需要POST的數據的文件.
    -T content-type Content-type header for POSTing
    //POST數據所使用的Content-type頭信息。
    -v verbosity    How much troubleshooting info to print
    //設置顯示信息的詳細程度 - 4或更大值會顯示頭信息, 3或更大值可以顯示響應代碼(404, 200等), 2或更大值可以顯示警告和其他信息。 -V 顯示版本號并退出。
    -w              Print out results in HTML tables
    //以HTML表的格式輸出結果。默認時,它是白色背景的兩列寬度的一張表。
    -i              Use HEAD instead of GET
   // 執行HEAD請求,而不是GET。
    -x attributes   String to insert as table attributes
    //
    -y attributes   String to insert as tr attributes
    //
    -z attributes   String to insert as td or th attributes
    //
    -C attribute    Add cookie, eg. 'Apache=1234. (repeatable)
    //-C cookie-name=value 對請求附加一個Cookie:行。其典型形式是name=value的一個參數對。此參數可以重復。
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    //-P proxy-auth-username:password 對一個中轉代理提供BASIC認證信任。用戶名和密碼由一個:隔開,并以base64編碼形式發送。無論服務器是否需要(即, 是否發送了401認證需求代碼),此字符串都會被發送。
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -h              Display usage information (this message)
    //-attributes 設置 屬性的字符串. 缺陷程序中有各種靜態聲明的固定長度的緩沖區。另外,對命令行參數、服務器的響應頭和其他外部輸入的解析也很簡單,這可能會有不良后果。它沒有完整地實現HTTP/1.x; 僅接受某些'預想'的響應格式。 strstr(3)的頻繁使用可能會帶來性能問題,即, 你可能是在測試ab而不是服務器的性能。

參數很多,一般我們用 -c 和 -n 參數就可以了. 例如:

./ab -c 1000 -n 1000 http://10.88.15.77/test.php

這個表示同時處理1000個請求并運行1000次index.php文件.
#ab -c 1000 -n 1000 http://10.88.15.77/test.php


Benchmarking 10.88.15.77 (be patient)

Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests


Server Software:        Apache/2.2.8
//平臺apache 版本2.2.8
Server Hostname:        10.88.15.77
//服務器主機名
Server Port:            80
//服務器端口

Document Path:          /test.php

//測試的頁面文檔
Document Length:        1018 bytes
//文檔大小

Concurrency Level:      1000
//并發數
Time taken for tests:   8.188731 seconds
//整個測試持續的時間
Complete requests:      1000
//完成的請求數量
Failed requests:        0
//失敗的請求數量
Write errors:           0

Total transferred:      1361581 bytes
//整個場景中的網絡傳輸量
HTML transferred:       1055666 bytes
//整個場景中的HTML內容傳輸量
Requests per second:    122.12 [#/sec] (mean)
//大家最關心的指標之一,相當于 LR 中的 每秒事務數 ,后面括號中的 mean 表示這是一個平均值
Time per request:       8188.731 [ms] (mean)
//大家最關心的指標之二,相當于 LR 中的 平均事務響應時間 ,后面括號中的 mean 表示這是一個平均值
Time per request:       8.189 [ms] (mean, across all concurrent requests)
//每個請求實際運行時間的平均值
Transfer rate:          162.30 [Kbytes/sec] received
//平均每秒網絡上的流量,可以幫助排除是否存在網絡流量過大導致響應時間延長的問題

Connection Times (ms)
              min mean[+/-sd] median   max
Connect:        4 646 1078.7     89    3291
Processing:   165 992 493.1    938    4712
Waiting:      118 934 480.6    882    4554
Total:        813 1638 1338.9   1093    7785
//網絡上消耗的時間的分解,各項數據的具體算法還不是很清楚

Percentage of the requests served within a certain time (ms)
50%   1093
66%   1247
75%   1373
80%   1493
90%   4061
95%   4398
98%   5608
99%   7368
100%   7785 (longest request)
//整個場景中所有請求的響應情況。在場景中每個請求都有一個響應時間,其中50%的用戶響應時間小于1093 毫秒,60% 的用戶響應時間小于1247 毫秒,最大的響應時間小于7785 毫秒

      由于對于并發請求,cpu實際上并不是同時處理的,而是按照每個請求獲得的時間片逐個輪轉處理的,所以基本上第一個Time per request時間約等于第二個Time per request時間乘以并發請求數
轉自:http://blog.sina.com.cn/s/blog_3c9872d00100dbox.html



瘋狂 2011-12-13 14:36 發表評論
]]>
xmlrpc介紹和使用http://www.aygfsteel.com/freeman1984/archive/2011/11/11/363526.html瘋狂瘋狂Fri, 11 Nov 2011 06:58:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/11/11/363526.htmlhttp://www.aygfsteel.com/freeman1984/comments/363526.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/11/11/363526.html#Feedback1http://www.aygfsteel.com/freeman1984/comments/commentRss/363526.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/363526.html  閱讀全文

瘋狂 2011-11-11 14:58 發表評論
]]>
Directory index forbidden by Options directive問題http://www.aygfsteel.com/freeman1984/archive/2011/11/01/362421.html瘋狂瘋狂Tue, 01 Nov 2011 02:09:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/11/01/362421.htmlhttp://www.aygfsteel.com/freeman1984/comments/362421.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/11/01/362421.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/362421.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/362421.html方法1: 在mod_jk.conf中配置JkMountCopy All ,這樣所有虛擬主機都公用了mod_jk的配置
方法2:在虛擬主機中配置JkMountCopy On 例如:

<VirtualHost *:80>
    #JkMountCopy On
   ...

瘋狂 2011-11-01 10:09 發表評論
]]>
Apache的Order Allow,Deny 詳解(轉)http://www.aygfsteel.com/freeman1984/archive/2011/10/31/362372.html瘋狂瘋狂Mon, 31 Oct 2011 06:23:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/10/31/362372.htmlhttp://www.aygfsteel.com/freeman1984/comments/362372.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/10/31/362372.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/362372.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/362372.htmlAllow和Deny可以用于apache的conf文件或者.htaccess文件中(配合Directory, Location, Files等),用來控制目錄和文件的訪問授權。

所以,最常用的是:
Order Deny,Allow
Allow from All

注意“Deny,Allow”中間只有一個逗號,也只能有一個逗號,有空格都會出錯;單詞的大小寫不限。上面設定的含義是先設定“先檢查禁止設定,沒有禁止的全部允許”,而第二句沒有Deny,也就是沒有禁止訪問的設定,直接就是允許所有訪問了。這個主要是用來確保或者覆蓋上級目錄的設置,開放所有內容的訪問權。

按照上面的解釋,下面的設定是無條件禁止訪問:
Order Allow,Deny
Deny from All

如果要禁止部分內容的訪問,其他的全部開放:
Order Deny,Allow
Deny from ip1 ip2
或者
Order Allow,Deny
Allow from all
Deny from ip1 ip2

apache會按照order決定最后使用哪一條規則,比如上面的第二種方式,雖然第二句allow允許了訪問,但由于在order中allow不是最后規則,因此還需要看有沒有deny規則,于是到了第三句,符合ip1和ip2的訪問就被禁止了。注意,order決定的“最后”規則非常重要,下面是兩個錯誤的例子和改正方式:

Order Deny,Allow
Allow from all
Deny from domain.org
錯誤:想禁止來自domain.org的訪問,但是deny不是最后規則,apache在處理到第二句allow的時候就已經匹配成功,根本就不會去看第三句。
解決方法:Order Allow,Deny,后面兩句不動,即可。

Order Allow,Deny
Allow from ip1
Deny from all
錯誤:想只允許來自ip1的訪問,但是,雖然第二句中設定了allow規則,由于order中deny在后,所以會以第三句deny為準,而第三句的范圍中又明顯包含了ip1(all include ip1),所以所有的訪問都被禁止了。
解決方法一:直接去掉第三句。
解決方法二:
Order Deny,Allow
Deny from all
Allow from ip1

 

下面是測試過的例子:
--------------------------------
Order deny,allow
allow from all
deny from 219.204.253.8
#全部都可以通行
-------------------------------
Order deny,allow
deny from 219.204.253.8
allow from all
#全部都可以通行
-------------------------------
Order allow,deny
deny from 219.204.253.8
allow from all
#只有219.204.253.8不能通行
-------------------------------
Order allow,deny
allow from all
deny from 219.204.253.8
#只有219.204.253.8不能通行
-------------------------------
-------------------------------
Order allow,deny
deny from all
allow from 219.204.253.8
#全部都不能通行
-------------------------------
Order allow,deny
allow from 219.204.253.8
deny from all
#全部都不能通行
-------------------------------
Order deny,allow
allow from 219.204.253.8
deny from all
#只允許219.204.253.8通行
-------------------------------
Order deny,allow
deny from all
allow from 219.204.253.8
#只允許219.204.253.8通行
-------------------------------
--------------------------------
Order deny,allow
#全部都可以通行(默認的)
-------------------------------
Order allow,deny
#全部都不能通行(默認的)
-------------------------------
Order allow,deny
deny from all
#全部都不能通行
-------------------------------
Order deny,allow
deny from all
#全部都不能通行
-------------------------------
對于上面兩種情況,如果換成allow from all,則全部都可以通行!
-------------------------------
Order deny,allow
deny from 219.204.253.8
#只有219.204.253.8不能通行
-------------------------------
Order allow,deny
deny from 219.204.253.8
#全部都不能通行
-------------------------------
Order allow,deny
allow from 219.204.253.8
#只允許219.204.253.8通行
-------------------------------
Order deny,allow
allow from 219.204.253.8
#全部都可以通行
-------------------------------
-------------------------------
order deny,allow
allow from 218.20.253.2
deny from 218.20
#代表拒絕218.20開頭的IP,但允許218.20.253.2通過;而其它非218.20開頭的IP也都允許通過。
-------------------------------
order allow,deny
allow from 218.20.253.2
deny from 218.20
#和上面的差不多,只是掉換的order語句中的allow、deny先后順序,但最終結果表示全部都拒絕!

form:http://hi.baidu.com/enjoypain/blog/item/f48c7aecdba298d12f2e21ac.html

前段時間做了個Apache的HTTP代理服務器,其中的order allow,deny這部分弄的不太懂,于是上網找資料看,誰知道越看越糊涂,其中有些難以分辨對錯甚至是誤導。就像破解windows系統密碼的一些文章那樣,很多都是人云亦云的,并沒有經過測試。廢話少說,先把我經過測試后分析總結出來的結論show出來,相信這對大家的理解非常有幫助。
轉自:http://hi.baidu.com/amenmen/blog/item/3145921fdf498f11314e154b.html



瘋狂 2011-10-31 14:23 發表評論
]]>
jsessionid 問題分析http://www.aygfsteel.com/freeman1984/archive/2011/09/02/357833.html瘋狂瘋狂Fri, 02 Sep 2011 08:33:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/09/02/357833.htmlhttp://www.aygfsteel.com/freeman1984/comments/357833.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/09/02/357833.html#Feedback2http://www.aygfsteel.com/freeman1984/comments/commentRss/357833.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/357833.html閱讀全文

瘋狂 2011-09-02 16:33 發表評論
]]>
linux php5 apache2 安裝步驟http://www.aygfsteel.com/freeman1984/archive/2011/06/10/352043.html瘋狂瘋狂Fri, 10 Jun 2011 06:37:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/06/10/352043.htmlhttp://www.aygfsteel.com/freeman1984/comments/352043.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/06/10/352043.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/352043.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/352043.html相關軟件:
apache:httpd-2.2.19.tar.gz
php:php-5.2.17.tar.gz

首先安裝apache:
將 zxvf httpd-2.2.19.tar.gz放到=/usr/local/src下
#tar zxvf httpd-2.2.19.tar.gz
#cd httpd-2.2.19
#./configure --prefix=/usr/local/apache2219 --enable-module=so  (--prefix=/usr/local/apache2219 是apache最終的安裝目錄)
#make
#make install

裝php:aix下可能需要安裝libxml2 見http://www.aygfsteel.com/freeman1984/archive/2011/06/14/352271.html,在編譯的時候如果報錯:
configure: error: xml2-config not found.
就加上--with-libxml-dir=/XIV1/qkydb/libxml

將 zxvf php-5.2.17.tar.gz放到=/usr/local/src下
#tar zxvf php-5.2.17.tar.gz
#cd php-5.2.17
#./configure --prefix=/usr/local/php --with-apxs2=/usr/local/apache2219/bin/apxs (--prefix=/usr/local/php是php最終的安裝目錄 )
#make
#make install

配置
(1)復制PHP.INI文件到正確位置
在PHP解壓的目錄下運行
#cp php.ini-dist /usr/local/php/lib/php.ini
(2)編輯apache配置文件httpd.conf
#vi /usr/local/apache2219/conf/httpd.conf
要改的有如下幾處:
一般都在
#AddType application/x-tar .tgz
下加一行
AddType application/x-httpd-php .php
還有找到
DirectoryIndex index.html index.html.var
在后面加 index.php 讓它把index.php做為默認頁
再找
#ServerName
把#去掉,后面的IP改成你的IP.
找到
DocumentRoot "/usr/local/apache2219/htdocs"
把/usr/local/apache2/htdocs改為你存放網頁文件的路徑

比如我是放在/myweb目錄下,所以我以后上傳PHP文件就放在/myweb目錄下,然后用IP訪問,就能看到首頁了
差不多就這些了,至于apache2其它優化,請看
http://www.phpv.net/
里的apache配置那一分類.
保存httpd.conf文件.

寫個index.php
內容:
<?php
phpinfo();
?>

啟動apache
/usr/local/apache2219/bin/apachectl start

訪問:
http://ip/



瘋狂 2011-06-10 14:37 發表評論
]]>
Apache Commons Configuration簡介http://www.aygfsteel.com/freeman1984/archive/2011/06/09/351984.html瘋狂瘋狂Thu, 09 Jun 2011 06:56:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/06/09/351984.htmlhttp://www.aygfsteel.com/freeman1984/comments/351984.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/06/09/351984.html#Feedback1http://www.aygfsteel.com/freeman1984/comments/commentRss/351984.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/351984.htmlhttp://commons.apache.org/configuration/
它支持對配置文件的讀取,保存,運行期加載,操作非常方便。下面簡單的一下代碼示例一下,具體的其他操作文檔可以去官方找到:
需要用到commons-lang,commons-collections,commons-logging,log4j jar包
public class Test {
    
    
public static  void main(String[] args) throws ConfigurationException, InterruptedException {
        xmlLoadTest();
        fileLoadTest();
        saveTest();
        runtimeReload();
    }

    
//xml文件
    public static void xmlLoadTest() throws ConfigurationException{
        String file 
= "test1.xml";
        XMLConfiguration config 
= new XMLConfiguration(Test.class.getResource(file));
        System.out.println(config.getString(
"conf.url"));
        System.out.println(config.getDouble(
"conf.money"));
    }
  
    
//properties文件
    private static void fileLoadTest() throws ConfigurationException {
        String file 
= "test2.properties";
        PropertiesConfiguration config 
= new PropertiesConfiguration(Test.class.getResource(file));
        System.out.println(config.getString(
"url"));
    }

    
//保存到文件
    public static void saveTest() throws ConfigurationException{
        String file 
= "test2.properties";
        PropertiesConfiguration config 
= new PropertiesConfiguration(Test.class.getResource(file));
        
//設置自動保存 或顯示調用 config.save();
        config.setProperty("colors.background""#000000");
        config.setAutoSave(
true);
    }

    
//運行期參數修改加載
    public static void runtimeReload() throws ConfigurationException, InterruptedException{
        String file 
= "test2.properties";
        PropertiesConfiguration config 
= new PropertiesConfiguration(Test.class.getResource(file));
        config.setReloadingStrategy(
new FileChangedReloadingStrategy());
        System.out.println(config.getString(
"url"));
        Thread.sleep(
10000);//在休眠期間,手動修改文件里面的url值后觀察日志情況
        System.out.println(config.getString("url"));
    }

}

Configuration 的參數可能來自下面的資源: 
     Properties files XML documents,Property list files (.plist),JNDI,JDBC Datasource,System properties, Applet parameters,Servlet parameters


瘋狂 2011-06-09 14:56 發表評論
]]>
對Lucene PhraseQuery的slop的理解(轉載)http://www.aygfsteel.com/freeman1984/archive/2011/02/25/345116.html瘋狂瘋狂Fri, 25 Feb 2011 05:51:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/02/25/345116.htmlhttp://www.aygfsteel.com/freeman1984/comments/345116.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/02/25/345116.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/345116.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/345116.html 這幾天看Lucene,看到檢索那塊,被PhraseQuery折騰了一陣,那本《Lucene In Action》里的代碼版本太舊了,也不知是翻譯的問題還是我的理解問題,總之在看PhraseQuery的設置slop時費了半天勁,不過,總算是搞明白了,發個帖子來分享一下:

    所謂PhraseQuery,就是通過短語來檢索,比如我想查“big car”這個短語,那么如果待匹配的document的指定項里包含了"big car"這個短語,這個document就算匹配成功??扇绻ヅ涞木渥永锇氖?#8220;big black car”,那么就無法匹配成功了,如果也想讓這個匹配,就需要設定slop,先給出slop的概念:slop是指兩個項的位置之間允許的最大間隔距離,下面我舉例來解釋:

   我的待匹配的句子是:the quick brown fox jumped over the lazy dog.

   例1: 如果我想用“quick fox”來匹配出上面的句子,我發現原句里是quick [brown] fox,就是說和我的“quick fox”中間相差了一個單詞的距離,所以,我這里把slop設為1,表示quickfox這兩項之間最大可以允許有一個單詞的間隔,這樣所有“quick [***] fox”就都可以被匹配出來了。

   例2:如果我想用“fox quick”來匹配出上面的句子,這也是可以的,不過比例1要麻煩,我們需要看把“fox quick”怎么移動能形成“quick [***] fox”,如下表所示,把fox向右移動3次即可:

   fox quick      
1    fox|quick      
2    quick fox   
3    quick    fox

    例3:如果我想用“lazy jumped quick”該如何匹配上面的句子呢?這個比例2還要麻煩,我們要考慮3個單詞,不管多少個單詞,slop表示的是間隔的最大距離,詳細起見,我們分別來看每種組合:(我的待匹配的句子是:the quick brown fox jumped over the lazy dog.)

  • lazy jumped:原句是jumped [over] [the] lazy,就是說它們兩個之間間隔了2個詞,如下所示:需要把lazy向右移動4位

 

   lazy jumped         
1    lazy|jumped         
2    jumped lazy      
3    jumped    lazy   
4    jumped     lazy 

 

  •   lazy jumped quick:我們主要看lazyquick,但是由于jumped是在中間,所以移動的時候還是要把jumped考慮在內,原句里lazyquick的關系是:quick [brown] [fox] [jumped] [over] [the] lazy ,quick lazy中間間隔了5個詞,所以如下圖所示,把lazy向右移動8次
    lazy

jumped

quick               

1

  

lazy|jumped

quick

  

  

  

  

  

 

2

  

jumped

lazy|quick

  

  

  

  

  

 

 3 

  

jumped

quick

 lazy 

  

  

  

  

 

4

  

jumped

quick

  

lazy 

  

  

  

 

 5 

  

jumped

quick

  

  

lazy 

  

  

 

6

  

jumped

quick

  

  

  

lazy 

  

 

7

  

jumped

quick

  

  

  

  

lazy 

 

8

  

jumped

quick

               lazy 

 

  •  最后是jumped qucik,這里不詳細畫表格了,大家可以自己試試,應該是把jumped向右移動4次。

   綜合以上3種情況,所以我們需要把slop設為8才令“lazy jumped quick”可以匹配到原句。



瘋狂 2011-02-25 13:51 發表評論
]]>
使用apache pdfbox讀取pdf 實例http://www.aygfsteel.com/freeman1984/archive/2011/02/24/345064.html瘋狂瘋狂Thu, 24 Feb 2011 06:55:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/02/24/345064.htmlhttp://www.aygfsteel.com/freeman1984/comments/345064.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/02/24/345064.html#Feedback2http://www.aygfsteel.com/freeman1984/comments/commentRss/345064.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/345064.htmlpublic static void main(String[] args) throws Exception {
    InputStream inputStream 
= new BufferedInputStream(
            
new FileInputStream(new File("d:\\work\\lt.pdf")));
    PDDocument pdfDocument 
= PDDocument.load(inputStream);
    StringWriter writer 
= new StringWriter();
    PDFTextStripper stripper 
= new PDFTextStripper();
    stripper.writeText(pdfDocument, writer);
    String contents 
= writer.getBuffer().toString();
    System.out.println(
"文檔內容:"+contents);
    PDDocumentInformation documentInformation 
= pdfDocument.getDocumentInformation();
    System.out.println(
"標題:"+documentInformation.getTitle());
}

}
需要jar包:
pdfbox-1.4.0.jar
fontbox-1.4.0.jar

瘋狂 2011-02-24 14:55 發表評論
]]>
Tomcat中限制ip訪問http://www.aygfsteel.com/freeman1984/archive/2011/02/15/344326.html瘋狂瘋狂Tue, 15 Feb 2011 03:07:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/02/15/344326.htmlhttp://www.aygfsteel.com/freeman1984/comments/344326.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/02/15/344326.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/344326.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/344326.htmlOriginal URL: http://www.miotour.com/2010/04/27/tomcat%e4%b8%ad%e9%99%90%e5%88%b6ip%e8%ae%bf%e9%97%ae/
Tomcat中限制ip訪問是非常簡單的,只需要編輯server.xml文件即可

vi server.xml

找到context區域,如

<context path=”/joseph”  reloadable=”true” docBase=”/var/www/joseph”>

<value className=”org.apache.catalina.values.RemoteAddrValue” allow=”” deny=”127.0.0.1″ />

</context>

說明:只限制127.0.0.1訪問

如要限制192.168.1.0-192.168.5.255和192.168.10.0-192.168.15.255

deny=”192.168.[1-5].*,192.168.[10-15].*”


瘋狂 2011-02-15 11:07 發表評論
]]>
jkmount不轉發部分http://www.aygfsteel.com/freeman1984/archive/2011/02/15/344325.html瘋狂瘋狂Tue, 15 Feb 2011 02:53:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/02/15/344325.htmlhttp://www.aygfsteel.com/freeman1984/comments/344325.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/02/15/344325.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/344325.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/344325.htmlOriginal URL: http://www.miotour.com/2009/11/30/jkmount%e4%b8%8d%e8%bd%ac%e5%8f%91%e9%83%a8%e5%88%86%e8%af%b7%e6%b1%82/

第一種情形:部分靜態頁面需要apache處理,不轉發給后端的tomcat

JkMount  /*    router    ###默認將所有請求轉發給tomcat處理
JKUnmount /*.php   router    ###php請求不交給tomcat處理
JKUnmount /*.htm   router    ###htm請求不交給tomcat處理
JKUnmount /*.html  router
###html請求不交給tomcat處理

JKUnmount     /css/*       router    ###css請求不交給tomcat處理
JKUnmount     /js/*         router     ###js請求不交給tomcat處理

JKUnmount  /image/*   router    ###image請求不交給tomcat處理

 

第二種情形:將所有請求轉發到后端tomcat之后,將不同路徑定位給不同的tomcat

JkMount /*           router

JkMount /login/*     tomcat1

JkMount /shop/*     tomcat2

JkMount /buy/*       tomcat3

 

注意,這種情形下,必須要有這樣的處理:

worker.list=router,jkstatus,tomcat1,tomcat2,tomcat3

如果是第一種情形,tomcat1,tomcat2,tomcat3是不需要寫在上面這個地方的

而是寫在下面:

worker.router.balance_workers=tomcat1,tomcat2,tomcat3

實際使用中,應該是上述兩種情形相結合使用的較多,將靜態內容交給apache處理,然后將動態內容分布到不同的服務器上。

 

 

JkMount把匹配的轉發到指定服務器.
JkUnMount把匹配的不轉發到指定服務器.
JkUnMount選項的級別高于JkMount.
單獨有JkMount規則有效,但單獨有JkUnMount無效,JkUnMount與JkMount要成對出現.



瘋狂 2011-02-15 10:53 發表評論
]]>
apache 集群tomcat配置參數說明http://www.aygfsteel.com/freeman1984/archive/2011/02/15/344322.html瘋狂瘋狂Tue, 15 Feb 2011 02:37:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2011/02/15/344322.htmlhttp://www.aygfsteel.com/freeman1984/comments/344322.htmlhttp://www.aygfsteel.com/freeman1984/archive/2011/02/15/344322.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/344322.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/344322.htmlTomcat 集群配置
打開Server.xml,shutdown, ajp, http這三個端口就不多說了,解開下面注釋
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
jvmRoute的值要根據apache的配置,不能沖突。
接著是最重要的一點,tomcat默認集群配置(<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>)時,配置的細節實際上被省略了,對于大多數應用而言,使用默認配置已經足夠,完整的默認配置應該是這樣:

Xml代碼 [url=http://tyler-zhou.javaeye.com/blog/507158]


<!--同步異步模式由channelSendOptions參數控制,默認值是8,為異步模式,4是同步模式。在異步模式下,可以通過加上拷貝確認(Acknowledge)來提高可靠性,此時channelSendOptions設為10。-->  
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"  channelSendOptions="6">  
<!---session 拷貝方式 BackupManager 只拷貝部署當前應用的服務器,DeltaManager 拷貝方式all to all-->  
    <Manager className="org.apache.catalina.ha.session.BackupManager"  
        expireSessionsOnShutdown="false"  
        notifyListenersOnReplication="true"  
        mapSendOptions="6"/>  
    <!--   
    <Manager className="org.apache.catalina.ha.session.DeltaManager"  
    expireSessionsOnShutdown="false"  
    notifyListenersOnReplication="true"/>  
    -->  
    <!--Channel負責對tomcat集群的IO層進行配置-->  
    <Channel className="org.apache.catalina.tribes.group.GroupChannel">  
        <!--Membership用于發現集群中的其他節點,這里的address用的是組播地址(Multicast address,了解更多組播地址詳情請參見http://zyycaesar.javaeye.com/admin/blogs/296501),使用同一個組播地址和端口的多個節點同屬一個子集群,因此通過自定義組播地址和端口就可將一個大的tomcat集群分成多個子集群-->  
        <Membership className="org.apache.catalina.tribes.membership.McastService"  
            address="228.0.0.4"  
            port="45564"  
            frequency="500"  
            dropTime="3000"/>  
        <!--Receiver用于各個節點接收其他節點發送的數據,在默認配置下tomcat會從4000-4100間依次選取一個可用的端口進行接收,自定義配置時,如果多個tomcat節點在一臺物理服務器上注意要使用不同的端口-->  
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"  
            address="auto"  
            port="5001"  
            selectorTimeout="100"  
            maxThreads="6"/>  
        <!--Sender用于向其他節點發送數據,具體實現通過Transport配置,PooledParallelSender是從tcp連接池中獲取連接,可以實現并行發送,即集群中的多個節點可以同時向其他所有節點發送數據而互不影響-->  
        <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">  
            <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>  
        </Sender>  
        <!---Interceptor有點類似下面將要解釋的Valve,起到一個閥門的作用,在數據到達目的節點前進行檢測或其他操作,如TcpFailureDetector用于檢測在數據的傳輸過程中是否發生了tcp錯誤。--->  
        <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>  
        <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>  
        <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>  
  
    </Channel>  
    <!--Valve用于在節點向客戶端響應前進行檢測或進行某些操作,ReplicationValve就是用于用于檢測當前的響應是否涉及Session數據的更新,如果是則啟動Session拷貝操作,filter用于過濾請求,如客戶端對圖片,css,js的請求就不會涉及Session,因此不需檢測,默認狀態下不進行過濾,監測所有的響應.JvmRouteBinderValve會在前端的Apache mod_jk發生錯誤時保證同一客戶端的請求發送到集群的同一個節點-->  
    <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"  
    filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>  
    <!--Deployer用于集群的farm功能,監控應用中文件的更新,以保證集群中所有節點應用的一致性,如某個用戶上傳文件到集群中某個節點的應用程序目錄下,Deployer會監測到這一操作并把這一文件拷貝到集群中其他節點相同應用的對應目錄下以保持所有應用的一致。這是一個相當強大的功能,不過很遺憾,tomcat集群目前并不能做到這一點,開發人員正在努力實現它,這里的配置只是預留了一個接口-->  
    <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"  
        tempDir="/tmp/war-temp/"  
        deployDir="/tmp/war-deploy/"  
        watchDir="/tmp/war-listen/"  
        watchEnabled="false"/>  
  
    <!--Listener用于跟蹤集群中節點發出和收到的數據,也有點類似Valve的功能。-->  
    <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>  
  
</Cluster>  
最后在Web.xml里面加上<distributable/>,官方文檔沒有這個,但我覺得還是應該加上,因為按照標準的tomcat啟動,當Host對象被創建時,一個Cluster對象(默認配置下是SimpleTcpCluster)也同時被關聯到這個Host對象。當某個應用在web.xml中設置了distributable時,Tomcat將為此應用的上下文環境創建一個DeltaManager。SimpleTcpCluster啟動membership服務和Replication服務。

---

extra/httpd-mpm.conf 模塊  

上邊一樣的就不貼了,主要是下邊的配置,因為我用了mod_security模塊,所以要做一些配置,這里不做解釋了,寫的很詳細,我比較喜歡在配置文件里把容易忘記的地方寫上文檔。畢竟這東西配完了就不再動了,很容易忘記

# WinNT MPM

# ThreadsPerChild: constant number of worker threads in the server process

# MaxRequestsPerChild: maximum  number of requests a server process serves

#注意:ThreadLimit指令應當放在ThreadsPerChild之前,否則ThreadsPerChild指令生效后ThreadLimit會失效,而導致不必要的錯誤 ThreadLimit必須大于等于ThreadsPerChild

#對于mpm_winnt,ThreadLimit的默認值是1920;對于其他MPM這個值是64

#ThreadLimit 這個指令設置了每個子進程可配置的線程數ThreadsPerChild上限。任何在重啟期間對這個指令的改變都將被忽略,但對ThreadsPerChild的修改卻會生效。

#ThreadLimit 使用這個指令時要特別當心。如果將ThreadLimit設置成一個高出ThreadsPerChild實際需要很多的值,將會有過多的共享內存被分配。

#如果將ThreadLimit和ThreadsPerChild設置成超過系統的處理能力,Apache可能無法啟動,或者系統將變得不穩定。該指令的值應當和ThreadsPerChild大致保持一致

#ThreadsPerChild 每個子進程建立的常駐的執行線程數。默認值是25。子進程在啟動時建立這些線程后就不再建立新的線程了。

<IfModule mpm_winnt_module>

    ThreadLimit            2000

    ThreadsPerChild        2000

    MaxRequestsPerChild    2000

</IfModule>



瘋狂 2011-02-15 10:37 發表評論
]]>
stuts2 返回xmlhttp://www.aygfsteel.com/freeman1984/archive/2010/09/17/332278.html瘋狂瘋狂Fri, 17 Sep 2010 03:13:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2010/09/17/332278.htmlhttp://www.aygfsteel.com/freeman1984/comments/332278.htmlhttp://www.aygfsteel.com/freeman1984/archive/2010/09/17/332278.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/332278.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/332278.html關于Struts2 返回XML的問題

1. Action其實是一個POJO,所以我們可以直接把Action生成一個XML.只要把Result Type設為xslt就可以了:
      <action name="XmlModel" class="cpu.XmlModelAction">
            <result name="success" type="xslt" />
      </action>
里面包含了Action的所有屬性,還有Locale等信息. 可以在瀏覽器里輸入http://localhost:8080/XXX/XXX/XmlModel.action來看.

2. 為了定制自己想要的XML,我們可以輸入參數來輸出自己想要的Action的某個屬性(屬性可以是一個List).
      <action name="XmlModel" class="cpu.XmlModelAction">
            <result name="success" type="xslt">
                  <param name=”exposedValue”>modelList</param>
            </result>
      </action>

3. 如果有多于一個屬性呢.加個大括號圍起來
      <action name="XmlModel" class="cpu.XmlModelAction">
            <result name="success" type="xslt">
                  <param name=”exposedValue”>{modelList, type}</param>
            </result>
      </action>

4. 以上三個方法都是由Action 來控制生成格式.那么對于我們這種控制欲很強的人來說并不滿足,最好是由我們自己來定義生成樣子.那么這時我們就要做的就是在屬性里生成一個 org.w3c.dom.Document屬性.注意:不要用org.dom4j.Document類.要不會出現轉化錯誤,死得很慘.
      <action name="XmlModel" class="cpu.XmlModelAction">
      <result name="success" type="xslt">
            <param name="exposedValue">xmlDoc</param>
      </result>
      </action>
上面的xmlDoc就是 Action里的org.w3c.dom.Document類型.

5. 我只會用并且非要用org.dom4j.Document類怎么辦? 那就在最后轉化成 org.w3c.dom.Document:
Java代碼 復制代碼
  1. import java.io.ByteArrayInputStream;     
  2. import java.io.IOException;     
  3.       
  4. import javax.xml.parsers.DocumentBuilderFactory;     
  5. import javax.xml.parsers.ParserConfigurationException;     
  6.       
  7. import org.xml.sax.SAXException;     
  8.       
  9. public class XmlUtil {     
  10.      
  11.       private XmlUtil() {     
  12.       }     
  13.       
  14.       public static org.w3c.dom.Document XmlString2W3cDom(String xml)     
  15.                   throws SAXException, IOException, ParserConfigurationException {     
  16.             byte[] byteArray = xml.getBytes("UTF-8");     
  17.             ByteArrayInputStream baos = new ByteArrayInputStream(byteArray);     
  18.             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();     
  19.             org.w3c.dom.Document doc = factory.newDocumentBuilder().parse(baos);     
  20.             return doc;     
  21.       }     
  22.       
  23.       public static org.dom4j.Document W3c2Dom4j(org.w3c.dom.Document doc) {     
  24.             if (doc == null) {     
  25.                  return (null);     
  26.             }     
  27.             org.dom4j.io.DOMReader xmlReader = new org.dom4j.io.DOMReader();     
  28.             return (xmlReader.read(doc));     
  29.       }     
  30.       
  31. }     

Action里加上一句: xmlDoc = Xmlutil.XmlString2W3cDom(dom4jDoc.asXML());
上面的xmlDoc就是 Action里的org.w3c.dom.Document類型.

6. 用org.dom4j.dom.DOMDocumentFactory()來建立 Document.而不要用DocumentHelper.createDocument()來產生.最后直接cast一下.
 
public String execute() throws UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException {     
  1.   InfoCpuService cpuSvc = null;     
  2.   cpuSvc = (InfoCpuService) ServiceLocator.getInstance().getService(InfoCpuService.class);     
  3.       
  4.   modelList = cpuSvc.getModels(prodBrand);     
  5.       
  6.   log.info(ReflectionToStringBuilder.toString(this));     
  7.      
  8.  org.dom4j.Document dom4jDoc = new org.dom4j.dom.DOMDocumentFactory().createDocument();     
  9.     
  10.                Element root = dom4jDoc.addElement("root");     
  11.  root.addAttribute("prodType""CPU");     
  12.     
  13. for (Object o : modelList) {     
  14.   root.addElement("model").addAttribute("name", (String) o);     
  15.  }     
  16.      
  17. //xmlDoc = XmlUtil.XmlString2W3cDom(doc.asXML());     
  18.  xmlDoc = (Document) dom4jDoc;     
  19.      
  20.   HttpServletResponse response = ServletActionContext.getResponse();     
  21.   response.setContentType("text/xml;charset=UTF-8");     
  22.   response.setHeader("Cache-Control""no-cache");     
  23.        
  24.  return SUCCESS;     
  25.     

其中三句代碼是為了防止生成中文亂碼
   HttpServletResponse response = ServletActionContext.getResponse();
   response.setContentType("text/xml;charset=UTF-8");
   response.setHeader("Cache-Control", "no-cache");

7. 在action中返回類型最好設置為import org.w3c.dom.Document;
private Document retXML;  

配置格式為:
Java代碼
  1. <action name="XmlModel" class="com.XmlModelAction">   
  2.            <result name="success" type="xslt">   
  3.                  <param name=”exposedValue”>retXML</param>   
  4.            </result>   
  5.  </action>  
轉自:http://skyful.javaeye.com/blog/505775

瘋狂 2010-09-17 11:13 發表評論
]]>
tomcat userhttp://www.aygfsteel.com/freeman1984/archive/2010/09/17/332276.html瘋狂瘋狂Fri, 17 Sep 2010 03:11:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2010/09/17/332276.htmlhttp://www.aygfsteel.com/freeman1984/comments/332276.htmlhttp://www.aygfsteel.com/freeman1984/archive/2010/09/17/332276.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/332276.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/332276.htmlTomcat的配置

  Tomcat的主要配置文件有3個,分別是Tomcat-users.xml、web.xml和server.xml。它先前的版本采用了和Apache一樣的conf文本文件。這樣的文本文件對于初學者是一種很大的挑戰。但現在它采用了比較通用的XML文件格式,這是一種向著開放性、標準性的轉變。下面分別對3個文件進行說明。

配置Tomcat-users.xml

  該文件包含了所有Tomcat服務器的注冊用戶,其中有role(角色)、user(用戶)兩種信息。下面列舉出這個XML文件的部分內容。

<?xml version='1.0' encoding='utf-8'?>
            <Tomcat-users>
            <role rolename="Tomcat"/>
            <user username="Tomcat" password="Tomcat" roles="Tomcat,admin"/>
            </Tomcat-users>


  1.role參數

  Tomcat中保存了一些用戶權限,也就是角色,比如admin、Tomcat等。用戶還可以自定義,通過""來注冊一個角色。它只有rolename一個屬性,通過這個屬性可以把用戶的權限進行分配。

  2.User參數

這個數據項中包含了諸如用戶名、用戶密碼、用戶權限、用戶說明等數據屬性。通過下面的這個例子講解。

<user username="wudi" password="wudi" fullName="test"
            roles="admin,manager,role1,Tomcat"/>


  這個語句建立了一個用戶,用戶名是"wudi",密碼也是"wudi"。這個用戶的全稱是"test"。"wudi"這個用戶擁有的權限是admin、manager、role1、Tomcat。這些用戶權限是Tomcat系統默認的。在這里有一些需要聲明,Tomcat的系統管理員必須有admin的用戶權限,否則無法登陸Tomcat的管理界面。


瘋狂 2010-09-17 11:11 發表評論
]]>
Apache Harmonyhttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331049.html瘋狂瘋狂Sat, 04 Sep 2010 10:13:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331049.htmlhttp://www.aygfsteel.com/freeman1984/comments/331049.htmlhttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331049.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/331049.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/331049.html

Apache Harmony 是 2005 年 5 月宣布的開放源碼 Java SE 實現,本文是由 5 部分組成的 進入 Harmony 世界 系列文章的第一篇,這個系列主要介紹 Apache Harmony 項目的內部實現,最新發展現狀和開源 Java 開發的模式,并鼓勵和歡迎大家參與到 Harmony 的社區中來。本文是 5 個系列的第一篇,概括介紹了 Harmony 項目的背景,技術架構,社區運作和未來的方向。

本文是 5 個系列的第一篇,概括介紹了 Harmony 項目的背景,技術架構,社區運作和未來的方向。

Apache Harmony 的背景

Apache Harmony 的提案在 2005 年 5 月被 Apache 軟件基金會(ASF)接受,并且按照 ASF 慣例成為一個孵化器(incubator)項目。

Harmony 為自己定了兩個目標,首先是開發出一個獨立并且與現有 JDK 兼容的 Java SE 5 實現,并且以 Apache 軟件許可證 2.0 版發行;其次是建立一個開放的模塊化運行時架構,包括虛擬機和類庫之間及其內部的模塊化,并通過這個平臺,允許社區在此基礎上自由定制自己的 Java 實現,或者對某個模塊單獨進行創新。

Apache Harmony 項目的成立以及它的這兩個目標具有很大的現實意義。首先,由于商業JDK的流行性,它們幾乎成為事實上的標準,所以 Harmony 必須與它們保持高度的兼容,才能夠使應用程序的遷移成本最低,也就相對容易被用戶所接受;其次,Harmony 存在的重要意義之一就在于這是一個屬于開源社區的 Java 平臺,在這個平臺上,社區可以自由的移植和創新,而一個開放的模塊化的架構,將為移植和創新帶來最大的便利性;最后,Apache 軟件許可證是一個對商業公司和開源社區都比較友好的開源許可證,因此 Harmony 可以給最大范圍的開發人員和用戶帶來便利。本文和本系列后續文章將詳細介紹 Harmony 在兼容性和模塊化方面的努力,以及這些目標帶來的價值。

也許正是基于以上一些原因,Harmony 項目成立僅僅一年多一點的時間,就得到了廣泛的支持和關注,并且得以飛速發展。目前,Apache Harmony 已經擁有了一個活躍的開發社區,并且接受了來自公司,學校和個人的多次捐贈。IBM 在 developerWorks 上提供了一個 Java 虛擬機環境的免費下載,以支持 Harmony 項目的開發,還多次捐贈了核心類庫的實現和測試代碼,在 IBM 英國 Hursley 軟件開發實驗室和中國軟件開發中心各有一個開發團隊積極參與 Harmony 項目。此外 Harmony 項目還接受了三個 Java 虛擬機實現的捐贈,另外還有一個開源 Java 虛擬機 SableVM 正在積極的與 Harmony 社區合作以實現與 Harmony 類庫的集成。Java SE 實現難度最大的是其規模龐大的類庫,而最近的類庫 API 覆蓋率統計表明,Harmony 的 J2SE 1.4.2 類庫 API 的覆蓋率已經超過 80%,Java SE 5 的覆蓋率已經達到 79% 以上。目前經不完全測試,在 Harmony 上已經可以良好運行 Eclipse、JEdit、Ant 等流行的 Java 工具,并且可以部分運行 Tomcat 和 Geronimo 等企業應用。




 

技術架構

如前所述,Apache Harmony 非常注重模塊化,從圖一中,可以對 Apache Harmony 的總體架構有一個初步的感覺。與所有其他 Java SE 實現類似的是,Harmony 從大體上可以分為三個層次,最下層是操作系統,中間是 Java 虛擬機,最上層是 Java 類庫。而 Harmony 的特點在于:

  • 虛擬機和類庫內部被高度模塊化,在 Harmony 中,類庫在功能和 Java Package 的基礎上被分成 31 個模塊,而虛擬機也被分成即時編譯器, 內存管理, 線程管理,Java 本地接口等等模塊。每個模塊都有一定的接口定義,從而有可能單獨被替換成不同的實現。
  • 操作系統層次與虛擬機層次之間的接口由 Port Layer 定義。Port Layer 封裝了不同的操作系統的差異,為虛擬機和類庫的本地代碼提供了一套統一的 API 訪問底層系統調用。
  • 虛擬機與類庫之間的接口除了 Java 規范定義的 JNI,JVMITI 之外,加入了一層虛擬機接口,主要由內核類(Kernel Class)和本地代碼 VMI 組成,實現了虛擬機接口的虛擬機實現都可以使用 Harmony 的類庫實現,并且可以被 Harmony 提供的同一個 Java 啟動程序啟動。


圖一 Apache Harmony 技術架構鳥瞰圖
圖一 Apache Harmony 技術架構鳥瞰圖

本節將分別對 Port Layer,VMI 和 Java 統一啟動程序作進一步的介紹。

Apache Harmony Port Layer

Apache Harmony 在操作系統與虛擬機之間定義了一個 Port Layer,Port Layer 是由一個標準 C 的庫(Port Library)來實現得,Port Library 與操作系統交互,為虛擬機和類庫的本地代碼提供了一個平臺無關的標準 C 語言 API 訪問系統調用。諸如文件 I/O,網絡 I/O, 內存操作,信號處理,以及錯誤處理等等功能,都被納入 Port Library 的范圍。

通過使用 Port Library, 所有(目前還沒有做到,但這是設計目標)與操作系統平臺相關的內容被封裝在一個庫里面,虛擬機和類庫的其他部分都可以盡可能以平臺無關的方式實現出來。這樣一來,將 Java SE 的龐大類庫和虛擬機代碼移植到其他操作系統的工作就可以被快速的開發出來,從而大大提高了可移植性和程序的可維護性。

在 Apache 軟件基金會資助的開源項目中,有一個類似的平臺無關庫叫做 Apache Portable Runtime(APR), 這個項目是從 Apache Http Server 等項目的開發過程中提煉和分離出來的,目前已經比較成熟,它與 Harmony 的 Port Layer 的目標有類似之處,但是也有明顯的不同,從而使得目前 APR 還不適合作為 Java 虛擬機和類庫的平臺無關庫實現。在本系列后續文章中會有單獨的文章詳細介紹 Harmony Port Library 的設計特點,并與 APR 進行比較。

Apache Harmony 虛擬機接口

Apache Harmony 虛擬機接口定義了類庫和虛擬機之間的接口,Java 規范已經定義了一些虛擬機的 API,比如 Java 本地接口(JNI), Java 虛擬機工具接口(JVMTI)等,但是 Java 規范并沒有定義類庫和虛擬機之間的接口。Harmony 為了模塊化和可移植性的要求,定義了虛擬機接口(VMI),只要是實現了該接口的虛擬機就是 Harmony 兼容虛擬機,從而可以與 Harmony 的類庫實現互操作,并且可以與 Harmony 提供的 Java 啟動程序協作。

Apache Harmony 虛擬機接口分為三個部分,一部分是 Java 語言接口,由 23 個內核類(Kernel Class)組成,另一部分是 C 語言接口,由 10 個函數組成,最后一部分就是標準 JNI。

  • 內核類的提出是因為少數核心的公共類是與虛擬機密切相關(VM-specific)的,它們都是屬于 java.lang,java.lang.ref,java.lang.reflect 和 java.security 等幾個核心的包,比如說 java.lang.ClassLoader, java.lang.ref.WeakReference 等。隨著 Java 版本的升級,核心類的數量也可能會增加。Harmony 的類庫實現為大多數核心類定義了實現模板。VM 的開發人員可以從零開始實現這些核心類,也可以在 Harmony 提供的模板基礎上開始開發。
  • 虛擬機接口還定義了 VM 必須實現的 10 個 C 函數,用來訪問虛擬機和類庫共享的數據結構和接口,比如說訪問操作系統抽象庫(Port Library),虛擬機本地存儲空間等。
  • 虛擬機的最后一部分就是標準 JNI,它在這里的主要用途是允許從 Java 類庫的本地鏈接庫中創建 Java 對象。

應該說虛擬機接口是一個相對寬松的接口,它并不要求對虛擬機和類庫特殊的耦合,對垃圾收集,同步和對象的數據結構等等也沒有特殊的規定。另外一個著名的開源 Java SE 類庫 GNU Classpath 也有類似的虛擬機接口,本系列后續文章將詳細介紹 Harmony VMI,并且與 GNU Classpath 比較。

Apache Harmony 啟動程序

Apache Harmony 提供了一個啟動程序,也就是通常我們用來運行 Java 程序的 java 和 javaw 命令的實現,這個啟動程序是個多目標的啟動器,可以根據命令行參數啟動不同的虛擬機,也可以支持虛擬機特有的選項,如屬性文件或命令行參數等。這一切都是基于虛擬機接口,Port Library 和標準 JNI 實現的。

在進一步介紹啟動程序之前,需要先介紹一下 Harmony Development Kit(HDK)和 Harmony JRE 的目錄結構,請參考圖二。HDK 是一個完整的開發包,不僅僅包括 Harmony 用戶所需的所有內容,也提供 Harmony 開發人員所有的靜態鏈接庫和頭文件,使得他們可以在此基礎上對其中任何一部分進行修改和重新構建。

  • <hdkbase>/jdk/jre, 這個目錄包含了標準的 JRE 結構,如 bin 和 lib 目錄等。
  • <hdkbase>/jdk/include,這個目錄包含了標準的 JDK 頭文件,如 jni.h 等。
  • <hdkbase>/include, 這個目錄包含了 Harmony 獨有的并且被多個模塊共享的頭文件
  • <hdkbase>/lib, 這個目錄包含了編譯 Harmony 本地代碼所需的靜態鏈接庫文件,如在 Windows 平臺,就包含了 .lib 文件,而在 Linux 平臺,則包含了 .a 文件。

對于啟動程序來說,需要特別注意的是 <hdkbase>/jdk/jre/bin 目錄,在這里可以包含多個虛擬機實現,每一個實現應該被放在該目錄的一個子路徑里(比如 vm1, vm2 等),缺省的虛擬機實現在 <hdkbase>/jdk/jre/bin/default 目錄,如果不指定特定參數,該虛擬機會被啟動程序使用。一般來講,每個虛擬機實現應該包含虛擬機實現文件和資源文件,尤其是必須有三個部分的虛擬機接口的實現。


圖二 HDK 目錄結構
圖二 HDK 目錄結構

在調用啟動程序的時候,有兩個參數被用來指定啟動哪一個虛擬機實現,-vmdir 用來指定虛擬機所在的子目錄,-vm 用來指定實現了JNI接口的動態鏈接庫,比如要使用 IBM 提供的 VME,而 VME 放在 vm1 目錄下的話,啟動程序的命令行就應該像:


		java -vmdir:vm1 -vm :clearvm.dll …
            

Harmony 的啟動程序在啟動時將執行以下任務:

  • 生成一個 Port Library 實例并且裝載它
  • 裝載虛擬機本地動態鏈接庫
  • 初始化內核類
  • 調用 JNI_CreateJavaVM(…), main(…), JarRunner 等

Apache Harmony 類庫的模塊化

Apache Harmony 將類庫分成易于管理的模塊,這樣做的目的是

  • 使 Java 類庫的開發工作易于管理,開源社區的參與者可以集中開發他擅長的模塊
  • 方便模塊裝配, 用戶可以自由選擇模塊提供者,可以自由替換或者升級任一模塊
  • 使法律方面的風險易于管理,如果開發人員以前接觸過其他 Java SE 實現的代碼,他也可以參與以前未接觸過的模塊開發。
  • 方便代碼捐獻

類庫的模塊實際上是由一組實現相關的功能的 Java 類和本地程序組成的,目前它們按照包的級別來劃分,也就是說不會有兩個屬于同一個 Java package 的類出現在兩個不同的模塊里(內核類所在的包除外,但也僅在內核類模塊和另一個類庫模塊中出現)。這些模塊可以包含私有的內部實現,但是必須導出 Java API 參考文檔規定標準 API,也可以導出 Harmony 獨有的 API,但是這些 API 并不鼓勵用戶使用,只是供其他模塊調用的。

模塊的鑒別方法是: 首先根據 Java 規范,確定各 Java 包之間的依賴關系;然后尋找弱耦合的部分,將本身內聚的包組織在一起,最后在社區討論哪部分類庫應該可以拆開獨立成一個模塊。目前 Harmony 將 Java SE 5 規定的類庫分成了三十一個模塊,在 Java 升級之后,模塊的數量可能會增加。目前這三十一個模塊包括:

  • ACCESSIBILITY
  • ANNOTATION
  • APPLET
  • ARCHIVE
  • AUTH
  • AWT
  • BEANS
  • CONCURRENT
  • CRYPTO
  • IMAGEIO
  • INSTRUMENT
  • JMX
  • JNDI
  • LANG-MANAGEMENT
  • LOGGING
  • LUNI (lang, util, net, io)
  • MATH
  • NIO-CHANNELS
  • NIO-CHARSET
  • ORB
  • PREFS
  • PRINT
  • REGEX
  • RMI
  • SECURITY
  • SOUND
  • SQL
  • SWING
  • TEXT
  • X-NET
  • XML

在 Harmony 的代碼資源庫中,每個模塊的源文件都保存在自己的各自的路徑中,如果使用 Eclipse 做開發工具,每個模塊就可以看作一個單獨的工程項目。特別需要注意的是,按照 jar 文件的規范,在每個模塊都有一個 META-INF/manifest.mf 文件,在這個文件中定義了該模塊的 OSGI 元數據,其中最重要的就是該模塊導入導出的 Java package。


Manifest-Version: 1.0
            Bundle-ManifestVersion: 2
            Bundle-Name: Harmony NIO
            Bundle-SymbolicName: org.apache.harmony.nio
            Bundle-Version: 1.0.0
            Bundle-ClassPath: .
            Eclipse-JREBundle: true
            Import-Package: java.io,
            java.lang,
            java.lang.ref,
            java.lang.reflect,
            java.net,
            java.nio.charset,
            java.security,
            java.util,
            org.apache.harmony.kernel.vm,
            org.apache.harmony.luni.net,
            org.apache.harmony.luni.platform,
            org.apache.harmony.luni.util,
            tests.support;hy_usage=test;resolution:=optional,
            tests.util;hy_usage=test;resolution:=optional
            Export-Package: java.nio,
            java.nio.channels,
            java.nio.channels.spi,
            org.apache.harmony.nio
            

在編譯之后,每一個模塊將被打包成一個 jar 文件,如果該模塊有本地代碼,則該模塊的本地代碼被編譯成一個單獨的動態鏈接庫文件。如圖二所示,hyluni.dll 就是 LUNI(lang, util, net, io)模塊的本地二進制代碼庫,而在 <hdkbase>/jdk/jre/lib/boot 目錄中,對應 LUNI 模塊的則有一個 luni.jar。




 

Apache Harmony 的開發方法

近年來,開源軟件相關的知識產權問題越來越受到關注。為了保證對知識產權的尊重,保持 Harmony 代碼的純潔性和原創性,除了 Apache 軟件基金會原有的通用規則之外,Harmony 開發社區花了很大的精力來定義 Harmony 接受代碼捐贈和接受項目參與者的規則。

Harmony 要求每個開發人員在參與代碼捐贈之前,必須完成一個問卷調查,問卷的主要內容是關于該開發人員以前是否接觸過其他 Java SE 實現,如果他接觸過其他專有代碼的某一部分,他就不能參與 Harmony 相應模塊的代碼工作(但也有一些特殊的例外情況)。同時,任何現有代碼的捐贈必須提供代碼的"血統"信息。

知識產權之外的另一個重要問題就是兼容性。Harmony 的目標產生一個 Java SE 5 兼容的實現,它不僅僅要完全遵循 Java API 參考定義的 Java SE 規范,Java 語言規范以及 Java 虛擬機規范;同時還必須保證與現有 Java SE 參考實現的兼容性,為此,Harmony 采用了測試驅動開發模式,以單元測試用例來保證 Harmony 的行為和參考實現一致。最重要的是,Harmony 正在試圖申請 Java SE 5 JCK 兼容性測試的許可證,因為只有被 JCK 認證過,Harmony 才能正式被稱為 Java 兼容的實現。

除了單元測試之外,Harmony 還會通過一些已有的成熟的 Java 程序來作為黑盒測試的應用,測試 Harmony 是否已經可以支持這些應用。目前 Harmony 可以運行 Eclipse,Tomcat,JEdit 等 Java 程序。Harmony 提供了一個工具,鼓勵 Java 程序作者將他們的程序運行在 Harmony 上,并且通過這個工具將運行結果反饋給 Harmony 開發社區。

總的來說,Harmony 采用以下幾種方式來衡量開發進度:

  • 粗粒度層次上,可以衡量一個模塊是否已經開發。
  • 使用工具比較 Harmony 和參考實現兼容性,比如使用 JAPI 檢測 Harmony 的 API 覆蓋率。
  • 使用工具檢查測試覆蓋率,檢查 Harmony 的各種行為是否得到充分的測試。
  • 支持成熟的 Java 應用程序列表。
  • 將來的目標是通過 JCK 測試。

本系列后續文章將進一步介紹 Harmony 開發中的最佳實踐。



Apache Harmony 未來的發展方向

Harmony 的一個重要目標是類庫的模塊化。Harmony 將進一步采用 OSGi 運行時框架技術,根據模塊元數據描述,自動裝載模塊。并且還將努力實現以下目標:

  • 允許同時裝載同一模塊的不同版本。
  • 通過模塊的 MANIFEST.MF 元數據文件控制其所包含的 Java package 的可見性。
  • Java 類和相應的本地代碼的啟動/停止/卸載等生命周期管理。


你能為 Harmony 做些什么

目前 Harmony 已經建立了一個相當活躍的開發社區,并且非常歡迎更多的人參與進來,包括參與 Harmony 的開發,移植 Harmony 到其他平臺(目前 Harmony 只有 IA32 的 Windows 和 Linux 版本),撰寫文檔,在 Harmony 上運行成熟的 Java 應用檢查其實現的覆蓋率和兼容性等等。除此之外,同樣重要的是,你還可以參與遠未成熟的 Harmony 用戶社區,試用 Harmony,參與 Harmony 的討論,等等。Harmony 是一個屬于所有人的 Java 平臺。

總結

  • Harmony 的目標是一個完全兼容的開源的 JSE 實現
  • Harmony 投入巨大的努力保證知識產權的純潔性
  • Harmony 社區的目標是創建一個一流的模塊化的運行時環境
  • Harmony 在過去的一年中取得了巨大的成就
  • Harmony 歡迎任何有興趣的開發者

 

轉載自 ibm dw http://www.ibm.com/developerworks/cn/java/j-lo-harmony1/



瘋狂 2010-09-04 18:13 發表評論
]]>
apache Regexphttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331048.html瘋狂瘋狂Sat, 04 Sep 2010 09:57:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331048.htmlhttp://www.aygfsteel.com/freeman1984/comments/331048.htmlhttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331048.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/331048.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/331048.html Regexp是一個由100%純java正則式處理包,是Jonathan Locke捐給Apache軟件基金會的。 他最初開發這個軟件是在1996年, 它包括完整的Javadoc文檔,以及一個簡單的Applet來做可視化調試和兼容性測試.

2)RE類regexp包中非常重要的一個類,它是一個高效的、輕量級的正則式計算器/匹配器的類,RE是regular expression的縮寫。正則式是能夠進行復雜的字符串匹配的模板,而且當一個字符串能匹配某個模板時,你可 以抽取出那些匹配的部分,這在進行文本解析時非常有用。下面討論一下正則式的語法。
  為了編譯一個正則式,你需要簡單地以模板為參數構造一個RE匹配器對象來完成,然后就可調用任一個 RE.match方法來對一個字符串進行匹配檢查,如果匹配成功/失敗,則返回真/假值。例如:

RE r = new RE("a*b");
boolean matched = r.match("aaaab");

  RE.getParen可以取回匹配的字符序列,或者匹配的字符序列的某一部分(如果模板中有相應的括號的 話),以及它們的位置、長度等屬性。如:

RE r = new RE("(a*)b"); // Compile expression
boolean matched = r.match("xaaaab"); // Match against "xaaaab"

String wholeExpr = r.getParen(0); // wholeExpr will be 'aaaab'
String insideParens = r.getParen(1); // insideParens will be 'aaaa'

int startWholeExpr = r.getParenStart(0); // startWholeExpr will be index 1
int endWholeExpr = r.getParenEnd(0); // endWholeExpr will be index 6
int lenWholeExpr = r.getParenLength(0); // lenWholeExpr will be 5

int startInside = r.getParenStart(1); // startInside will be index 1
int endInside = r.getParenEnd(1); // endInside will be index 5
int lenInside = r.getParenLength(1); // lenInside will be 4


  RE支持正則式的后向引用,如:

([0-9]+)=\1
匹配 n=n (象 0=0 or 2=2)這樣的字符串

3)RE支持的正則式的語法如下:
字符
unicodeChar  Matches any identical unicode character
\  Used to quote a meta-character (like '*')
\\  Matches a single '\' character
\0nnn  Matches a given octal character
\xhh  Matches a given 8-bit hexadecimal character
\\uhhhh  Matches a given 16-bit hexadecimal character
\t  Matches an ASCII tab character
\n  Matches an ASCII newline character
\r  Matches an ASCII return character
\f  Matches an ASCII form feed character

字符集
[abc]  簡單字符集
[a-zA-Z]  帶區間的 字符集
[^abc]  字符集的否定

標準POSIX 字符集
[:alnum:]  Alphanumeric characters.
[:alpha:]  Alphabetic characters.
[:blank:]  Space and tab characters.
[:cntrl:]  Control characters.
[:digit:]  Numeric characters.
[:graph:]  Characters that are printable and are also visible.(A space is printable, but not visible, while an `a' is both.)
[:lower:]  Lower-case alphabetic characters.
[:print:]  Printable characters (characters that are not control characters.)
[:punct:]  Punctuation characters (characters that are not letter,digits, control characters, or space characters).
[:space:]  Space characters (such as space, tab, and formfeed, to name a few).
[:upper:]  Upper-case alphabetic characters.
[:xdigit:]  Characters that are hexadecimal digits.

非標準的 POSIX樣式的字符集
[:javastart:]  Start of a Java identifier
[:javapart:]  Part of a Java identifier

預定義的字符集
.  Matches any character other than newline
\w  Matches a "word" character (alphanumeric plus "_")
\W  Matches a non-word character
\s  Matches a whitespace character
\S  Matches a non-whitespace character
\d  Matches a digit character
\D  Matches a non-digit character

邊界匹配符
^  Matches only at the beginning of a line
$  Matches only at the end of a line
\b  Matches only at a word boundary
\B  Matches only at a non-word boundary

貪婪匹配限定符
A*  Matches A 0 or more times (greedy)
A+  Matches A 1 or more times (greedy)
A?  Matches A 1 or 0 times (greedy)
A{n}  Matches A exactly n times (greedy)
A{n,}  Matches A at least n times (greedy)

非貪婪匹配限定符
A*?  Matches A 0 or more times (reluctant)
A+?  Matches A 1 or more times (reluctant)
A??  Matches A 0 or 1 times (reluctant)

邏輯運算符
AB  Matches A followed by B
A|B  Matches either A or B
(A)  Used for subexpression grouping
(?:A)  Used for subexpression clustering (just like grouping but no backrefs)

后向引用符
\1  Backreference to 1st parenthesized subexpression
\2  Backreference to 2nd parenthesized subexpression
\3  Backreference to 3rd parenthesized subexpression
\4  Backreference to 4th parenthesized subexpression
\5  Backreference to 5th parenthesized subexpression
\6  Backreference to 6th parenthesized subexpression
\7  Backreference to 7th parenthesized subexpression
\8  Backreference to 8th parenthesized subexpression
\9  Backreference to 9th parenthesized subexpression


RE運行的程序先經過RECompiler類的編譯. 由于效率的原因,RE匹配器沒有包括正則式的編譯類. 實際上, 如果要預編譯1個或多個正則式,可以通過命令行運行'recompile'類,如

java org.apache.regexp.recompile a*b
則產生類似下面的編譯輸出(最后一行不是):

// Pre-compiled regular expression "a*b"
char[] re1Instructions =
{
0x007c, 0x0000, 0x001a, 0x007c, 0x0000, 0x000d, 0x0041,
0x0001, 0x0004, 0x0061, 0x007c, 0x0000, 0x0003, 0x0047,
0x0000, 0xfff6, 0x007c, 0x0000, 0x0003, 0x004e, 0x0000,
0x0003, 0x0041, 0x0001, 0x0004, 0x0062, 0x0045, 0x0000,
0x0000,
};
REProgram re1 = new REProgram(re1Instructions);
RE r = new RE(re1);

  通過利用預編譯的req來構建RE匹配器對象,可以避免運行時進行編譯的成本。 如果需要動態的構造正 則式,則可以創建單獨一個RECompiler對象,并利用它來編譯每個正則式。注意,RE 和 RECompiler 都不是 threadsafe的(出于效率的原因), 因此當多線程運行時,你需要為每個線程分別創建編譯器和匹配器。


3、例程

1)regexp包中帶有一個applet寫的小程序,運行如下:
java org.apache.regexp.REDemo
運行后:

2)Jeffer Hunter寫了一個例程,可以下載。
3)regexp自帶的測試例程,也很有參考價值。它把所有正則式及相關的字符串以及結果都放在一個單獨的文件 里,在$REGEXPHOME/docs/RETest.txt中。當然,這個例程的運行也要在$REGEXPHOME目錄下。
cd $REGEXPHOME
java org.apache.regexp.RETest

瘋狂 2010-09-04 17:57 發表評論
]]>
Apache commons簡介http://www.aygfsteel.com/freeman1984/archive/2010/09/04/331028.html瘋狂瘋狂Sat, 04 Sep 2010 03:57:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331028.htmlhttp://www.aygfsteel.com/freeman1984/comments/331028.htmlhttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331028.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/331028.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/331028.html作者Blog:http://blog.csdn.net/sswt/
 

Apache Commons是一個非常有用的工具包,解決各種實際的通用問題,下面是一個簡述表,詳細信息訪問http://jakarta.apache.org/commons/index.html

BeanUtils
Commons-BeanUtils 提供對 Java 反射和自省API的包裝

Betwixt
Betwixt提供將 JavaBean 映射至 XML 文檔,以及相反映射的服務.

Chain
Chain 提供實現組織復雜的處理流程的“責任鏈模式”.

CLI
CLI 提供針對命令行參數,選項,選項組,強制選項等的簡單API.

Codec
Codec 包含一些通用的編碼解碼算法。包括一些語音編碼器, Hex, Base64, 以及URL encoder.

Collections
Commons-Collections 提供一個類包來擴展和增加標準的 Java Collection框架

Configuration
Commons-Configuration 工具對各種各式的配置和參考文件提供讀取幫助.

Daemon
一種 unix-daemon-like java 代碼的替代機制

DBCP
Commons-DBCP 提供數據庫連接池服務

DbUtils
DbUtils 是一個 JDBC helper 類庫,完成數據庫任務的簡單的資源清除代碼.

Digester
Commons-Digester 是一個 XML-Java對象的映射工具,用于解析 XML配置文件.

Discovery
Commons-Discovery 提供工具來定位資源 (包括類) ,通過使用各種模式來映射服務/引用名稱和資源名稱。.

EL
Commons-EL 提供在JSP2.0規范中定義的EL表達式的解釋器.

FileUpload
FileUpload 使得在你可以在應用和Servlet中容易的加入強大和高性能的文件上傳能力

HttpClient
Commons-HttpClient 提供了可以工作于HTTP協議客戶端的一個框架.

IO
IO 是一個 I/O 工具集

Jelly
Jelly是一個基于 XML 的腳本和處理引擎。 Jelly 借鑒了 JSP 定指標簽,Velocity, Cocoon和Xdoclet中的腳本引擎的許多優點。Jelly 可以用在命令行, Ant 或者 Servlet之中。

Jexl
Jexl是一個表達式語言,通過借鑒來自于Velocity的經驗擴展了JSTL定義的表達式語言。.

JXPath
Commons-JXPath 提供了使用Xpath語法操縱符合Java類命名規范的 JavaBeans的工具。也支持 maps, DOM 和其他對象模型。.

Lang
Commons-Lang 提供了許多許多通用的工具類集,提供了一些java.lang中類的擴展功能

Latka
Commons-Latka 是一個HTTP 功能測試包,用于自動化的QA,驗收和衰減測試.

Launcher
Launcher 組件是一個交叉平臺的Java 應用載入器。 Commons-launcher 消除了需要批處理或者Shell腳本來載入Java 類。.原始的 Java 類來自于Jakarta Tomcat 4.0 項目

Logging
Commons-Logging 是一個各種 logging API實現的包裹類.

Math
Math 是一個輕量的,自包含的數學和統計組件,解決了許多非常通用但沒有及時出現在Java標準語言中的實踐問題.

Modeler
Commons-Modeler 提供了建模兼容JMX規范的 Mbean的機制.

Net
Net 是一個網絡工具集,基于 NetComponents 代碼,包括 FTP 客戶端等等。

Pool
Commons-Pool 提供了通用對象池接口,一個用于創建模塊化對象池的工具包,以及通常的對象池實現.

Primitives
Commons-Primitives提供了一個更小,更快和更易使用的對Java基本類型的支持。當前主要是針對基本類型的 collection。.

Validator
The commons-validator提供了一個簡單的,可擴展的框架來在一個XML文件中定義校驗器 (校驗方法)和校驗規則。支持校驗規則的和錯誤消息的國際化。



瘋狂 2010-09-04 11:57 發表評論
]]>
apache discoveryhttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331019.html瘋狂瘋狂Sat, 04 Sep 2010 03:34:00 GMThttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331019.htmlhttp://www.aygfsteel.com/freeman1984/comments/331019.htmlhttp://www.aygfsteel.com/freeman1984/archive/2010/09/04/331019.html#Feedback0http://www.aygfsteel.com/freeman1984/comments/commentRss/331019.htmlhttp://www.aygfsteel.com/freeman1984/services/trackbacks/331019.html轉載:http://terrencexu.javaeye.com/blog/715982

Discovery組件被用以查找可插拔接口的實現實例,它提供了一種通用的實例化這些實現的方式,而且可以管理單例(工廠)的生命周期。本質上來講,就是定位那些實現了給定Java接口的類,并實例化。除此之外,Discovery還可以用以在給定的classpath中查找并加載資源文件。

 

Discovery組件在查找所有的實現類的時候需要預先將允許被查找的實現類配置到默認的配置文件中,默認的配置文件為:

/META-INF/services/<YOUR Interface whole name including pkg name>, Discovery將依次加載該文件中配置的允許加載的實現類。

 

下面將舉例說明:

首先定義一個Interface:Action

Java代碼 復制代碼
  1. package com.javaeye.terrencexu.discovery;   
  2.   
  3. public interface Action {   
  4.   
  5.     public String getName();   
  6.        
  7. }  

 

然后在不同的包里分別實現Action接口,如下(請注意包名)

Java代碼 復制代碼
  1. package com.javaeye.terrencexu.discovery.impl;   
  2.   
  3. import com.javaeye.terrencexu.discovery.Action;   
  4.   
  5. public class CreateAction implements Action {   
  6.   
  7.     @Override  
  8.     public String getName() {   
  9.         return "Create Action";   
  10.     }   
  11.   
  12. }  

 

Java代碼 復制代碼
  1. package com.javaeye.terrencexu.discovery.impl;   
  2.   
  3. import com.javaeye.terrencexu.discovery.Action;   
  4.   
  5. public class DeleteAction implements Action {   
  6.   
  7.     @Override  
  8.     public String getName() {   
  9.         return "Delete Action";   
  10.     }   
  11.   
  12. }  

 

Java代碼 復制代碼
  1. package com.javaeye.terrencexu.discovery.impl2;   
  2.   
  3. import com.javaeye.terrencexu.discovery.Action;   
  4.   
  5. public class AddAction implements Action {   
  6.   
  7.     @Override  
  8.     public String getName() {   
  9.         return "Add Action";   
  10.     }   
  11.   
  12. }  

 

Java代碼 復制代碼
  1. package com.javaeye.terrencexu.discovery.impl2;   
  2.   
  3. import com.javaeye.terrencexu.discovery.Action;   
  4.   
  5. public class RemoveAction implements Action {   
  6.   
  7.     @Override  
  8.     public String getName() {   
  9.         return "Remove Action";   
  10.     }   
  11.   
  12. }  

 

接下來將定義配置文件,按序定義允許被加載的實現類,該文件默認存在位置為/META-INF/services/,文件名為com.javaeye.terrencexu.discovery.Action,文件內容如下:

Java代碼 復制代碼
  1. # Display in order   
  2.   
  3. com.javaeye.terrencexu.discovery.impl.CreateAction   
  4. com.javaeye.terrencexu.discovery.impl.DeleteAction   
  5. com.javaeye.terrencexu.discovery.impl2.AddAction  

 

這樣所有的準備材料就都已經齊全了,接下來可以驗證一把了,如下:

Java代碼 復制代碼
  1.  /**  
  2.  *  CreateAction/DeleteAction/AddAction have been defined in /META-INF/services/com.javaeye.terrencexu.discovery.Action  
  3.  *    
  4.  *  And the order is CreateAction > DeleteAction > AddAction  
  5.  */  
  6. @SuppressWarnings("unchecked")   
  7. public void testGetAllProviders() {   
  8.     String[] expectedResults = new String[] {"Create Action""Delete Action""Add Action"};   
  9.            
  10.     Enumeration<Action> enu = Service.providers(Action.class);   
  11.   
  12.     int count = 0;   
  13.     while (enu.hasMoreElements()) {   
  14.         Action action = enu.nextElement();   
  15.         assertTrue("The action name should be \"" + expectedResults[count] + "\", but actually is \"" + action.getName() + "\"",    
  16.                action.getName().equals(expectedResults[count]));   
  17.         count ++;   
  18.     }   
  19.            
  20.     assertEquals(count, expectedResults.length);   
  21. }  

 

可以發現,因為RemoveAction沒有被配置到service文件中,所以將不會被加載,另外一點兒就是,配置文件中的定義順序即加載順序。

 

除此之外,Discovery提供了singleton模式加載唯一實現,并且該實現將被緩存在cache中,除非通過顯示的調用release()方法釋放緩存,否則所有之后的調用,都將返回初次調用加載的Action。

Java代碼 復制代碼
  1. public void testFindCreateAction() {   
  2.     try {   
  3.         // Load provider com.javaeye.terrencexu.discovery.impl.CreateAction   
  4.         Action createAction = (Action) DiscoverSingleton.find(Action.class, CreateAction.class.getName());   
  5.         assertEquals("Create Action", createAction.getName());   
  6.     } finally {   
  7.         DiscoverSingleton.release();   
  8.     }   
  9. }  

 

 

還有一點需要說明的是,如果定義了默認的service文件,無論通過singleton模式加載的實現類有沒有被配置在service文件中,都將默認加載配置中文中的第一個Action,比如上文中的CreateAction。

Java代碼 復制代碼
  1. public void testFindDeleteActionInConfig() {   
  2.     try {   
  3.         // Load provider com.javaeye.terrencexu.discovery.impl.CreateAction   
  4.         Action deleteAction = (Action) DiscoverSingleton.find(Action.class, DeleteAction.class.getName());   
  5.            
  6.         // As the default configuration file defines the CreateAction as the first element, so you will always get the CreateAction as singleton.    
  7.         assertEquals("Create Action", deleteAction.getName());   
  8.     } finally {   
  9.         DiscoverSingleton.release();   
  10.     }   
  11. }  

 

那么如果必須使用service文件,又想通過singleton模式加載某特定的實現類該怎么辦呢?可以通過傳遞Properties到DiscoverSingleton中去改變它的行為,如下:

Java代碼 復制代碼
  1. public void testFindDeleteActionWithProperty() {   
  2.     try {   
  3.         Properties props = new Properties();   
  4.         props.setProperty(Action.class.getName(), DeleteAction.class.getName());   
  5.            
  6.         // Load provider com.javaeye.terrencexu.discovery.impl.CreateAction   
  7.         Action deleteAction = (Action) DiscoverSingleton.find(Action.class, props);   
  8.         assertEquals("Delete Action", deleteAction.getName());   
  9.     } finally {   
  10.         DiscoverSingleton.release();   
  11.     }   
  12. }  

 

除了加載類之外,很多情況下我們還想加載資源文件,比如在你的classpath下有一個配置文件為/conf/testResource,下面我們通過Discovery去加載該資源文件:

Java代碼 復制代碼
  1. public void testFindResources() {   
  2.     ClassLoaders loaders = new ClassLoaders();   
  3.     ClassLoader cl = getClass().getClassLoader();   
  4.     if(cl != null) {   
  5.         loaders.put(getClass().getClassLoader(), true);   
  6.     } else {   
  7.         loaders.put(JDKHooks.getJDKHooks().getSystemClassLoader(), true);   
  8.     }   
  9.        
  10.     String name = "conf/testResource";   
  11.     DiscoverResources discovery = new DiscoverResources(loaders);   
  12.     ResourceIterator iter = discovery.findResources(name);   
  13.        
  14.     while(iter.hasNext()) {   
  15.         Resource resource = iter.nextResource();   
  16.         URL url = resource.getResource();   
  17.         System.out.println(url);   
  18.     }   
  19. }  

 

Discovery還有其他一些功能這里就不在詳細的一一贅述了,可以參考http://commons.apache.org/discovery/index.html進一步詳細了解。

 

下圖是我的例子的目錄結構,僅供參考:


然后附件中有source code,僅供參考。


 



瘋狂 2010-09-04 11:34 發表評論
]]>
主站蜘蛛池模板: 北碚区| 遂平县| 西宁市| 库车县| 萨迦县| 开化县| 闸北区| 蒙城县| 罗源县| 新蔡县| 耿马| 工布江达县| 台安县| 桐梓县| 普兰县| 芒康县| 达孜县| 沾益县| 青河县| 太康县| 太仓市| 沙河市| 都江堰市| 北安市| 建德市| 广汉市| 醴陵市| 随州市| 和平区| 丹巴县| 瑞安市| 鹿邑县| 兰州市| 明光市| 修武县| 乃东县| 拉萨市| 澎湖县| 五峰| 柏乡县| 沙河市|