วันเสาร์ที่ 28 พฤศจิกายน พ.ศ. 2552

ปิดเสียง log-in ใน Karmic

จะเห็นได้ว่าไม่สามารถปิดได้ถึงแม้ไปตั้งใน Sound Preferences แล้ว
ต้นเหตุที่ปิดไปแล้วแต่เหมือนไม่ปิดคือ หน้า log-in ทำงานคนละ User กับที่ใช้งานอยู่ โดย log-in จะใช้ User คือ gdm ดังนั้นสามารถปิดเสียงได้โดยใช้คำสั่งดังนี้
#sudo -u gdm gconftool-2 --set /desktop/gnome/sound/event_sounds --type bool false

วันศุกร์ที่ 20 พฤศจิกายน พ.ศ. 2552

SpringMVC: ตอนหนทางของ Request กว่าจะมาเป็น Response

ใครเคยเขียน SpringMVC มาบ้างคงพอจะผ่านๆตามาบ้างกับ 6 ส่วนประกอบนี้
ซึ่งเมื่อจับมาวาดเป็นแผนภาพ ก็จะทำให้เข้าใจได้มากขึ้น

เริ่มต้นกันเลยดีกว่า

  1. มีใครสักคนส่ง Request เข้ามา ด่านแรกที่ต้องเจอคือ DispatcherServlet ถูกคอนฟิกไว้ใน web.xml ถ้า Reqest ตรงกับ url-pattern ที่กำหนด DispatcherServlet นี้ก็ทำงานไป
    * เรื่องชื่อของ DispatcherServlet ที่กำหนดไว้ก็สำคัญจะกล่าวต่อไป(รอไปก่อน)

  2. Request ที่เข้ามาถูกส่งไปตีความที่ HandlerMapping ว่า Controller ไหนจะเป็นผู้รับกรรมดี
    HandlerMapping มีอยู่หลายตัวเลือก ถ้าไม่เลือกเลย SpringMVC เองมีค่าพื้นฐานอยู่แล้วคือ BeanNameUrlHandlerMapping คู่กับ DefaultAnnotationHandlerMapping (สำหรับ Java5+) เขียนไปเดี่ยวก็งงมาดูตัวอย่างการใช้ BeanNameUrlHandlerMapping กันหน่อย

    <bean name="/home" class="com.gable.train.springmvc.test2.mvc.HomeController" />

    อ่านชื่อของ BeanNameUrlHandlerMapping ก็คงพอรู้ว่ามันแมพกับ Controller ยังไง นั่นก็คือใช้ชื่อของ bean นั่นเอง

  3. หลังจาก DispatcherServlet รู้แล้วว่าเป็น Controller ตัวใด DispatcherServlet จะรอช้าอยู่ใย Controller ตัวนั้นก็ถูกเรียกทำงาน ผลลัพธ์จากการทำงานที่ได้คือ ModelAndView

  4. ModelAndView ประกอบด้วยสองส่วนคือ ชื่อของ View ซึ่งจะไปหากันต่อไปว่าชื่อที่ระบุนี้ตรงกับ View ตัวไหน ส่วน Model คือแมพอ็อพเจคที่จะเอาไปแสดงผลบน View

  5. หลังจากได้ชื่อ View มาแล้ว จะนำชื่อไปตีความที่ ViewResolver ซึ่งทำหน้าที่คล้ายคลึงกับ BeanNameUrlHandlerMapping คือแมพชื่อ View เข้ากับ View
  6. ตัวอย่างการแมพชื่อเข้ากับ View

    <bean name="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
    </bean>


  7. สั่งให้ View เรนเดอร์ผลลัพธ์เป็นอันจบ การเดินทางของ Request กว่าจะมาเป็น Response ได้เดินทางมาจนถึงจุดจบที่นี่เอง

  8. หมายเหตุ HandlerMapping และ ViewResolver สามารถเซ็ตการทำงานได้ในลักษณะของโช่(chain) คือมีได้หลายตัวสามารถเซ็ตลำดับผ่าน property order ไว้ต่อตอนหน้า
    หมายเหตุ2 ใครใช้ SpringMVC แบบ Annotation อาจไม่ได้เห็นภาพตรงตามนี้เนื่องจาก SpringMVC แบบ Annotation ช่วยลดข้อยุ่งยากในการคอนฟิก และที่เห็นชัดๆเลยคือการสร้าง Controller ตัดการ implements หรือ extends คลาสที่น่าสับสนออกไป ถ้าจำไม่ผิด Controller แบบเดิมมีตั้ง 7 ชนิด

Picture Credit: SpringInAction2

