Category Archives: Java

ของเล่นใหม่ใน Java 7

duke_java7
 
เป็น major version อันแรกของ Java ใต้ร่มเงาของ Oracle! ผมเองไม่ได้เขียน Java มานานมากๆแล้วเพราะงานที่ทำงานไม่ได้ใช้ตรงๆ แต่ก็ตื่นเต้นไปกับของเล่นใหม่ๆด้วย วันนี้เลยลอง Netbeans 7 + JDK 7 มาเล่นปัดฝุ่นดู 😀

เข้าใจว่ามันมีของใหม่เติมเข้ามาในเวอร์ชันนี้เยอะ แต่ที่ลองเล่นไปจะเป็นอะไรที่เกี่ยวกับตัวภาษาตรงๆ:

Binary Literals

ให้เราแทนค่าที่เป็น binary เช่น 01010101 ลงไปใน code ได้ตรงๆ น่าจะมีประโยชน์มากกับคนที่ทำพวก network / protocol / data format programming ที่แบบว่าต้องเซ็ตบิตที่ตำแหน่งเท่านี้เท่านั้นเยอะๆ ทำให้โค้ดอ่านง่ายขึ้นด้วย (รึเปล่า ??)

int data = 0b001;
int mask = 0b101;
data |= mask;

System.out.println("Data: " + Integer.toBinaryString(data));
// prints 'Data: 101'

Underscores in Numeric Literals

เป็นเรื่อง readability คือพวกค่าที่เป็นตัวเลขก็เอา underscore ไปคั่นได้ ทำให้อ่านง่ายขึ้น (เหรอ?) เช่น

int mask = 0b1110_1010;
int colorCode = 0xFF_FF_CC;
double myAccountBalance = 3_141_592.654;

Strings in switch Statements

อันนี้ไม่มีอะไรต้องอธิบาย เป็น feature ที่ถูกขอมานานถึง 16 ปีแล้ว!

มีเรื่องที่น่าสนใจอีกเรื่อง ถ้าใครตั้งใจเรียนสมัยอยู่มหาลัยจะรู้ว่า switch กับ if ซ้อนกันหลายๆอันมันทำงานไม่เหมือนกัน (ในเชิงทฤษฎี) ในเชิงปฎิบัติ หนังสือเกี่ยวกับ JVM เล่มนี้เค้าบอกว่า ถ้า constants ใน case ต่างๆทั้งหมดรวมกันแล้วมันโล่งเตียน (Sparse) คือมันกระจายตัวกันมากๆ Java จะใช้ Binary search แทนการใช้ Offset table (แบบที่เราเข้าใจตอนเรียน) แต่ถ้าอยู่กันหนาแน่น ก็จะใช้ Offset Table ตามปกติ .. เป็น optimization อย่างนึง

Type Inference for Generic Instance Creation

เป็นการแนะนำตัวของ diamond (“<>”) ช่วยให้เวลาประกาศพวก Generic เขียนง่ายขึ้น ไม่รกหูรกตา

List<String> nameList = new ArrayList<>() {};
Map<Integer, List<String>> customerToOrders = new HashMap<>();

The try-with-resources Statement

ผมว่าอันนี้มีประโยชน์เยอะเลย น่าจะทำให้โค้ด Java ใหม่ๆเปลี่ยนไปเยอะ

ถ้าให้อธิบายแบบผมคือ มันเป็นเป็นใช้ syntax ของภาษาที่บังคับให้ทำอะไรซักอย่างก่อนออกจาก scope เสมอๆ (คล้ายๆกับ destructor ของ C++ ที่จะโดนเรียกเสมอตอนออกจาก scope, เอาไปทำเทคนิคที่เรียกว่า RAII ได้)

ตัวอย่างที่ยกมาให้ดูในเว็บของ Java เป็นการใช้ BufferedReader แต่ไม่ต้องมีการสั่ง close() เอง ทำให้โค้ดอ่านง่ายขึ้นเยอะเลย จริงมั้ย??

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
// br is auto-closed here!

ใน Java 7 ก็มีหลาย class นอกจาก BufferedReader ที่สนับสนุน try-with-resources แบบนี้ ถ้าเราอยากจะให้ Class ของเราสนับสนุน try แบบนี้ด้วย ก็แค่ implements AutoCloseable

