วันพฤหัสบดีที่ 20 ธันวาคม พ.ศ. 2550

Basic Config Log4J without properties File

การ Config แบบที่ไม่ใช้ properties File เราจะใช้ Class Properties ในการ Set แทนนน่ะครับ โดยเราจะ Config เหมือน Properties File เลยครับ คือ ถ้าอยู่ทางขวาของ "=" จะเป็น Key ส่วนทางซ้ายเป็น Value ครับ ข้างล่างเป็นตัวอย่างประมาณนี้น่ะครับ

Example
Properties properties = new Properties();
properties.put("log4j.logger.test","DEBUG,test");
properties.put("log4j.appender.test","org.apache.log4j.DailyRollingFileAppender");
properties.put("log4j.appender.test.DatePattern","'.'yyyy_MM_dd");
properties.put("log4j.appender.test.File","C:/TEMP/a.log");
properties.put("log4j.appender.test.layout","org.apache.log4j.PatternLayout");
properties.put("log4j.appender.test.layout.ConversionPattern","[Test] [%d{dd/MM/yyyy HH:mm:ss,SSS}] (%c:%L) - %5p - %m%n");
PropertyConfigurator.configure(properties);

วันพุธที่ 19 ธันวาคม พ.ศ. 2550

ปัญหาที่พบบ่อยสำหรับนักพัฒนา Java Web Application ในประเทศไทยครับ ที่ควรแก้ไข

อันนี้เป็นปัญหาที่ผมเจอกับเพื่อนร่วมงานด้วยกันที่ ควรจะแก้ไขครับ ถ้าคุณทำงานมาเป็นปีแล้วไม่ได้ใช้ หรือว่าไม่ได้ทำก็ควรจะทำนะครับ

Q : ยังมีการใช้ System.out.println อยู่
A : สำหรับเด็กจบใหม่ผมไม่คิดอะไรหรอกครับที่เขาจะใช้เพราะยังไม่รู้ ตอนผมจบใหม่ผมก็เป็น ตอนหลังถึงมาเรียนรู้ว่าไม่ควรจะใช้ System.out.println แล้ว ควรจะใช้ Log4J (พื้นฐานการ Config อ่านได้ที่นี่ครับ) มาใช้ ซึ่งจริงๆ แล้วที่เราใช้ Log4J ก็เพราะว่าเราสามารถที่จะควบคุมพวก ข้อมูลที่ต้องการโชว์ได้ ว่าอยู่ระดับใด(info, debug, warn, fatal) สามารถแยกเกบเป็นไฟลล์ต่างๆ ได้ง่าย ถ้าเราใช้ System.out.println มันจะไม่ได้น่ะครับ (ที่จริงมันก็พอได้โดยเอา Log4J ไปคุมอีกทีแต่ก็ไม่ควรครับ) แล้วก็วิธีใช้ง่ายๆ ก็อย่าไปแยก Log เป็น Class Utitility เลยครับ ควรคุมง่าย แต่ดูยากไม่รู้ว่าอยู่บรรทัดไหน Class ไหนที่ทำงานอยู่ ให้ทำแบบนี้
private Logger log = Logger.getLogger(xxxx.class);
ไว้ที่ Class ที่เราทำงานเลยครับ แล้วก็ใช้ log.xxx(""); เอาจะดีกว่า

Q : ใช้ Google ไม่เป็น
A : ผมคิดว่าแบบนี้ไม่น่าจะมีแล้วนะครับ คือจะหาอะไรก็พิมพ์คำนั้นลงไปเลย (ถ้าไม่รู้ภาษาอังกฤษ ก็พิมพ์ไทยลงไปเลยครับ ผมคิดว่าปัญหาบางอย่างอาจจะหาภาษาไทยได้เลย แต่ถ้าไทยอาจจะต้องพิมพ์เป็นคำๆ แล้วเว้นวรรค ถึงจะหาเจอ) แล้วก็เพิ่มพวกภาษาที่เราใช้ไปด้วยก็จะแคบเข้า เช่น ถ้าเราเขียน Java ตอนจะต้นอะไรก็ติดคำว่า Java ลงไปด้วยก็น่าจะหาเจอนะครับ หรืออย่างถ้าเราใช้ Tomcat Server เราก็พ่วงคำนี้ลงไปด้วย ถ้ามีปัญหาบน Server น่ะครับ น่าจะช่วยให้หาเจอได้ง่ายขึ้นมาก หรือ ถ้าเราอยากรู้ว่า มันคืออะไรก็พิมพ์เลยครับ เช่น JMS คือ แบบนี้ก็หาเจอความหมายที่เป็นภาษาไทยเลยง่ายในการอ่านด้วย