วันจันทร์ที่ 26 ตุลาคม พ.ศ. 2552

Recompiling Virtualbox Kernel Module

วันนี้เอาอีกสัก blog

ใครใช้ Virtualbox แล้วอัพเดท Linux kernal น่าจะเคยเจอว่า อาจจะ start VM ไม่ขึ้น
มีข้อความว่า 'The vboxdrv kernel module was either not loaded…' แล้วบอกให้ 'Re-setup the kernel module by executing ‘/etc/init.d/vboxdrv setup’ as root.'
recompile virtualbox ใหม่ก็ได้แล้ว
#sudo /etc/init.d/vboxdrv setup

สร้าง Icon เรียกโปรแกรมบน Desktop ของ Linux

บ่นๆก่อนเลยช่วงนี้แค่งานที่ office ก็หมดแรงแล้ว(จริงๆแล้วขี้เกียจ !^^)

พอดีลง Netbean แล้วมันสร้าง icon เรียกโปรแกรมไว้บนหน้า desktop จึงได้รู้
ตัวอย่างสคริปไฟล์ ~/Desktop/netbeans-6.7.1.desktop
[Desktop Entry]
Encoding=UTF-8
Name=NetBeans IDE 6.7.1
Exec=/bin/sh "/media/src/IDE/netbeans-6.7.1/bin/netbeans"
Icon=/media/src/IDE/netbeans-6.7.1/nb6.7/netbeans.png
Categories=Application;Development;Java;IDE
Version=1.0
StartupNotify=true
Type=Application
Terminal=0

แค่อ่านรายละเอียดก็พอรู้กันแล้วใช่ไหมว่าพารามิเตอร์แต่ละตัวมีความหมายว่าอย่างไรกันบ้างเอาหลักๆแล้วกัน
- Name เป็นชื่อที่จะเห็นบนหน้า desktop
- Icon เป็นรูปที่จะแสดงบนหน้า desktop
- Exec ตำแหน่งของโปรแกรมจริงๆ
- Terminal มีค่า 0 คือไม่ต้องเปิด terminal ขึ้นเป็น background

มันสร้างให้แต่ผมลบทิ้งรก desktop แต่เอาว่าได้รู้แล้วกันว่ามันมีวิธีนี้ในการสร้าง Icon ไว้เรียกโปรแกรมได้ด้วย อ๋อ OS Linux Ubuntu นะ Windows ไม่ต้องแปลกใจเพราะมันไม่มีจะทำได้ก็แค่ link อย่างเดียว (แอบกัด Windows ซะหน่อย)

วันพุธที่ 16 กันยายน พ.ศ. 2552

Java Decompiler

ตั้งแต่ย้ายมาทำงานบน Ubuntu เพิ่งจะได้มีโอกาศต้อง decompile โค้ดชาวบ้านเค้า ปกติจะใช้งาน Open source ซะส่วนใหญ่เลยสบายไป
หาๆเจอ JD-GUI, JD-Eclipse ที่นี่เลย Java Decompiler project ใช้ได้เลย

How to add a TrueType font to Java

To add a TrueType font to Java, just put the .TTF file in the /usr/java/jre/lib/fonts directory.

Note: you may need to restart the JVM to see it

Thank http://www.fileformat.info/tip/java/ttf.htm

วันจันทร์ที่ 31 สิงหาคม พ.ศ. 2552

การทำ Relationship Mapping ใน LDAP

บทความนี้ต่อเนื่องจาก ทำความเข้าใจ LDAP (แบบย่อๆ)
เนื่องจากโครงสร้างของ LDAP เป็น tree ไม่ใช้ table อย่าง RDBMS ปัญหาที่ตามมาคือจะใช้ LDAP เก็บข้อมูลที่มีความสัมพันธ์กันอย่างไร

การแม็พความสัมพันธ์มีหลายวิธีเช่น
1. Relations by DN
2. Relations by Attribute
3. Relations by Hierarchy
ในบทความนี้จะอธิบายแบบ Relations by DN ซึ่งเป็นวิธีที่ยืดหยุ่นและพบว่าใช้กันมาก

ต้องขอบคุณเอกสารจาก DataNucleus ที่ทำให้เข้าใจโครงสร้างข้อมูลของ LDAP สำหรับการนำไปใช้งาน

วันศุกร์ที่ 28 สิงหาคม พ.ศ. 2552