class TestAutoCloseable implements AutoCloseable{

@Override
public void close() throws Exception {
System.out.println("== Close ==");
}
}

// ...

try(TestAutoCloseable ac = new TestAutoCloseable()){
// Doing something ..
System.out.println("== Inside try ==");
}catch(Exception ex){ // (you don't want to do this)
// Close failed!
}
System.out.println("== Outside try ==");

// Prints:
// == Inside try ==
// == Close ==
// == Outside try ==

Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking

อันนี้มีสองอย่าง

อย่างแรกคือ catch Exception ได้หลายๆแบบ (ยิงปืนนัดเดียวได้นกหลายตัว) โดยใช้ try{ .. } catch(FirstException | SecondException ex){ .. }

อย่างที่สองคือ Improved Type Checking คือ Java 7 ฉลาดขึ้นสามารถเข้าใจ Type ของ Exception ได้ละเอียดขึ้น ในตัวอย่างที่ยกมา:

public void rethrowException(String exceptionName)
throws FirstException, SecondException {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
}
catch (Exception e) {
throw e;
}
}

จะเห็นได้ว่าถึงแม้ใน catch จะ thorw e (ที่มี type เป็น Exception) แต่ปรากฎว่าที่หัว method เราเขียน throws FirstException, SecondException ซึ่งเป็น type ที่ specific กว่าได้! อันนี้ทำได้เพราะ Java ฉลาดพอที่จะเข้าใจได้ว่า code ใน try มัน throw  อะไรออกมาได้บ้าง

Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods

อ่านหัวข้อก็รู้แล้วว่าอันนี้เข้าใจยากแน่ๆ! = =’ (เลยเอาไว้หัวข้อสุดท้าย)  อันนี้ผมอ่านแล้วก็ยังงงๆ เลยไม่กล้าลงรายละเอียด

โดยสั้นๆคือ code แบบนี้มันถูก syntax และ compile ผ่าน แต่จะตายตอนรัน

List l = new ArrayList<Number>();
List<String> ls = l; // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0); // ClassCastException is thrown

Java 7 มีการพัฒนาในการระแวดระวังความผิดพลาดทำนองนี้ โดยการเพิ่ม Warning และ Errors ให้ผู้ใช้ระวังตัวนั่นเอง (รากหญ้าแบบผมคงไม่เจอปัญหาทำนองนี้บ่อยๆ = =’)

..

โดยสรุปว่าผม try-with-resources เป็น highlight ของอันนี้ ถ้าเอาไปเทียบกับ C# มันคือ using(..) statement นั่นเอง