Q : อ่าน Log (SystemOut.log) ไม่เป็น
A : วิธีการอ่านแบบนี้ เราจะต้องมีวิธีการเขียน Log ที่โชว์ให้ดีๆ ด้วยครับ คือพยายาม Log ว่าเราเข้า Class ไหน, Method ไหน ตลอด ค่าไหนเราแค่เช็คของเรา ก็ใช้ Log.debug เอา แล้วให้โชว์ออกมา (ถ้าใช้ Log4J จะช่วยได้เยอะ เพราะเราจะรู้ว่าตอนนี้ทำอยู่บรรทัดไหน Class ไหน, Method ไหน เลยน่ะครับ ขึ้นอยู่กับ Config ของ Log4J) และอีกอย่างพวก Exception น่ะครับ ก็หัดใช้ e.printStackTrace() ไว้ด้วยตอน ดัก try, catch น่ะครับ จะได้รู้ว่าบรรทัดไหน วิธีการไล่พวกนี้ก็ไม่ยากแค่ดูว่า Exception ที่อยู่ใน Package ของเราอยู่ตรงไหนแล้วก็ไปไล่โค้ดไปเรื่อยๆ ก็จะเจอที่ผิดของเราเองน่ะครับ

Q : ไม่ยอมเช็ค Null ไว้
A : อันนี้ผมก็เป็นบ่อยชอบลืม เช็ค Null ทุกครั้ง ที่จะใช้ตัวแปรนั้นน่ะครับ เดี๋ยวจะเกิดปัญหา NullPointerException น่ะครับ พยายามตรวจดูว่าจะ ตัวแปรตัวไหนให้เช็คก่อนที่จะใช้งานตัวแปรตัวนั้น

Q : ไม่รู้จะเขียน Log ให้แสดงตรงไหนบ้าง
A : วิธีการเขียนง่ายๆ นะครับ ก็เข้า Method ไหน Log แสดงว่าเข้า Method นั้น แลวก็แสดงค่าทุกค่าที่ใช้ใน Method นั้น อันนี้แบบง่ายๆ (พวกแสดงค่าต่างๆ ก็ืำเป็น log.debug เอาแล้ว ครอบด้วย if log.isdebugEnable() ไว้ พอเวลาไม่ต้องการให้แสดงก็ไป Config ไว้ที่ Log4J) สำหรับที่สำคัญๆ ที่ควรมีถ้าขี้เกียจ ก็ Log บอกว่าเข้า Method ไหน แล้วก็ค่าที่ลง Database ว่าลงเป็นอะไร แล้วก็ใช้ SQL อะไรครับ จะได้รู้ว่าผิดที่ Database หรือว่าโปรแกรมที่เราเขียน

Q : เขียน Program พวกค่าต่างๆ ไว้ใน Code เลย
A : พวกค่าต่างที่คิดว่าเป็นค่าที่เราต้อง Config ไว้ ควรเอาไปเก็บไว้ใน General Parameter สักที่นึงที่สามารถแก้ไขได้โดยเราไม่ต้องมานั่ง Deploy Application ใหม่ เช่น ใน Database หรือ Properties Files ตัวอย่างค่าที่เราควรไว้ข้างนอก เช่น URL ที่เราต้องติดต่อกับ External System อื่นๆ, ค่าำคงที่ที่เราต้องส่งไปให้กับ External System เป็นต้น

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

การเรียก Datasource ของ Websphere จาก Java Application