Narisa Tach Talk7 (#NTT7)

พรุ่งนี้เตรียมตื่นแต่เช้าไปงาน #NTT7
หลังจากงาน NJUG ซึ่งก็ผ่านมานาน มาครั้งนี้ค่อนข้างจะเป็นงานใหญ่เลยแหละ ได้ไปพบปะกับพี่ๆ(ตัวเป็นๆ อิๆๆ)
รายละเอียดของงาน Narisa Tech Talk 7.08.29
น่าติดตามทุก Session เลย
- Development process อย่าง Agile, TDD ของพี่ข้าวโพดหวาน อยากดูโปรเซส เทคนิคและเครื่องมือที่นำใช้
- Apache CouchDB ของพี่ @roofimon ดูสิว่ามันคืออะไรทำไมพี่รูฟจึงเปลี่ยนจาก TDD มาเป็น CouchDB ได้มันมีอะไรดีกัน
- DemoFest ช่วงดูโชดู ติดตาม OFBiz Framework มันง่ายขนาดไหน ตั้งแต่พี่ Sand เอามาโชในงาน NJUG ครั้งที่แล้วก็ยังไม่ได้แตะเลย
- Theory of constraint ของพี่ @pphetra พี่ป๊อกมาแนว workshop น่าจะทำให้เข้าใจได้ง่ายขึ้น
- Seam ตะเข็บยัก 555 เห็น @dean4j ละเชียร์จังเลย ถ้ามันแจ๋วได้เอามาใช้ร่วมกับ Spring เดี๋ยวเตรียมคำถามไปคอยถามดีกว่าเรื่อง conversation scope นี่แหละ
- Build and run many LOB applications on a single platform with xRM ชื่อยาวจริงๆของพี่ฟูเกียรติ ไม่รู้ว่าคืออะไรเลยลองหานิยามมันซักหน่อย
XRM is an application platform layer that accelerates the development of relational Line-of-Business applications and drives business results through an optimised infrastructure on the Microsoft Application Platform.
มันจะเหมือน OFBiz Framework รึเปล่าน้า

เตรียมเคลียร์หัวให้ว่างแล้วเจอกันพรุ่งนี้คับ

วันเสาร์ที่ 22 สิงหาคม พ.ศ. 2552

แก้ปัญหา HD ง่ายๆด้วย e2fsck

อธิบาย system ที่ใช้อยู่ซักหน่อย
- Ubuntu 9.04
- โปรแกรม Azureus
- External HD ใช้ file system เป็น EXT3

เปิด Azureus โหลดอยู่ดีๆ มีข้อความแจ้งมาประมาณว่าหาข้อมูลในตำแหน่งนั้นไม่พบ เลยเปิดเข้าไปดูในโฟลเดอร์ที่โหลดไฟล์หน่อยสิ
อ้าวเฮ้ยไม่มีไฟล์อยู่จริงด้วย งั้นลองปิดให้ HD ได้พักสักหน่อย เปิดขึ้นมาร้องจ๊ากเลย เป็นอีกแล้วหรอ mount partition ไม่ได้
ก่อนหน้านี้ก็เคยเป็นไปใช้โปรแกรมกู้ข้อมูล กู้เอาเสียเวลาม๊ากกก แถมต้องมี HD อีกตัวมาเก็บข้อมูลที่กู้ด้วย รอบนี้จำไม่ได้ด้วยว่าเคยกู้มายังไงจำได้ว่าใช้โปรแกรมบน windows กู้เอา
รอบนี้ขี้เกียจ ไหนๆก็ไหนๆแล้วอ่านข้อความที่เมื่อพยายาม mount HD ผ่าน nautilus ดูหน่อย มันบอก block error อะไรสักอย่าง รายละเอียดให้ไปอ่าน message จาก kernal โดยใช้คำสั่ง
#dmesg | tail

สิ่งที่พบคือ
[ 65.273067] EXT3-fs warning: mounting fs with errors, running e2fsck is recommended
[ 65.273406] EXT3 FS on sdb5, internal journal

หาข้อมูลสักหน่อยก็ลุยด้วยคำสั่ง
#sudo e2fsck -C0 -f -v /dev/sdb1

นั่งรอไปสักครึ่งชั่วโมง อ้อลืมใส่ -y นั่งตอบ yes ไปเรื่อยๆด้วย(เมื่อยเลย) ตอนแรกใช้ -p ให้มันกู้แบบอัตโนมัติให้แต่มันบอกให้รัน manual แทน ==" เลยลืมใส่ -y เลย

ปรากฎว่า e2fsck แก้ไข ข้อมูลที่ผิดพลาดได้เรียบร้อยดี

คติเตือนใจ อ่านคำแนะนำของระบบด้วย ถึงแม้ว่าในหลายๆครั้งจะอ่านไม่รู้เรื่อง แต่บางครั้งมันมีประโยชน์(จริงๆนะ)
EXT3 สุดยอดดด

วันจันทร์ที่ 17 สิงหาคม พ.ศ. 2552

ทำความเข้าใจ LDAP (แบบย่อๆ)

โน๊ตย่อๆเกี่ยวกับ LDAP เพื่อความเข้าใจเบื้องต้น เป้าหมายอยู่ที่ SSO (Single Sign On) ถ้าไม่ขี้เกียจไปซ่ะก่อน

LDAP (Lightweight Directory Access Protocol) เก็บข้อมูลโดยมีโครงสร้าง คล้ายๆ ต้นไม้(Tree) โดยแต่ละโนด(Node) เรียกว่า เอ็นทรี(Entry) แต่ละ Entry จะมี DN(Distinguished Name) หรือก็คือชื่อที่ใช้ระบุ Entry


โดย Entry ลูก ที่อยู่ใต้ Entry แม่ จะมี DN ของ Entry แม่ เป็น Suffix Entry นั้น ดังภาพ (รูปจาก SUN ไม่ค่อยชัดเพ่งๆเอาหน่อย)

รายละเอียด Entry จะประกอบด้วย objectClass และ Attribute ต่างๆ
- objectClass ใช้บอกรายละเอียดชนิดของ Entry ซึ่ง Object Class นี้เองที่สามารถบอกว่า Entry มี Attribute อะไรได้บ้าง
- Attribute เทียบได้กับ property ของ Object ในภาษา OO ทั่วไป มักใช้ตัวย่อ ตัวอย่างของ Attribute เช่น uid = User id, cn = Common Name, sn = Surname ฯลฯ
รายละเอียดชนิดของ Obejct Class, Attribute type ถูกกำหนดโดยสิ่งที่เรียกว่า Schema ซึ่งมีมาตราฐานตาม RFC2247 และ RFC2256 ตามลำดับ Schema ไม่ได้เพียงแต่กำหนด Object Class และ Attribute type เท่านั้น ยังมีกำหนดอย่างอื่นอีกเพียบ Attribute Syntaxes, Matching Rules, Matching Rule Uses, Attribute Types, Object Classes, Name Forms, Content Rules และ Structure Rule

ตัวอย่าง Entry ในรูปแบบ LDIF(LDAP Data Interchange Format)
dn: cn=John Doe,dc=example,dc=com
cn: John Doe
givenName: John
sn: Doe
telephoneNumber: +1 888 555 6789
telephoneNumber: +1 888 555 1232
mail: john@example.com
manager: cn=Barbara Doe,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top


ถ้า Directory Service ใช้เก็บและแชร์ข้อมูล คล้ายสมุดหน้าเหลือง แล้วมันจะต่างอะไรกับ Database ลองอ่านดูจากลิงค์ ได้มีเปรียบเทียบไว้

Directory Service มักจะเป็นส่วนประกอบหลักในการออกแบบระบบรักษาความปลอดภัย เนื่องจาก admin สามารถคุมการเข้าถึงทรัพยากรต่างๆในระบบได้ โดยใช้ Directory Service นี้เป็นศูยน์กลางในการเซ็ตข้อมูลต่างๆของผู้ใช้งาน สิทธิ์การเข้าถึงทรัพยากรต่างๆ สาเหตุหนึ่งเนื่องจากโครงสร้างของ Directory Service ที่สามารถเข้าถึงข้อมูลได้อย่างรวดเร็ว ทำให้เหมาะกับการเป็นศูยน์กลาง การเข้าถึงเพื่อดึงข้อมูลต่างๆหรือเพื่อทำ access control ผู้ใช้จากแอฟพริเคชั่นต่างๆในปริมาณสูงได้

วันอังคารที่ 28 กรกฎาคม พ.ศ. 2552

ขอบคุณผู้เก็บมือถือผมไว้

ไม่รู้ว่าผู้มีพระคุณจะได้อ่านไหมแต่อยากบอกขอบคุณมากๆครับ

เรื่องก็มีอยู่ว่าผมขึ้นรถกระป๋องสาย 70 เข้าประชาอุทิศ ผมไปลงบ้านสวนธนอยู่แถวๆซอยพุทธบูชา 42
ลงรถมาก็เดินมาหน่อยได้ยินเสียงเหมือนของตกหันกลับไปดูก็ไม่เจออะไร คิดในใจเสียงเหมือนโทรศัพท์เราตกรึเปล่า คลำกระเป๋าดูจริงๆด้วย ส่วนเสียงที่ได้ยินก็ไม่รู้เพราะใครบรรดาลใจรึเปล่า ขอบคุณสิ่งนั้นด้วยครับ
ผมก็รีบโทรเข้าไปเลยพี่เค้ารับสายแล้วบอกจะคอยอยู่ที่ปากซอยพุทธบูชา 36 ผมคิดในใจว่าค่อยยังชั่วโชคดีจัง
หลังจากนั้นก็รีบวิ่งทั้งที่สะพายเป้ใส่โน๊ตบุคกับของอย่างอื่นสักห้าหกกิโล ไปเลยวิ่งไปเรื่อยๆไม่เหนื่อยเลยแฮะไกลอยู่เหมือนกัน(เกือบกิโล) ไปเจอพี่เค้านั่งคอยอยู่ลืมบอกไปว่าพี่เค้าเป็นผู้หญิง
หลังจากได้รับโทรศัพท์ ผมจะให้สินน้ำใจพี่เค้าไว้ แต่พี่เค้าไม่รับ ผมก็ได้แต่ขอบคุณพี่เค้า ลืมถามชื่อพี่เค้าไปด้วยเลย
ยังไงก็ขอบคุณอีกครั้งครับ เงินส่วนนั้นผมจะเอาไปทำบุญให้ครับ ผมตั้งใจจะมอบให้ครับ
กลับถึงห้องอาบน้ำเสร็จขาเกร็งนิดหน่อยเลย ดีที่ไปวิ่งตอนเย็นบ่อยๆ
ขอบคุณครับ

Transaction annotation-driven แล้ว Spring สร้างอะไรให้บ้าง

การใช้งาน @Transactional จะต้องกำหนดใน Spring Context ดังนี้

<tx:annotation-driven transaction-manager="transactionManager" />

มาดูกันว่า มันสร้างอะไรให้บ้าง

<aop:aspectj-autoproxy />
<bean id="transactionAttributeSource" class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributeSource" ref="transactionAttributeSource" />
</bean>
<bean id="org.springframework.transaction.config.internalTransactionAdvisor" class="org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor">
<property name="transactionAttributeSource" ref="transactionAttributeSource" />
<property name="adviceBeanName" value="transactionInterceptor" />
</bean>

บรรทัดแรกสั่งให้ Spring ทำ auto proxy จาก Advisor ที่มีการคอนฟิกใน Spring Context
ที่ เหลือเป็นการคอนฟิก Advisor, Interceptor(เป็น Advice) และ TransactionAttributeSource ที่ทำหน้าที่ บอกว่า method ของ class ที่ถูกเรียกนี้มี TransactionAttribute ยังไง
ตัวที่บอกรายละเอียด Transaction พวก propagation, isolation, timeout ฯลฯ อยู่ที่ TransactionAttribute นี่แหละ

อันนี้เฉพาะโหมด proxy ของ annotation-driven ยังไม่ไล่โหมด aspectj แต่มันก็คือๆกันแหละแค่เปลี่ยนการทำ proxy จากใช้ Proxy ของ JDK เป็น cglib แทน

วันเสาร์ที่ 25 กรกฎาคม พ.ศ. 2552

ดูการสร้าง Bean ของ Spring JavaConfig

เริ่มแรกดูการคอนฟิก Spring Context ก่อนจากเดิมใช้ XML เป็น Java + Annotation

@Configuration
class MyConfig {
public @Bean MyBean myBean() {
new MyBean();
}
}


เพื่อให้ง่ายต่อความเข้าใจจะใช้ XML ร่วมกับ ConfigurationPostProcessor เพื่อทำ Bootstrapping JavaConfig

<beans>
<!-- first, define your individual @Configuration classes as beans -->
<bean class="myapp.MyConfig"/>

<!-- be sure to include the JavaConfig bean post-processor -->
<bean class="org.springframework.config.java.process.ConfigurationPostProcessor"/>
</beans>

จะเห็นได้ว่ามีการกำหนด MyConfig เป็น Spring Bean ร่วมกับใช้ ConfigurationPostProcessor ซึ่งเป็น BeanFactoryPostProcessor ชนิดหนึ่ง

การสร้าง Spring Bean แบบปกติตัวที่ทำหน้าที่สร้าง Instance Bean คือ InstantiationStrategy

Spring JavaConfig ก็ใช้หลักการเดียวกัน แต่จะใช้การสร้าง bean ผ่าน Factory Method นั่นคือ MyConfig.myBean() จะทำหน้าที่เป็น Factory Method นั่นเอง หากแปลงเป็น XML จะได้ประมาณนี้

<bean id="myconfig" class="myapp.MyConfig" />
<bean id="myBean" factory-bean="myconfig" factory-method="myBean" />


ส่วนเหตุที่มานั่งไล่ Spring JavaConfig เพราะกำลังเขียน BeanDefinitionParser อยากให้ Instance ที่สร้างใน BeanDefinitionParser ด้วยการ new Object ธรรมดานี่แหละขึ้นมาเป็น Spring Bean เลยมาดูสักหน่อยว่า Spring JavaConfig ใช้วิธีไหน

วันพุธที่ 15 กรกฎาคม พ.ศ. 2552

Distribution Spring, maven repository, and SpringIDE

You can find those on "Amazon S3 Web Frontend".
Distribution Spring at dist.springframework.org, in addition, you can find SpringIDE updatesite here too.
Spring Maven repository at maven.springframework.org.
Enjoy your spring anytime.

เคยพบกับปัญหาเหล่านี้ไหม

ทำไมถึงเลือก framework ตัวนี้ นี่ไงตัวนี้เร็วกว่า หรือจะใช้ไปทำไมมันช้า?
แต่เคยมองถึงประเด็นอื่นบ้างไหม เร็วจริงแต่เวลาเขียนนรก =="
พอดีไปเจอคำตอบที่โดนใจ จากพี่ข้าวโพดหวาน อยากทราบว่า framework ตัวไหน ทำงานได้เร็วที่สุดครับ
เฟรมเวิร์คที่ช้ากว่า มีเหตุผลที่ช้ากว่า ส่วนใหญ่จะเป็นที่มันมี layer เพิ่มเพื่อ 1) ทำให้เราเขียนโปรแกรมได้ง่ายขึ้น งานเสร็จเร็วขึ้น 2) ทำให้เราบำรุงรักษาโปรแกรมได้ง่ายขึ้น 3) มีฟีเจอร์สนับสนุนมากกว่า ไม่ต้องเขียนเอง