แต่ที่ดูแล้วน่าคิดอีกเรื่องคือเรื่อง throw error ได้ละเอียดขึ้น อันนี้ถ้าไม่ใช้ Checked Exception ตั้งแต่แรกก็จะไม่มีปัญหานี้เลย (เหมือนใน C#)

ชอบ features ไหนกันบ้าง ? อ่านละเอียดๆได้ที่ http://download.oracle.com/javase/7/docs/technotes/guides/language/enhancements.html#javase7

ทดลอง IKVM

IKVM เป็น run-time ที่ใช้แปลง byte code ของ Java ไปเป็น IL บน .NET รวมถึงมี Base Class Library ของ Java ที่ implement เป็น .NET ให้เรียกใช้ด้วย ตอนนี้ใช้งานได้ในสองโหมดคือ

1. เอา IKVM ไปแทน Java ไปเลย สั่งรัน class ของ Java หรือ .JAR ที่ build มาแล้วได้ทันทีบน .NET Framework

2. แปลง byte code ไปเป็น IL ให้เสร้จก่อน แล้วเรียกใช้เหมือน app ปกติ (หรือ add reference ไปในกรณ๊ที่เป็น library)

กรณีทั่วๆไปคงหาโอกาสใช้ให้เกิดประโยชน์ได้ยาก ถ้าโปรแกรมเล็กๆเขียนใหม่จาก Java –> .NET ดูจะเป็นวิธีแก้ปัญหาที่ดีกว่า ถ้าแต่โปรแกรมมันเริ่มซับซ้อนและใหญ่ และการใช้งานจริงๆเราก็มองว่าเป็น black box (give input, get output) แก้ปัญหาโดยใช้ IKVM ก็ไม่เลว เคสของผมคือมันมี logic สำหรับการแกะ format อะไรซักอย่างที่มัน proprietary มากๆ spec ก็คงหาค่อนข้างยาก ให้แกะ spec จากโค้ดลองดูแล้วนิดหน่อยก็คิดว่าคงใช้เวลามหาศาล แต่โชคดีที่มันมี implementation ที่เป็น Java อยู่แล้ว ก็ใช้ IKVM แปลงมาเป็น library ใน .NET แล้วเรียกใช้ได้เลย

ตอนแรกคิดว่าคงมีปัญหาแน่ๆ เพราะ library มันก็ใหญ่มากอยู่ แต่ปรากฎว่าผ่านฉลุยตั้งแต่รอบแรกอย่างน่าตกใจ o__o! วันนี้กลับมาบ้านเลยมาลองกับ project วิชา programming methodology ที่เคยเขียนเป็น game คู่กับแบงค์ ทิ้งไว้เมื่อตอนปีสอง ถ้าวัดในแง่ขนาดของโค้ดคงเล็กกว่าที่แปลงก่อนหน้านี้หลักร้อยเท่า แต่เนื่องจากมันเป็น game เลย depends on libraries หลายตัว อาทิ:

  • Swing ทำ GUI
  • อ่านเขียนไฟล์
  • Audio เล่นเสียง
  • คลาสพวกจัดการ Image
  • Math
  • อ่าน Image จากไฟล์ใน JAR (เทียบได้กับ Resource ล่ะมั้ง)
  • ..

รัน

ikvmc CPLander100.jar

ได้มาเป็น CPLander100.exe ผลคือ

  • Start up นานได้ใจ (เกือบ 3 วินาที)
  • เปิดเมนูหน้าแรกได้ ใช้ได้ Hooray!
  • In game ใช้ได้ แต่ออกมาเมนูข้างนอกอีกรอบไม่ได้ T_T
  • เสียงหาย
  • ช้ากว่ารันด้วย Java มาก (สมเหตุสมผล)
  • Component ของ Swing ที่ใช้ทำงานถูก
  • พวก Math มีคำนวณพลาดจน paint ภาพผิดตำแหน่ง คิดว่าน่าจะเกิดจากตอนเขียนโค้ดไม่ระวังเรื่องพวกใช้ floating point (มั้ง)

 

ถึงจะรันได้ไม่ perfect แต่โดยรวมถูกใจ IKVM มาก ว่างๆไปหาโอกาสเล่นกันดู ยกนิ้วให้คนทำ –/\-

IKVMx

หนังไม่สมจริง

ตอนเด็กๆ (ก็ไม่น่าจะเด็กมากประมาณ ม.3 ล่ะมั้ง) เวลาป๊าม๊าที่เป็นหมอนั่งดูละครชุดเรื่อง E.R. กันก็จะนั่งดูเหมือนจะบันเทิงแต่ก็จะจับผิดตลอดเวลาอย่างโน้นอย่างนี้ ไม่สมจริง ทำแบบนี้ไม่ได้ …. ตัวเองตอนนี้มาพอนั่งดูนั่งที่เกี่ยวกับคอมพิวเตอร์หลายๆเรื่องก็ไม่เห็นจะมีเรื่องไหนมันทำสมจริงๆมากๆเลยว่ะ (มีนะแต่น้อย) ส่วนใหญ่ GUI ของคอมพิวเตอร์ในหนังมันก็จะเว่อร์ๆอยู่แล้วเพื่อให้คนดูสนุก วันก่อนก็ได้คุยกับพี่ที่ทำงานอีกคนเค้าก็ติๆ Angel & Demon หน่อยว่าทำอะไรไม่อิงข้อมูลวิทยาศาสตร์ แล้วก็ชมเรื่อง Iron Man ให้ฟังว่าเรื่องนี้ทำอะไรปรึกษานักวิทยาศาสตร์ตลอด ไม่ได้ให้ข้อมูลผิดๆเหมือน Angel & Demon

พักหลังๆผมชอบไปอ่าน review หนัง หลายครั้งบทวิจารณ์หนังพวกนี้มันบอกว่าหนังเรื่องนึงไม่ดีด้วยเหตุผล “ไม่สมจริง” ยกตัวอย่างเช่นเรื่อง The Hurt Locker คนวิจารณ์เคยทำงานเกี่ยวกับทหารมาก่อน เค้าบอกว่าเค้าดูแล้วรู้สึกสะดุดมากตอนที่ตัวเอกตัดสินใจจัดกลุ่ม 3 คนไปกู้ระเบิด เค้าบอกว่าสถานการณ์จริงไม่มีทางมีเรื่องแบบนี้เกิดขึ้นเป็นอันขาด ทำให้เค้าเสียอารมณ์ = =’

มานั่งคิดๆดู สมมติว่าคนเขียนบทเค้าสามารถทำให้คนดู 95% ทั่วโลกบันเทิงไปกับหนังโดยไม่สะดุดเลยได้จนจบเรื่อง และไม่ต้องสนใจคน “วงใน” อีก 5% เลย ว่าจะคิดยังไง มันก็ดูคุ้มค่าที่จะทำนะ ไม่รู้จะเอาเงินไปจ้างที่ปรึกษาด้านวิทยาศาสตร์ การแพทย์ คณิตศาสตร์ โบราณคดี blah blah ไปทำให้คนอีก 5% พอใจไปทำไม

ผมมาจบที่ข้อสรุปว่า “ความไม่สมจริง” ไม่ใช่เหตุผลที่ทำให้หนังมันไม่ดีที่สามารถใช้เอามาบอกคนอื่นได้ (ยกเว้นชัวร์ว่าเป็น 5% ด้วยกัน) … หรือว่ายังไง ?

ถ้าจะให้ผมพูดในฐานะที่เป็นคนใน “5%” ของบางเรื่อง อย่างถ้าใครเคยดูเรื่อง Antitrust ไม่รู้จะมีคนสงสัยเหมือนผมรึเปล่าว่า บริษัทยักษ์ใหญ่จะแย่งตัวหนุ่มน้อยอัจฉริยะผู้เขียนโปรแกรมภาษา “Java” ได้ (ซึ่งมีคนเขียนเป็นอยู่ล้นตลาด) ไปทำงานทำไม =_=” อย่าลืมกดดูให้ถึงหน้าจอที่แสดงโค้ด Java สำหรับทำ Satellite Uplink .. หนังเรื่องนี้พยายาม feature ผลิตภัณฑ์ของ Sun ทั้งเรื่องเลย  …. ไม่อยาก spoil เพิ่มแต่ลองไปดูแล้วกันว่าคนพวกนี้พยายามกันขนาดไหนเพื่อจะ “ขโมย” โค้ด “Java” ของคนอื่น

แต่ก็ต้องยกให้ว่าเรื่องนี้ในด้าน GUI มันค่อนข้างจะสมจริงมาก จะมองมุมไหนคอมพิวเตอร์ก็น่าเกลียดเหมือนจริง +__+’

ถ้าหนังเรื่องไหนสามารถกำจัดความไม่สมจริงที่ถูกสั่งสมขึ้นมาโดยเรื่องอื่นๆได้นี่ ก็จะได้เป็น Hero ไปเลย :’) ยกตัวอย่าง Trinity ใช้ nmap ใน The Matrix (เคยลองๆใช้โปรแกรมนี้ตอนไปแข่ง Network Security Contest ด้วยนะ!) อันนี้ได้ใจคน 5% ไปชัวร์ๆ