วิธีการเรียกที่ผมเห็นทำได้ 2 แบบน่ะครับ แต่มีแบบนึงไม่แน่ใจว่าเป็นปัญหาของ Websphere หรือเปล่า
ที่ผมลองลองกับ Websphere 6.0, Websphere 6.1 ครับ ควรจะทำบน RAD นะครับ ถึงจะรันได้
1. เรียกโดยใช้ Library ของ Websphere เลยซึ่งวิธีนี้จะอ้าง JNDI Name ได้ตรงๆ เลยครับ

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere .naming.WsnInitialContextFactory"); // เป็นตัวที่เราใช้ในการเรียก Context ซึ่ง Library จะอยู่ที่ lib ใน RAD น่ะครับ
env.put(Context.PROVIDER_URL, "iiop://localhost:2809/");// IP Address ของ JNDI Name ตัวที่เราเรียก ซึ่งเราสามารถดู Port ได้ที่ Servers --> Application Server แล้วเลือก Server ที่เรามี JDBC อยู่ เสร็จแล้วดู Port (Communications) ว่า BOOTSTRAP_ADDRESS เป็นอันไหนก็ใช้อันนั้นครับ
InitialContext ctx = new InitialContext(env);
DataSource ds = (DataSource) ctx.lookup("jdbc/test");//ชื่อ JNDI Name ที่เราใช้เรียกครับ


2. จะคล้ายวิธีแรกแต่เราใช้ Context มาตรฐานของ Sun เลย (วิธีนี้ผมลองเรียกแล้วมันได้ค่าเป็น NULL น่ะครับ ม่รู้เพราะอะไรเหมือนกัน)

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi .cosnaming.CNCtxFactory"); // เป็นตัวที่เราใช้ในการเรียก Context ซึ่งจะเป็นของ Sun เลย
env.put(Context.PROVIDER_URL, "iiop://localhost:2809/");// IP Address ของ JNDI Name ตัวที่เราเรียก ซึ่งเราสามารถดู Port ได้ที่ Servers --> Application Server แล้วเลือก Server ที่เรามี JDBC อยู่ เสร็จแล้วดู Port (Communications) ว่า BOOTSTRAP_ADDRESS เป็นอันไหนก็ใช้อันนั้นครับ
InitialContext ctx = new InitialContext(env);
DataSource ds = (DataSource) ctx.lookup("cell/nodes/Node01/servers/server1/jdbc/test"); //ชื่อที่ใช้เรียกจะต่างกับเรียกโดยใช้ของ Websphere โดยเราจะต้องทำการใส่ cell/nodes/<ชื่อ Node>/servers/<ชื่อ Server>/

ปล.
1. ต้องใช้ JRE On Websphere กับ Websphere Runtime ด้วยน่ะครับ
2. ถ้าไปเรียกที่ Server อาจจะต้องดูว่า Server เปิดให้เรียกใช้หรือเปล่าน่ะครับ แต่ถ้าเทสเครื่องตัวเองคืดว่าไม่น่าจะมีปัญหาอะไรครับ

Reference
http://www.webservertalk.com/archive80-2006-4-1481822.html

วิธีการดึงข้อมูลจาก XML อย่างง่ายโดยใช้ Dom4J

เวบของ DOM4J (Entry วิธีการสร้าง XML อย่างง่ายโดยใช้ Dom4J)
จากข้อมูลข้างล่าง เราจะมาแกะ ข้อมูลออกกันว่าจะแกะด้อย่างไรบ้างนะครับ
<?xml version="1.0" encoding="UTF-8">
<Header>
<Parameter1></Parameter1>
<Parameter2>123456</Parameter2>
<Parameter3 total="3"/>
<Parameter4>
<SubParameter>Sub</SubParameter>
</Parameter4>
</Header>

ซึ่งในที่นี้จะสอนวิธีแกะออกมาโดยใช้ DOM4J นะครับ
Document document = DocumentHelper.parseText(xmlResult);//Parser String ที่เป็น XML ให้เป็น Document เพื่อที่เราจะได้ดึงข้อมูลได้
Element rootElement = document.getRootElement();// get Element ออกมาเพื่อจะดึงค่าข้างในมันออกมา
System.out.println("Parameter2 : " + rootElement.elementText("Parameter2")); //เป็นการดึงค่าที่อยู่ใน Parameter2 ออกมาแสดง (ดึงได้เฉพาะ String ถ้าข้างในเป็น Element จะดึงออกมาไม่ได้)
System.out.println("Parameter3 : " + rootElement.element("Parameter3").attributeValue("total")); //ดึงค่าของ total ที่อยู่ใน Parameter3
Element elementParameter4 = rootElement.element("Parameter4"); //ดึง Element ที่อยู่ใน Parameter4
System.out.println("Parameter4 : " + elementParameter4.elementText("SubParameter")); //ดึงค่าเหมือนก่อนหน้านี้ทุกประการ