โดยส่วนตัวผมมองถึงเรื่อง 1 Framework ไหน develop ง่าย 2 ทำ refactor ง่ายนั่นก็คือตัว framework ออกแบบสนับสนุนให้มีการเขียนโปรแกรมแบบ loosely coupling 3 โค้ดที่เขียนขึ้นกับ framework น้อย 4 scalable อย่างหลังนี่แหละที่ช่วยเรื่อง performance 5 opensource 6 มี support หรือ community ที่ดี

วันพฤหัสบดีที่ 16 เมษายน พ.ศ. 2552

JBoss5 JNDI

เพิ่งจะได้ลอง JBoss 5.0.1 หลังจากที่ลอง JBoss 5.0 ตั้งแต่วันแรกที่ออก(อุตส่าห์รอคอย)
ใน JBoss 5.0 พบว่าเขียน Test client (java class with main method to call ejb service) เปลี่ยน namming ให้ตายก็ lookup ไม่เจอสักทีเสียเวลาเป็นวัน เลิกเลย

หลังจากเห็น JBoss 5.0.1 ออกมาเกือบสองเดือนก็ยังไม่ได้เทส วันนี้ว่างๆเลยขอลองซะหน่อย
ปรากฏว่าเต่นเต๋นเต้น ตอน deploy เสร็จเห็นเลยว่ามี JNDI อะไรบ้างที่ binding เข้ากับ Global JNDI เลย
23:30:20,632 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