หรือคุณว่ายังไง ??

ตัดคำไทยด้วย C#

WARNING: Highly technical blog ahead

กาลครั้งหนึ่งนานมาแล้ว … อาจารย์สมชายแห่ง CP เคยเอารัฐธรรมนูญฉบับเก่ากับฉบับใหม่มาเทียบความถี่ในการปรากฎของคำ ตอนนั้นผมอึ้งมากที่รู้ว่า Java มันตัดคำไทยได้ด้วย แบบ built-in มาไม่ต้องหา library อะไรมาเพิ่มเลย >_<  ถ้าผมเข้าใจไม่ผิด Java ใช้ ICU ของ IBM ที่เป็น open source แต่ตัวที่อยู่ใน class library ของ Java จะเป็นเวอร์ชันเก่ากว่าหน่อย

เจ้า ICU ที่ว่านี่นอกจากตัดคำได้ (Boundary Analysis) แล้วมันยังทำอย่างอื่นที่เกี่ยวกับกับ localization & internationalization ได้อีกมากมายก่ายกองครับ ลองเข้าไปดูกันเอง IBM ทำไว้สองชุดคือ ICU4C และ ICU4J สำหรับ C, C++ และ Java (ไม่มี .NET แป่วว) ถ้าใครทันสมัยใช้ Firefox ที่ยังตัดคำไทยไม่ค่อยจะคล่องอาจจะได้ยินชื่อนี้บ่อย เพราะมีคนไทยฮาร์ดคอร์มากมายเอาโค้ด Firefox มาแก้ใส่ ICU ให้ตัดคำแล้ว build ใหม่ … แค่ฟังก็อยากจะอ้วกออกมาเป็น pointer กับไฟล์ .h แล้วว =__=’

