顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

星期日, 5月 17, 2009

JUnit 4.x初體驗

JUnit 4.x之後可使用Annotation, 因此已可將程式碼與測試程式碼混雜在同一個.java檔, 也不再需要extends TestCase, 但為了避免混亂, 還是將測試程式碼分開來比較好

建立測試程式的方式也很簡單, 使用Eclipse, 在想要撰寫測試程式碼的.java檔上按右鍵, 然後[New -> Other... -> Java -> JUnit -> JUnit Test Case]


選取JUnit 4, 要放置的路徑, 以及勾選一些希望自動產生的程式碼


勾選一些要測試的method

完成後就可以看到測試程式檔已經產生, 也帶有一些自動產生的method區塊並有著下列的Annotations之一

@BeforeClass => 產生class的實例之前呼叫, 為static method, 同一個測試class只會呼叫一次
@AfterClass => 銷毀class的實例之後呼叫, 為static method, 同一個測試class只會呼叫一次
@Before => 一個測試method會產生一個測試class實例, 因此每個測試method執行都會呼叫一次
@After => 一個測試method會產生一個測試class實例, 因此每個測試method執行都會呼叫一次
@Test => 測試method, 可以不用testXXX()當prefix, 但建議還是使用.

注意: 因為一個測試method會產生一個測試class實例, 因此若有變數需要在不同method之間傳遞, 要先將變數宣告為static才行.

要執行此測試程式的方法有兩個
  1. 在測試程式上按右鍵, [Run As -> JUnit Test]
  2. 在專案上按右鍵, [Run As -> JUnit Test], 這樣會執行這專案內所有的測試程式, 要注意!

星期五, 5月 15, 2009

將JMeter改為英文介面


JMeter若不設定的話, 會使用作業系統的預設語系, 一直看到那殘破不缺的中文, 實在是很令人扼腕, 而且時有時無的翻譯常常會讓人看不出所代表的是甚麼東西...

今天花了不少時間在玩弄JMeter, 雖然可以透過功能列來作語系的設定, 但總是會看到中英文夾雜的狀況, 而且每次重新啟動都要再修改一次, 終於忍不住將它改成啟動時就跑英文介面, Disable=不致能...真的很囧...


修改的方法很簡單.

[bin/jmeter.properties]
language=en

加上這行再重新啟動就可以囉.

慢慢上手後, 覺得真的不錯用, 雖然不像XXXrunner那麼強大, 但作為Web系統的功能測試已很足夠, 也可以做壓力測試, 功能選項中有Remote Start的選項, 雖然還沒研究要如何設定, 不過看來要做強度很大的分散式壓力測試也不是難事.

JMeter samplers include:

  • FTP Request
  • HTTP Request
  • JDBC Request
  • Java object request
  • LDAP Request
  • SOAP/XML-RPC Request
  • WebService (SOAP) Request

星期一, 5月 11, 2009

Hibernate設定連接池的問題

設定連接池時, 遇到兩個問題

1. Hibernate並未使用所設定的C3P0連接池, 出現下列訊息
INFO [org.hibernate.connection.DriverManagerConnectionProvider] - Using Hibernate built-in connection pool (not for production use!)

解決方法是在hibernate.cfg.xml裡面加入這行
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>


2. 連接池程式無法正確使用Log4J的錯誤訊息
log4j:WARN No appenders could be found for logger (com.mchange.v2.log.MLog).
log4j:WARN Please initialize the log4j system properly.

雖然說warning不是很要緊, 但是看到這樣的訊息還是讓我很想處理掉這個狀況.

解決方法很簡單, 在log4j.properties裡加入這行

log4j.logger.com.mchange.v2=INFO, A1

P.S. A1是我設定的appender

星期五, 5月 08, 2009

Hibernate初體驗

資料庫一向是我特別有興趣的部分, 但Hibernate卻一直沒好好研究與使用, 除了是對於自己既有技能的依賴, 另外也是不想因為framework而失去某些彈性. 但現在Hibernate支援了JPA(EJB3.0規格中的重點之一), 所以系統若需要分散式架構時也可以很容易的擴充, 另外JPA也可以使用在GAE上, 因此現在學習使用Hibernate可說是非常有利的時機點.

我先閱覽了 良葛格學習筆記, 受益良多, 也對於Hibernate有一個快速的認識 (這幾年來, 我應該是第四次看這個網站上的Hibernate介紹了, 站主真的很用心, 更新的也很快).

不過接下來的實作練習還是吃了不少苦頭, 因為
  • 我不喜歡重頭開始刻程式, 所以看到Hibernate Tool可以從資料庫反轉產生code就覺得非用不可
  • 我並不想認識原來的Hibernate, 也就是還需要*.hbm.xml的寫法
  • Hibernate的JPA實作包括 Annotations 和 EntityManager, 我並不清楚這兩者的關係以及與EJB的關聯性
  • 我也沒搞懂persistence.xml 和 hibernate.cfg.xmlx兩者的關係以及與EJB的關聯性, 連要放哪個目錄下都不知道
  • 一堆相依的libraries也沒搞懂
  • 因為需求的關係, 目前我只想使用Tomcat, 並不想使用JBoss/ Glassfish
  • 我不想使用command line來跑Ant之類的東西, 一心只想使用Eclipse來操作
  • 我甚至也不知道Hibernate可以不在AP server/ Web server跑, 哈哈
  • 我一向沒看完使用者手冊的習慣... 真糟糕的習慣...