MyPrint/remote - EJB3.x Default Remote Business Interface
MyPrint/remote-test.PrintRemote - EJB3.x Remote Business Interface


เข้าไปดูใน JMX Console ก็เห็นเหมือนเวอร์ชั่น 4.2 ด้วย(ดีใจไม่ต้องเสียเวลางม)
+- MyPrint (class: org.jnp.interfaces.NamingContext)
| +- remote-test.PrintRemote (class: Proxy for: test.PrintRemote)
| +- remote (class: Proxy for: test.PrintRemote)


ตัว Test client ก็ง่ายๆเหมือนเวอร์ชั่น 4.2 เลย

public class PrintClient {
public static void main(String[] args) {
try {
Properties prop = new Properties();
prop.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
prop.setProperty("java.naming.provider.url","jnp://localhost:1099");
prop.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");

InitialContext ctx = new InitialContext(prop);
PrintRemote print = (PrintRemote)ctx.lookup("MyPrint/remote");
print.display();
} catch (Exception e) {
e.printStackTrace();
}
}
}

จบเรื่องคาใจไปอีกเรื่อง งมใน mail ก็เห็นคนบ่นกัน ว่าแล้วว่ามันต้องแก้

วันจันทร์ที่ 6 เมษายน พ.ศ. 2552