ด้วยความที่ 3 วันนี้ผมเมาจัดหรือยังไงไม่ทราบ เลยใช้เวลาว่างอันมีอยู่น้อยนิดไปพยายามทำ binding ให้เรียกใช้ ICU จาก C# (และ .NET) ได้ครับ! ก่อนทำก็หา best practice โดยการไปถามที่แหล่งประจำเล็กน้อย ได้คำตอบมาแค่อันเดียวน่าเศร้าใจ TvT

ผมเข้าใจว่าการทำ binding มันจะต่างจาก wrapper ตรงที่ เราต้องนำเสนอ interface เดียว (หรือคล้ายๆ) กับที่ underlying C++ classes มันใช้อยู่ให้กับผู้ใช้ ส่วนการทำ wrapper มันเหมือนกับว่าเราไปสร้างอะไรซักอย่างหุ้ม C++ classes เหล่านั้นไว้ และให้ผู้ใช้เรียกใช้งานผ่าน interface ของเรา (โดยไม่รู้ว่าข้างในมีอะไรอยู่บ้าง – Facade Pattern อ่านว่า “ฟา-ซ้าด”) ซึ่งการทำ wrapper นี่มันง่ายกว่าโขเลยน่ะ

หลังจากลองถูๆไถๆ ใช้พลังกับ C++/CLI เหมือนที่เคยใช้ในซีเนียร์โปรเจค ก็ออกมาเป็นรูปเป็นร่าง อยู่ที่ ICU4NET สามารถลองดาวน์โหลดไปใช้ได้ ถึงชื่อจะบอกว่า ICU4NET แต่จริงๆแล้วตอนนี้มันมี class ที่ใช้งานได้อยู่ class เดียวคือ BreakIterator =_=” ตั้งใจไว้ว่าจะจัดการกับ class ในกลุ่ม boundary analysis ให้หมด

เอาโค้ดตัวอย่างให้ดูเล็กน้อย อันแรกเป็นแบบดั้งเดิม ลักษณะเดียวกับที่เขียนใน ICU4J และ ICU4C

private List<string> WordBreak(string text)
{
var sb = new StringBuilder();
var col = new List<string>();

using (BreakIterator bi = BreakIterator.CreateWordInstance(Locale.GetUS()))
{
bi.SetText(text);
int start = bi.First(), end = bi.Next();
while (end != BreakIterator.DONE)
{
col.Add(text.Substring(start, end - start));
start = end; end = bi.Next();
}
}

return col;
}

ส่วนอันนี้ผมเขียน Extension Method เพิ่มให้มัน return เป็น IEnumerable ได้ พวกขา 3.5 จะได้เล่นซนแบบนี้ได้ :’)

using (BreakIterator bi = BreakIterator.CreateWordInstance(Locale.GetUS()))
{
bi.SetText(uxText.Text);

// requires ICU4NETExtension to use Enumerate extension method
MessageBox.Show(string.Join(Environment.NewLine, bi.Enumerate()
.GroupBy(w => w)
.OrderBy(x => x.Count())
.Reverse()
.Select(x => x.Key + " : " + x.Count())
.Take(10)
.ToArray()));
}