綜合以上就讓我吃足了苦頭, 雖然後來都搞清楚了, 也發現在良葛格學習筆記中其實大部分都已說得很清楚, 不過這樣try-error的過程中也算是快速累積經驗吧, 哈哈...

另外試著跑自己想要的SQL statement和子查詢, 結果也是ok的.

初體驗的結論是, 目前看來一切都很不錯. 要繼續深入研究下去囉!

星期一, 5月 04, 2009

關於GAE中用來儲存資料的兩個標準 (JDO, JPA)

話說昨天看了一下GAE的說明得知, 若要在GAE上儲存資料必須要使用JDO或JPA這兩種技術... 但是其實這兩種技術我都不會, 哈哈~ 一直都還在用很老舊的架構 Session Bean <-> DAO <-> JDBC <-> DB, 因為我喜歡使用很華麗的SQL statement來提高資料存取的速度, 曾經我也使用過Entity Bean來開發J2EE的系統, 那根本是場災難... 也造成我一直對於所謂的frameworks有點敬而遠之 (Struts, Webwork, Spring, Hibernate... etc), 且也不希望增加版本更新的困擾 (光Tomcat要不要upgrade都可以讓我考慮好幾天), 因此都只有大概看看文件, 了解一下這些frameworks存在的必要性而已.

Anyway, 在GAE上儲存資料必須要使用JDO或JPA這兩種標準, 所以我今天花了點時間研究一下, Google上是採用 Datanucleus的solution, 但這時還不曉得這個solution是甚麼, 接著上網查到 http://en.wikipedia.org/wiki/Datanucleus中有這一段: DataNucleus Access Platform is the persistence layer behind Google App Engine for Java. 原來這個 plateform同時支援JDO跟JPA兩個標準, 因此想用哪個就用哪個囉.

另外也看到Hibernate主要是JPA的實作, 因此若使用JPA可算是有摸蜆仔兼洗褲的作用. 以後若有機會使用Hibernate的話, 不妨就使用JPA來儲存資料吧.

不過看到以下那一堆unsupported features... 很多features我看不太懂是甚麼意思, 不過不能join不能aggregrate?! 不會吧~~ 那我要資料總筆數怎麼作咧... 還是說有method可以用? 看來只好等空間拿到手再來好好試用一下.

Edit 1: 剛又多研究了一下, 知道資料總筆數要用 datastore.prepare(query).countEntities()來取得, 也就是說, 基本上資料應該已經全部從資料庫給拉出來了, 這樣若有需要作報表系統的話, 效能堪慮阿...

Unsupported Features of JDO

The following features of the JDO interface are not supported by the App Engine implementation:

  • Unowned relationships. You can implement unowned relationships using explicit Key values. JDO's syntax for unowned relationships may be supported in a future release.
  • Owned many-to-many relationships.
  • contains() syntax for query filters on Collection fields. You can test that a multi-valued property (a Collection field) has a value using an equality filter: collection == "value"
  • "Join" queries. You cannot use a field of a child entity in a filter when performing a query on the parent kind. Note that you can test the parent's relationship field directly in query using a key.
  • JDOQL grouping and other aggregate queries.
  • Polymorphic queries. You cannot perform a query of a class to get instances of a subclass. Each class is represented by a separate entity kind in the datastore.
  • IdentityType.DATASTORE for the @PersistenceCapable annotation. Only IdentityType.APPLICATION is supported.
  • There is currently a bug preventing preventing persistent fields on superclasses from being saved to the datastore. This will be fixed in a future release.


Unsupported Features of JPA

The following features of the JPA interface are not supported by the App Engine implementation:

  • Owned many-to-many relationships, and unowned relationships. You can implement unowned relationships using explicit Key values, though type checking is not enforced in the API.
  • "Join" queries. You cannot use a field of a child entity in a filter when performing a query on the parent kind. Note that you can test the parent's relationship field directly in query using a key.
  • Aggregation queries (group by, having, sum, avg, max, min)
  • Polymorphic queries. You cannot perform a query of a class to get instances of a subclass. Each class is represented by a separate entity kind in the datastore.

星期三, 7月 09, 2008

Hex String to Byte Array and reverse

A very easy way to do these 2 things.

import java.math.*;

public String toHexString(byte[] in){
BigInteger temp = new BigInteger(in);
return temp.toString(16);
}

public byte[] fromHexString(String in){
BigInteger temp = new BigInteger(in, 16);
return temp.toByteArray();
}