Bug in GORMSessionFactoryDefinitionParser

In GORM of Grails 1.1, I found this bug.
if you define context.xml like this.

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<gorm:sessionFactory base-package="org.grails.samples"
data-source-ref="dataSource" message-source-ref="messageSource" transaction-manager-ref="txManager">
<property name="configLocations" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<util:map>
<entry key="hibernate.hbm2ddl.auto" value="update" />
</util:map>
</property>
</gorm:sessionFactory>

An attribute transaction-manager-ref is not necessary, for Grails will create transactionManager (org.springframework.orm.hibernate3.HibernateTransactionManager), but whether you provide your transaction manager, you will see this exception.
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:387)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:971)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:758)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:422)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at com.gable.grails.test.interoperation.App.main(App.java:15)

In found in GORMSessionFactoryDefinitionParser on line 213.

targetRegistry.registerAlias("transactionManager", transactionManagerRef);

I thought this line intend to give transactionManager being an alias of transactionManagerRef.
It should be

targetRegistry.registerAlias(transactionManagerRef, "transactionManager");

วันศุกร์ที่ 20 มีนาคม พ.ศ. 2552

The ways to deal with non-transactional resources

There are serveral ways to deal with them.
1. Interaction without regard to transactionality. This approach is appropriate when there is no need for transaction management.
2. Development of transactional interfaces. This approach is the most comprehensive, but also the most time consuming because it needs to implement JTA interfaces (implementation of javax.transaction.xa.XAResource).
3. Implement the interactions in a “pseudo-transaction” that explicitly checks for and manages error conditions and rollback. I thought this approach like transaction in the web service which have to implement method for rollback by yourself.
In the detail, you can read at TheServerSide.