ตอนแรกตั้งใจว่า ส่วนที่น่าจะเอาไปเล่นได้หลักๆคงเป็นพวก ASP.NET Web App แหละ แต่นั่งคิดๆดูแล้วมันมีส่วนประกอบที่เป็น library native ของ ICU หลายอันอยู่ ถ้าเข้าใจไม่ผิดคงมีปัญหากับเรื่อง trust level ของ IIS พอสมควร …

ผลพลอยได้จากการผลาญเวลา (แบบไร้เหตุผล เอามันส์ล้วนๆ) ครั้งนี้คือ ได้ศึกษา C# เพิ่มอีกนิดหน่อย แล้วก็ลองใช้ C++/CLI อีกนิสสสนึง หลังๆมานี่อยู่ที่ทำงานได้ใช้แต่ C++ จนรู้สึกตัวเองตามโลก C# ไม่ทัน มาอ่านโค้ดของ @chakrit (ขา 3.5 ตัวพ่อ) ทีนี่นั่งงงอยู่หลายนาที –..-‘ เออออ … น้ำหลักลดด้วยนะ ^ ^

จากประสบการณ์ ด้วยหัวข้อยบลอกประมาณนี้ ผมเชื่อว่าคงมี นิสิต/นักศึกษา ที่กำลังปั่นงานของอาจารย์แล้ว search มาเจอ และอยากนำไปใช้ได้โดยเร็ว … ผมขอร้องว่าก่อนจะทิ้งคอมเม็นต์ไว้หรือเมล์มาถาม technical issue กับผม ช่วยศึกษาเรื่องพื้นฐาน C# กับเรื่องพวกวิธี reference รวมถึงอ่าน Readme ก่อน แล้วค่อยถามมานะครับ …

ผมตั้งเป้าไว้ว่าจะมีคนเอาไปใช้ประโยชน์ได้ 2 คนขึ้นไป ใครเอาไปใช้ทำอะไรบอกด้วยๆ :’)

ICU4NET – ICU Binding for .NET

WordBreak

Remote Debugging J2EE Application

ตั้งชื่อบลอกไม่ถูก คำศัพท์ Java มันเยอะจัด (J2EE, Web Container, Servlet, …)

ฐานโค้ดที่ผมดูอยู่ที่ทำงานมันค่อนข้างใหญ่มาก เป็นไฟล์ Text ขนาดรวมกันเกือบ 20 MB ซึ่งจริงๆแล้วส่วนที่เราจะเข้าไปมองจริงๆมันก็ไม่ได้เยอะอะไรหรอกครับ แต่ปัญหาก็คือว่า เราจะหาส่วนที่เราต้องการมาได้ยังไงจากข้อมูลที่เยอะขนาดนั้น ??? คำตอบหนึ่งคือใช้โปรแกรมพวก Cross Referencing เช่น OpenGrok จะช่วยให้ค้นหาส่วนของโค้ดที่ต้องการได้ง่ายขึ้นเยอะเลย นอกจากนี้ OpenGrok ยังสนับสนุนการทำ index บน repository ของพวก SCM Tools ต่างๆเช่น SVN, Git และ Mercurial อีกด้วย