วันพฤหัสบดีที่ 25 ตุลาคม พ.ศ. 2550

วิธีแก้ปัญหาเวลา Deploy EJB ไม่ได้ใน RAD 6.0

โดยปกติเราจะคลิกขวาแล้ว Deploy EJB เพื่อจะให้มัน Generate Stub เพื่อใช้ในการเรียก EJB นั้นๆ ในบางทีกรณีที่ทำหลายคนแล้ว Sync มาเราจะไม่สามารถ Deploy EJB ได้ครับ เลยต้องใช้วิธีทำจาก Command Prompt แทนโดย ไปที Directory ที่เรา install RAD 6.0 ไว้ แล้วจะอยู่ที่ IBM\Rational\SDP\6.0\runtimes\base_v6\bin\ แล้ว File ชื่อ ejbDeploy.bat

โดยใช้คำสั่งดังนี้
ejbdeploy inputEarFile Directory OutEar
Example
ejbDeploy test.ear c:\Temp testTemp.ear
พอทำเสร็จมันก็จะ Generate Folder Workspace ไว้ให้แล้วเราก็ Copy File ใน EJB Project มาทับของเดิมที่มีอยู่แล้ว Generate ใหม่ก็จะทำงานได้แล้วครับ

วันพุธที่ 17 ตุลาคม พ.ศ. 2550

วิธีการสร้าง XML อย่างง่ายโดยใช้ Dom4J

เวบของ DOM4J


Document vDocument = DocumentHelper.createDocument(); //ไว้สำหรับสร้าง Document XML
Element rootElement = vDocument.addElement("Header"); // สร้างส่วนหัวของ XML
rootElement.addElement("Parameter1"); // สร้าง Element ข้างในแบบไม่มีค่าใน Element
rootElement.addElement("Parameter2").addText("123456"); //สร้าง Element ข้างในแบบมีค่าใน Elementซึ่งค่าห้ามเป็น NULL
rootElement.addElement("Parameter3").addAttribute("total","3"); // สร้าง Element แบบมี Attribute
Element subElement = rootElement.addElement("Parameter4");
//สร้าง Sub Element ข้างใน
subElement.addElement("SubParameter").addText("Sub");

จะได้ข้อมูล ตามข้างล่าง

<?xml version="1.0" encoding="UTF-8">
<Header>
<Parameter1></Parameter1>
<Parameter2>123456</Parameter2>
<Parameter3 total="3"/>
<Parameter4>
<SubParameter>Sub</SubParameter>
</Parameter4>
</Header>

วันอังคารที่ 16 ตุลาคม พ.ศ. 2550

การ Set Connection Timeout ใน Web Service

การ Set Timeout เราสามารถที่จะ Config ไดสองที่ใน Axis คือ
org.apache.axis.client.Stub กับ org.apache.axis.client.Call เป็น SetTimeout
ถ้าเราไปใช้ Call RPC ตรงๆ จะไม่มี Config นะครับ ต้องทำแบบนี้แทน ถึงจะได้น่ะครับ

org.apache.axis.client.Call call = new org.apache.axis.client.Call(service);
call.setTimeout(timeOutWS);//Time Out Web Service เวลาเป็น หน่วย ms ครับ


สำหรับการ Set TimeOut ใน Websphere 6.xxx นั้น เราจะทำที่ Class ที่ลงท้ายด้วย stub แล้วไป Config ที่ Method Invoke (Class com.ibm.ws.webservices.engine.MessageContext) ครับ มันจะมี .setTimeOut (บน Rad 6.0 มันเป็นการ Set Read TimeOut น่ะครับ ต้องไปให้ Eclipse Generate แทน แล้วไป Config ที่ call แทนครับ ตามข้างบน)ได้เลยครับ ซึง Set เป็น ms ครับ แต่ให้จำไว้ว่า ถ้าเราทำการ Rebuild ใหม่ ข้อมูลพวกนี้จะหายเราต้องกลัมา Config ใหม่