วันพฤหัสบดีที่ 19 มีนาคม พ.ศ. 2552

Problem from using JPA in grails with maven

I got this problem when i called $mvn grails:run-app.
[groovyc] Compiling 9 source files to /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/target/classes
[groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, Compile error during compilation with javac.
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:3: package javax.persistence does not exist
[groovyc] import javax.persistence.Entity;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:4: package javax.persistence does not exist
[groovyc] import javax.persistence.GeneratedValue;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:5: package javax.persistence does not exist
[groovyc] import javax.persistence.GenerationType;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:6: package javax.persistence does not exist
[groovyc] import javax.persistence.Id;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:7: package javax.persistence does not exist
[groovyc] import javax.persistence.Version;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:26: cannot find symbol
[groovyc] symbol: class Entity
[groovyc] @Entity
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:28: cannot find symbol
[groovyc] symbol : class Id
[groovyc] location: class org.grails.samples.Person
[groovyc] @Id
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:29: cannot find symbol
[groovyc] symbol : class GeneratedValue
[groovyc] location: class org.grails.samples.Person
[groovyc] @GeneratedValue(strategy=GenerationType.AUTO)
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:31: cannot find symbol
[groovyc] symbol : class Version
[groovyc] location: class org.grails.samples.Person
[groovyc] @Version
[groovyc] ^
[groovyc] 9 errors
[groovyc]
[groovyc]
[groovyc] 1 error
Compilation error: Compilation Failed

It seems javax.persistence does not exist in maven dependencies of grails-maven-archetype 1.0.
To fix this problem, I added ejb3-persistence in pom.xml.

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>ejb3-persistence</artifactId>
<version>1.0.2.GA</version>
</dependency>

วันเสาร์ที่ 7 มีนาคม พ.ศ. 2552

Why cannot i play Patapon?

When I played this game, My PSP was freeze at loading screen.
I found that this game needs firmware 3.71 up and sets UMD ISO MODE to SONY NP9660,
but my firmware is 5.00 m33-6. Why is still not working?
In the end, I try changing the image file from CSO to ISO format.
yahh!!!! It's workkkkkkks.

วันพฤหัสบดีที่ 15 มกราคม พ.ศ. 2552

Can't start Tomcat after install VMware server.

Today (It is not real and I'm lazy to update my blog ==") I'm astonished at why i cannot start Tomcat.
Previously, I offen use Jetty to run my web application because It is fast and has great Maven plugin integreated.
This is exception.
SEVERE: StandardServer.await: create[8005]:
java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
at java.net.ServerSocket.bind(ServerSocket.java:319)
at java.net.ServerSocket.(ServerSocket.java:185)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:373)
at org.apache.catalina.startup.Catalina.await(Catalina.java:630)
at org.apache.catalina.startup.Catalina.start(Catalina.java:590)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)