เข้าเรื่อง … ปัญหาที่ผมเจอคือ OpenGrok มันดันไม่โชว์ History ให้ ซึ่งหลังจากถามไปใน mailing-list ก็พบว่ามันเกิดจากการหาโปรแกรม hg (Mercurial) ไม่เจอใน PATH ผมลองมา reproduce ที่บ้านบน environment ที่เป็น Windows ก็ยังเจอปัญหาเดียวกันอยู่ เลยต้องหาวิธี Debug OpenGrok ตอนนั้นคิดๆไว้หลายวิธี

  • Build เฉพาะ Class ที่ทำหน้าที่ส่วนนั้นขึ้นมาใหม่ แล้วใส่ให้มันโหลดขึ้นก่อนใน CLASSPATH  .. อันนี้สุดท้ายก็ทำไม่ได้เพราะผม build เป็นไฟล์ๆไม่ได้มันติดพวก dependency เลยไม่รู้ว่าสรุปแล้วใช้วิธีนี้ได้ป่าว
  • อ่านวิธี Build OpenGrok จากเว็บมันแล้วลองตั้ง breakpoint ตรงส่วนที่เป็นปัญหา อ่านแล้ววิธีนี้น่าจะง่าย แต่เนื่องจากว่าตัว Container ที่ใช้มันเป็น Tomcat แต่ปกติ Netbeans มันจะติดมากับ Glassfish เลยเกิดความขี้เกียด config ขึ้นมาในบัดดล
  • ทำ Remote Debugging คือ start Tomcat ใหม่ให้มันรันแบบ Debug และเปิด port 7001 รอไว้ แล้วเอา Debugger เข้าไป attach … อันนี้ได้ผลครับ และง่ายมากด้วย แต่ต้อง build OpenGrok ได้น่ะ หลังจากตั้ง breakpoint ไว้แล้วปรากฎว่ามัน break จริงๆด้วยว่ะ! Watch + Evaluate ได้แทบทุกอย่างเลย

จริงๆ ASP.NET ก็มีของแบบนี้เหมือนกัน มันเหมาะมากเวลาเกิดปัญหากับ Application ใหญ่ๆที่การ Setup ให้เกิดปัญหาเดียวกันมันยาก ใช้แล้วก็รู้สึกว่า Java ก็ไม่เลวครับ : )

Java Options สำหรับ Start Tomcat

-Xdebug
-Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7001

แล้วใช้ Netbeans attach เข้าไปที่ port 7001 ของ localhost

บั๊กที่เกิดบ้างไม่เกิดบ้าง

เป็นโปรเจคที่ทำอยู่ที่ฝึกงานครับ

แบ่งงานกับเพื่อนร่วมทีมเขียน เพื่อนร่วมทีมเขียน Data Access Layer ก็คือคลาสที่ห่อหุ้มการทำงานกับฐานข้อมูลทั้งหมดนั่นแหละ (ฐานข้อมูลที่ใช้คือ IBM DB2 ครับ ชื่อเก่า Cloudscape)  ส่วนผมเขียนส่วนที่เป็น Business Logic แล้วก็ทำ Presentation Layer (เป็น Web-based)

จริงๆแล้วมีวิธีมากมายที่จะสร้างเจ้าตัว DAL ขึ้นมาได้ ทั้งแบบอัตโนมัติ และไม่อัติโนมัติ แต่วิธีที่เราใช้กันเป็นวิธีที่คลาสสิกที่สุด คือการประกอบคำสั่ง SQL ขึ้นมาเอง ส่วนที่มีปัญหาก็คือเรื่องของ DateTime นี่แหละ

วิธีการที่ใช้ประกอบค่า DateTime ขึ้นมา คือเอา วัน เดือน ปี ชั่วโมง นาที วินาที มาต่อกัน เช่น 19-06-2008 15:43:12 เป็นต้น แต่ปรากฎว่าเพื่อนผมลืมไปว่า ถ้าเวลาตอนนั้นค่าของหลักวินาทีเป็นเลขหลักเดียว จะได้ String ผิดๆออกมา เช่น 19-06-2008 15:43:6 (จริงๆแล้วควรเป็น 19-06-2008 15:43:06) ตอนเอางานมารวมกันก็เลยมีปัญหาดังกล่าวเกิดขึ้นบ้างไม่เกิดขึ้นบ้าง เล่นเอางงอยู่นาน ถ้าประมาณคร่าวๆ โอกาสที่จะเกิดข้อผิดพลาดระหว่างการทำงานก็เป็น 1/6 ล่ะครับ

ก็ให้ข้อสังเกตไว้ครับ ว่าพวกข้อผิดพลาดที่เกิดบ้างไม่เกิดบ้าง เป็นไปได้สูงว่าจะเกี่ยวข้องกับเรื่องของเวลา (เช่นเดียวกับการ Random) เห็นเพื่อนบ่นเรื่องบั๊กที่พอจะแก้ก็หายไปแล้วไว้ใน Twitter ก็เลยอยากจดเรื่องนี้ไว้ซักหน่อย