I knew port 8009 and 8005 is used by another process but i don't know what process use.
Then I searched for process using this port.

sudo netstat -p -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 *:902 *:* LISTEN 6325/vmware-authdla
tcp 0 0 *:8333 *:* LISTEN 6466/vmware-hostd
tcp 0 0 localhost:8307 *:* LISTEN 6466/vmware-hostd
tcp 0 0 localhost:ipp *:* LISTEN 5069/cupsd
tcp 0 0 localhost:62168 *:* LISTEN 7621/wish8.5
tcp 0 0 *:8222 *:* LISTEN 6466/vmware-hostd
tcp6 0 0 localhost:6880 [::]:* LISTEN 8861/java
tcp6 0 0 localhost:8005 [::]:* LISTEN 6322/webAccess
tcp6 0 0 [::]:22214 [::]:* LISTEN 8861/java
tcp6 0 0 [::]:8008 [::]:* LISTEN 8861/java
tcp6 0 0 [::]:netbios-ssn [::]:* LISTEN 5387/smbd
tcp6 0 0 localhost:45100 [::]:* LISTEN 8861/java
tcp6 0 0 [::]:8009 [::]:* LISTEN 6322/webAccess
tcp6 0 0 [::]:47698 [::]:* LISTEN 8861/java
tcp6 0 0 [::]:8308 [::]:* LISTEN 6322/webAccess
tcp6 0 0 [::]:microsoft-ds [::]:* LISTEN 5387/smbd


Then I used ps command to find what webAccess is?

ps -ef | grep webAccess
root 6312 1 0 19:30 ? 00:00:00 /bin/sh /usr/bin/vmware-watchdog -s webAccess -u 30 -q 5 /usr/lib/vmware/webAccess/java/jre1.5.0_15/bin/webAccess -client -Xmx64m -XX:MinHeapFreeRatio=30 -XX:MaxHeapFreeRatio=30 -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/common/endorsed -classpath /usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/bin/bootstrap.jar:/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/bin/commons-logging-api.jar -Dcatalina.base=/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16 -Dcatalina.home=/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16 -Djava.io.tmpdir=/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/temp org.apache.catalina.startup.Bootstrap start
root 6322 6312 0 19:30 ? 00:00:10 /usr/lib/vmware/webAccess/java/jre1.5.0_15/bin/webAccess -client -Xmx64m -XX:MinHeapFreeRatio=30 -XX:MaxHeapFreeRatio=30 -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/common/endorsed -classpath /usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/bin/bootstrap.jar:/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/bin/commons-logging-api.jar -Dcatalina.base=/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16 -Dcatalina.home=/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16 -Djava.io.tmpdir=/usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/temp org.apache.catalina.startup.Bootstrap start


I got VMware using Tomcat to run webAccess.
I chose to change Tomcat ports of VMware. I prefer this approach because I do not change other Tomcat ports again. (yes, It includes JBoss too)

To change Tomcat ports.
1 edit server.xml at /usr/lib/vmware/webAccess/tomcat/apache-tomcat-6.0.16/conf/server.xml.
2 change file mode to writeable.
sudo chmod a+w server.xml

3 find and change 8009 and 8005 ports to others.
4 save and change file mode to old mode.
sudo chmod a-w server.xml

5 restart service or reboot you OS.

วันเสาร์ที่ 3 มกราคม พ.ศ. 2552

Other ways to run Maven on Eclipe.

M2eclipse is excellent Maven tool for Eclipse.
I always use hotkey Shift + Alt + X M to run the last maven goals of Maven Build projects.
example First time you run "compile goal" of MyProject. Next time you want to run with other goals. If you use this hotkey, It will run "compile goal" again. You must move a mouse, right click on project, then select Run as Maven builds ... and key the new goal that you want. It is inconvenient.

Today I read Eclipse integration with Grails. In the step Adding domain classes etc, It shows the way to use External Tools to run grails command. It can adapt to run maven goals.
1 Run -> External tools -> External tools configuration ... .
2 Select Program and new launch configuration.
3 Enter a name of "Maven".
4 Browse file system for the location of mvn command that you have installed.
5 Set the working directory to "${project_loc}".
6 Set the arguments as "${string_prompt}".
7 Under the "Refresh" tab, set to refresh the "project containing the selected resource" upon completion.
8 Under the "Common" tab, tick "Display in favorites menu".
9 I set hotkey Shift + Alt + X S to Runs the last launched external Tool.

Every time you use thes hotkey, Eclipe will always ask you what is the goals you need to run.
You can type any maven goals.