Saturday, May 07, 2005

NerdTests

เดี๋ยวคุณ bact กับ คุณ Keng จะไม่เชื่อ
เอารูปมาให้ดูเลย
จะได้ไม่โดนข้อหาแต่ง javascript :)

mynerd

ภรรยาผมเดินผ่านมา เลยบังคับให้ทำด้วย
ผลลัพท์คุณเธอได้ 12 แต้ม

Related link from Roti

Thursday, May 05, 2005

swt + opengl plugin

OpenGL Plug-in

Article ของ Eclipse OpenGl Plugin
Using OpenGL with SWT

สำหรับผู้ที่ใช้ swing ก็มีตัวที่คล้ายๆกันคือ Jogl

สุดท้ายก็ ariticle ที่พูดถึง java3D กับ java-opengl

Related link from Roti

Star Wars Asciimation

http://www.asciimation.co.nz/

Related link from Roti

j4K

J4KJava Game Contest
game must be 4096 bytes or under.

ตัวอย่างเกมส์
http://www.cokeandcode.com/4k/tilt

Related link from Roti

MIR

Music Information Retrieval
M2K (java opensource)
Tools

เห็นแล้วน่าสนใจดี (แต่ชาตินี้คงไม่ได้ใช้)
คุณ bact น่าจะชอบ

Related link from Roti

Swing Pointers

Link

Related link from Roti

Memory Leak TestCase

ตัวเนื้อหาได้มาจาก blog ของ Tim Boudreau

ปัญหาที่พบบ่อยในการเขียน Swing ก็คือ Memory leak
ซึ่งเกิดการการ add listener ระหว่าง component ต่างๆ
แล้วไม่มีการ remove ออก

ใน project netbean ซึ่งเป็น swing ขนาดใหญ่
ก็มีการจัดการกับปัญหานี้ผ่านทาง testcase + INSANE
โดย testcase ของเขามี pattern ดังนี้

SomeObject o = new SomeObject();
something.doSomethingWith (o);
WeakReference ref = new WeakReference (o);
o = null;
assertGC ("Object still referenced", ref);

object o เป็น object ที่เราสนใจว่ามีการ leak
เกิดขึ้นหรือไม่ โดยสังเกตุว่ามีการสั่ง o = null ซึ่ง
เป็นการ clear referenece ที่อ้างถึงภายใน method นี้แล้ว
ดังนั้นถ้ามี gc เกิดขึ้นเมื่อไร object o ควรจะหายไปจาก Heap
ซึ่งวิธีการตรวจสอบก็คือ wrap object o ด้วย
WeakReference ก่อนแล้วค่อยส่งไปตรวจด้วย method assertGC

ใน method assertGC มี code เขียนไว้ดังนี้
    public static void assertGC(String text, java.lang.ref.Reference ref) {
ArrayList alloc = new ArrayList ();
int size = 100000;
for (int i = 0; i < 50; i++) {
if (ref.get() == null) {
return;
}
System.gc();
System.runFinalization();
try {
alloc.add (new byte[size]);
size = (int)(((double)size) * 1.3);
} catch (OutOfMemoryError error) {
size = size / 2;
}
try {
if (i % 3 == 0) Thread.sleep(321);
} catch (InterruptedException t) {
// ignore
}
}
alloc = null;
fail(text + ":\n" + findRefsFromRoot(ref.get()));
}

หลักๆ ก็คือวน loop 50 ครั้งเพื่อ check ว่า
เจ้า object ที่อยู่ใน weak reference หายไปหรือยัง
โดยแต่ละครั้งก็พยายาม force gc ให้เกิด
โดยมีการ simulate การใช้ heap ผ่านทาง
ArrayList alloc

กรณีที่ loop ครบ 50 ครั้งแล้ว
ref.get() != null
ก็แสดงว่า memory leak แล้ว
ก็ call findRefsFromRoot ซึ่งมีการทำงานดังนี้
    private static String findRefsFromRoot(final Object target) {
final Map objects = new IdentityHashMap();
boolean found = false;

Visitor vis = new Visitor() {
public void visitClass(Class cls) {}

public void visitObject(ObjectMap map, Object object) {
objects.put(object, new Entry(object));
}

public void visitArrayReference(ObjectMap map, Object from, Object to, int index) {
visitRef(from, to);
}

public void visitObjectReference(ObjectMap map, Object from, Object to, java.lang.reflect.Field ref) {
visitRef(from, to);
}

private void visitRef(Object from, Object to) {
((Entry)objects.get(from)).addOut(to);
((Entry)objects.get(to)).addIn(from);
if (to == target) throw new RuntimeException("Done");
}


public void visitStaticReference(ObjectMap map, Object to, java.lang.reflect.Field ref) {
((Entry)objects.get(to)).addStatic(ref);
if (to == target) throw new RuntimeException("Done");
}
};

try {
ScannerUtils.scanExclusivelyInAWT(ScannerUtils.skipNonStrongReferencesFilter(), vis, ScannerUtils.interestingRoots());
} catch (Exception ex) {
// found object
found = true;
}

if (found) {
return findRoots(objects, target);
} else {
return "Not found!!!";
}
}

ซึ่งเป็นการ dump เอา Reference ทั้งหมดออกมา
ผมยังไม่ได้หา javadoc ของ ScannerUtils ดู
แต่เดาว่า skipNonStrongReferencesFilter คงจะ
เป็นการ scan หาเฉพาะพวกที่อยู่ใน WeakReference เท่านั้น

ที่นี้ลองดูตัวอย่างที่ Tim เขาเขียนไว้
public class MyFrame extends javax.swing.JFrame {
MenuAction menuAction = new MenuAction();
public MyFrame() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setBounds (20, 20, 300, 300);
getContentPane().addMouseListener (new MouseAdapter() {
public void mouseReleased (MouseEvent me) {
getPopupMenu().show((Component) me.getSource(), me.getX(), me.getY());
}
});
}

JPopupMenu getPopupMenu() {
JPopupMenu menu = new JPopupMenu();
menu.add (new JMenuItem (menuAction));
return menu;
}

static final class MenuAction extends AbstractAction {
public MenuAction() {
putValue (Action.NAME, "Do Something");
}
public void actionPerformed (ActionEvent ae) {
System.out.println("Action performed");
}
}
}

ผลลัพท์ที่ได้จากการ Test ออกมาหน้าตาประมาณนี้
Testcase: testLeak(javaapplication7.MyFrameTest):       FAILED
Popup menu should have been collected:
private static java.awt.Component java.awt.KeyboardFocusManager.focusOwner->
javaapplication7.MyFrame@d1e89e->
javaapplication7.MyFrame$MenuAction@f17a73->
javax.swing.event.SwingPropertyChangeSupport@3526b0->
javax.swing.event.EventListenerList@3ddcf1->
[Ljava.lang.Object;@105c1->
javax.swing.JMenuItem$1@f74864->
javax.swing.JMenuItem@110003->
javax.swing.JPopupMenu@627086

จะเห็นว่า leak ครั้งนี้ขึ้นใน JMenuItem
ของ JMenuItem ยัง hold reference ถึง MyFrame$MenuAction อยู่
โดยตัวที่ทำให้ leak ก็คือ menu.add(new JMenuItem(menuAction))
ซึ่งกรณีที่เรา new JMenuItem จะเกิดการ add listener
ระหว่าง MenuAction กับ MenuItem
ผลก็คือ PopupMenu ยังมี link จาก menuItem วิ่งไป menuAction

สรุป

โดยปกติเวลาเราสงสัยว่า memory leak หรือไม่ก็ต้องใช้
พวก Profiler ทำการใล่ trace ดู
แต่ที่ Tim เขาแสดงให้ดูก็คือ เราสามารถเขียน Testcase
เพื่อดักจับไว้ได้ก่อนเลย ทำให้เมื่อ project evolve
ไป ถ้าเกิดมีใครมาแก้อะไรแล้วทำให้ memory leak
ตัว testcase ก็จะฟ้องออกมาทันที

Related link from Roti

qemu

วันนี้อ่านเจอ Qemu
ซึ่งเป็น opensource emulator
ก็เลยทดลอง run linux บนเครื่อง mac

โดยจะทดลอง run knoppix ดู
1. เริ่มแรกก็สร้าง knoppix cdrom image file
สั่ง umount cdrom ก่อน
sudo umount /Volumns/KNOPPIX

ใช้ dd สร้าง image file
sudo dd if=/dev/disk1s0 of=/tmp/testimage.img bs=2048


2. ใช้ qemu run จาก image file
qemu -cdrom /tmp/testimage.img -pci -m 512 -k en-us  -boot d 


knoppixonmac
ความเร็วที่ได้นั้นไม่เป็นที่น่าประทับใจแต่อย่างไร

Related link from Roti

Tuesday, May 03, 2005

Linux บน Mainframe

วันนี้ได้มีโอกาสสัมผัส linux บน ​Mainframe
โดยมีหน้าที่ standby เพื่อเกิดปัญหาในการ
ย้าย Web Application จาก AIX Unix Server
ไปยัง Mainframe

ตัว Architecture มีลักษณะดังนี้
ที่ชั้นแรกสุดก็คือชั้นของ LPAR (Logical Partition)
ซึ่งก็คือการแบ่ง computer resources (processors, memory, storage)
ออกเป็นส่วนๆ โดยแต่ละส่วนก็จะมี Operating System
ของตัวเอง
ชั้นที่ 2 ก็คือ VM (virtual machine) ไม่ใช่ Java Virtual Machine นะ
แต่เป็น Virtual machine ที่เปิดโอกาศให้เรา
ติดตั้ง Virtual Server หลายๆตัวใน VM ได้
(แตละตัวก็จะมี virtual cpu, virtual memory, I/O, network
ของตัวเอง)
ขั้นที่ 3 ถึงจะเป็น Linux
โดยที่นี่ใช้ SUSE Linux Enterprise Server 8

หลังจาก Telnet ได้ เริ่มแรกสุดก็ทดสอบ Java Benchmark ก่อนเลย
โดยใช้ Scimark2
ได้คะแนน 66 คะแนน
ยิ้มเลย notebook เรายังได้แต้มตั้ง 200 นิดๆเลย
ด้วยความไม่แน่ใจก็เลยลองไป run ทดสอบ
บน Aix Unix Server ด้วย ปรากฎว่าเจ้า Power PC
ทำคะแนนได้ 266 คะแนน
หลังจากสับสนงงงวยกับคะแนนที่ได้ ก็เลย
ไปหา Red Book ของ IBM มานั่นอ่านดู
ก็พบว่า ตัว linux บน Z os นั้นเหมาะกับงานที่มีลักษณะ
I/O bound สลับกับ CPU bound แต่ไม่เหมาะอย่างยิ่ง
กับงานประเภท Deep Computing หรือ cpu intensive

เริ่มแรกสุดก็เจอปัญหาไม่สามารถต่อ jdbc ไป db2 ได้
มีข้อความว่า unsatisfied linkage error ใล่หา
สักพักจึงเจอว่า
ตัว SUSE เป็น 64 bit
ตัว WebSphere เป็น 31 bit (ไม่ได้พิมพ์ผิดนะ 31 bit)
ส่วน db2 client เป็น 64 bit
ปัญหาเกิดเมื่อ java ที่มากับ Websphere พยายาม
ที่จะต่อ jdbc ซึ่งจะต้องมีการเรียก native code
ของ db2 client ซึ่งเป็น 64 bit
ก็เลยขอให้คนของ ibm ลง db2client
version 31 bit ให้แทน

ปัญหาต่อไปก็คือเวลาที่ใช้ในการทำ I/O
เริ่มตั้งแต่การ FTP ตัวฐานข้อมูล ซึ่งช้ามากๆ
จากนั้นก็เป็นการ create table space
ของ db2 (เนื้อที่ประมาณ 30 GB)
ซึ่งก็ใช้เวลาไปอีก 1 ชั่วโมงครึ่ง
น้องชิ้มแจ้งว่า Data ชุดเดียวกันนี้
เคยเอาไปลงที่เครื่อง PC เวลาที่ใช้ในการ
create table space กับ copy data
ใช้เวลารวมกันแค่ 22 นาที
ด้วยความสงสัยก็เลยเอา Bonnie
มาทดสอบเปรียบเทียบกับ unix server
ปรากฎว่า write I/O ตัว unix กินขาด
(เผอิญว่าลืมเอา thumbdrive ที่บันทึกผลลัพท์กลับมา
ไว้ได้กลับมาเมื่อไรจะ post ให้ดูอีกที)
ก็เลยแจ้งคนของ IBM ว่าช่วยดูให้ด้วย
config อะไรผิดหรือเปล่า

ปัญหาถัดไปก็เป็นเรื่องของ web server
ซึ่งเราจำเป็นต้องใช้ mod_gzip ด้วย
ตัว IBM http Server ที่ bundle มากับ Websphere นั้นไม่
สามารถใช้ mod_gzip ได้
ก็เลยต้องใช้ Apache แทน
แต่ปรากฎว่าเกิดปัญหา conflict ของ 64 bit กับ 31 bit
อีกแล้ว
เนื่องจาก so ของ websphere เป็นแบบ 31 bit
ส่วน apache ที่มากับ SUSE เป็น 64 bit
ก็เลยลอง load source code ของ apache
มา build เองโดยกำหนด CFLAGS=-m31 เพื่อบังคับ
ให้ gcc compile ออกมาเป็น 31 bit
แต่ก็ไปตายตอน ld อยู่ดี
ในส่วนนี้ก็เลยให้คนของ ibm (อีกแล้ว)
ไปจัดหา Ibm HttpServer version
ที่ใหม่กว่า 1.3.31 และเป็น 31 bit มาให้

นอกจากนี้ยังพบปัญหาเกี่ยวกับการ FTP
ที่ส่ง file ได้สำเร็จแต่เกิดมีเนื้อหาบางส่วน
ผิดเพี้ยนไป
แต่ปัญหาในส่วนนี้คาดว่าไม่เกี่ยวข้องกับ linux บน Mainframe

ส่วนปัญหาหนักๆที่ยังไม่ทดสอบ
ก็จะเป็นเรื่อง Jasper Report ที่น่าจะมีปัญหาในส่วน
AWT Thread กับ X Window

สรุปเบื้องต้น
ก็คงต้องอวยพรให้บริษัทที่ปรึกษา ผู้ซึ่งแนะนำให้
move infra structure ขึ้นไปอยู่บน Mainframe
จงโชคดีในการย้ายด้วยเทอญ
ส่วนตัวผมนั้นรู้สึกหวั่นๆอยุ่บ้าง เพราะดูท่าแล้ว
resources ที่มีให้มัน fit เปรี๊ยะเสียเหลือเกิน
(แถมยังแพงด้วย มี paper อยู่อันบอกไว้ว่า
ด้วยราคาของ mainframe แล้ว เราต้อง
cosolidate linux อย่างน้อย 32 server
จึงจะเริ่มมี cost ที่สูสีกัน)

ปล. ขอนินทาที่ปรึกษา (ไม่บอกนะว่าอาจารย์
มหาลัยไหน) และคนของ ibm
ด้วยเถอะ สมัยที่เริ่มต้นโครงการใหม่ๆ (เมื่อต้นปีก่อน)
ทั้งที่ปรึกษาและคนของ ibm บอกว่าเครื่อง
database server ควรใช้ 4 cpu
ตัว application server ควรใช้ 2 cpu
ส่วนผมยืนยันและนั่งยันว่าผิด มันต้องกลับกัน
ผลลัพท์ก็ prove ไปแล้ว
ปรากฎว่า load ปัจจุบัน ถ้าใช้คำสั่ง sar ดู
เครื่อง App Server มี cpu load อยู่ที่ 40-60 %
ส่วน DB Server มี cpu load -> 5 % (tune ไว้ดี)

Related link from Roti

Monday, May 02, 2005

Absenter

http://www.absenter.org/
เกี่ยวกับ Photographs อีกแล้ว

ลองดู Design เขาสิครับ
ใช้รูปเป็นหลัก
ที่เหลือ (link, banner, note) เปลี่ยนสีไปตามรูป
ชอบตรงนกที่เกาะเหนือตัว R

Related link from Roti

Friday, April 29, 2005

Context Free Design Grammar

เอามาจาก Chriscoyne.com
ขอแนะนำให้เข้าไปดู Example 1

Related link from Roti

Sparklines ?

วันนี้อ่าน blog เจอศัพท์ sparklines
พึ่งเคยได้ยินนี่แหล่ะครับ
เลยต้องตามไปดู

เจ้า sparkline ก็คือการ represent
data ในรูป graph นั่นเอง
แต่ที่พิเศษก็คือ
เจ้า graph จะมีขนาดสูงเท่าๆกับตัวอักษร

ลองดูตัวอย่างการใช้


สำหรับ opensource
มีคนทำ library สำหรับ php แล้ว
ชื่อ Sparkline PHP Graphing Library
ส่วนที่ implement ด้วย java นั้นยังหาไม่เจอ

Related link from Roti

Thursday, April 28, 2005

Valang Validator

เป็น module ที่ใช้ในการ validate
อยู่ที่ spring modules sandbox
ตัวอย่างการใช้
<bean id="myValidator" class="org.springmodules.validation.ValangValidatorFactoryBean">
   <property name="valang"><value><![CDATA[
      { age : age is not null : 'Age is a required field.' }
      { age : age is null or age >= 18 : 'Customers must be 18 years or older.' }
      { valueDate : valueDate is not null : 'Value date is a required field.' }
      { valueDate : valueDate is null or (valueDate >= [Td] > valueDate) :
         'Value date must be today.' }
      { firstName : firstName has text : 'First name is a required field.' }
      { firstName : firstName has no text or length(firstName) <= 50 :
         'First name must be no longer than 50 characters.' }
      { size : size has length : 'Size is a required field.' }
      { size : size has no length or upper(size) in 'S', 'M', 'L', 'XL' :
         'Size must be either S, M, L or XL.' }
      { lastName : lastName has text and !(false) = true :
         'Last name is required and not false must be true.' }
   ]]></value></property>
</bean>


ยังไม่เห็นเอกสาร แต่เท่าที่เดาจากวิธีการใช้
คงจะไม่ support กรณี localization (หลายภาษา)

Related link from Roti

Wednesday, April 27, 2005

Rome

วันนี้อ่านเจอคน post เรื่อง Rome ใน blog 2 คน
ก็เลยตามไปดู
ROME is a set of Atom/RSS Java utilities that make it easy to work in Java with most syndication formats.

Related link from Roti

Project Life Cycle

เป็นการ์ตูนล้อเลียน project life cycle
อ่านแล้วตลกดี (เหมือนชีิวิตจริง)
เอามาจาก Deepak Alur's Blog

Related link from Roti

Street Art


Wooster Collective : A Celebration of Street Art
ดูดีๆ มีรูปจากเมืองไทยด้วยนะ

Related link from Roti

Tuesday, April 26, 2005

JavaBlackBelt

อ่านเจอ site นี้ใน serverside ก็เลยลองเข้าไปใช้บริการดู
เป็น web ที่ให้บริการทดสอบความรู้เราในเรื่องต่างๆ (ของ java)
ลองทดสอบเรื่อง hibernate ดู
ปรากฎว่า 15 ข้อ ตอบถูกไป 11 ได้คะแนน 75 % ถือว่า "Fail"
ไอ้ 4 ข้อที่ตอบไม่ได้ก็เป็นพวก

>In Hibernate 2.1, regarding constructors which of the following POJO class could be used by hibernate in order to store and retrieve your POJO instances ?
# A class that defines a public constructor
# A class that does not explicitely define a constructor
# A class that defines a private constructor with arguments (with all arguments Serializable)
# A class that defines a private no argument constructor

อันนี้ตอบตกไปข้อ ลืมเรื่อง private constructor ไป เพราะไม่เคยใช้

>How to specify composite keys in the Hibernate mapping file ?

ตอบไม่ได้อีกเช่นกัน เพราะใช้แต่ xdoclet ไม่เคยต้องเขียน mapping ด้วยมือ

อีกข้อ 1 อ่านแล้วงงคำถาม ก็เลยไม่ได้ตอบ
ส่วนอีกข้อ จำได้ว่าตอบถูก แต่เฉลยบอกว่าข้อนี้ไม่ได้ tick ตอบไป

ตัว Web Application นี้ใช้ struts, spring, hibernate ทำ
หลังจากเริ่ม post ประกาศตัวใน serverside
ปรากฎว่ามีคนแห่เข้ามาเยอะ ทำให้ server ล่ม
เพราะตัว application ไม่ scaleable
เจ้าคนเขียนเริ่มหงุดหงิด ถึงกับ post ว่า
We started developping using all the nice technologies we know: Servlet/JSP, Struts, Spring DAOs, Hibernate.

But we experienced painful problems and the learning curve was hard.

Between you and me, if we had to do it again in the same conditions, I may not use Hibernate, neither Spring transactions, and probably something else than Struts (maybe PhP ? oups, I've said it !). We'll publish an article later end May and explain how these painful layers have been useful sometimes.


เห็นด้วยนะว่า learning curve นั้นสูง
เวลาที่ต้อง train น้องใหม่ในเรื่องพวกนี้ ไม่รู้ว่าจะเริ่มต้นสอนยังไงดี
ส่วนเรื่องทำ app อย่างไรให้ scaleable อันนี้สิเป็นเรื่องที่ต้อง
พึ่งประสบการณ์(ที่เคยผิดผลาด)
กับต้องใช้ความเข้าใจในภาพรวมและภาพย่อยมากหน่อย

มีคน post เสริมว่า
Java is fast and scallable when used right.
Unfortunatelly, Java developers quite often over-engineer, over-design, over-layer, over-hype, over-complicate...


ผมก็เป็นอีกคนที่เคยทำ over-... มา
(ทำไงได้มันสนุกดีนี่น่า)

ไว้รออ่าน article ในเดือน may กันว่าเขาจะพูดถึงประเด็นไหน

Related link from Roti

Thursday, April 21, 2005

Bird Eye View

ใครที่สนใจภาพถ่ายลองเข้าไปชมดูครับ

ANETA GRZESZYKOWSKA & JAN SMAGA: PLAN


ถ้าสนใจในตัวศิลปินก็เข้าไปดูที่นี่
aneta grzeszykowska & jan smaga

Related link from Roti

ความแตกต่างระหว่าง Arial กับ Helvetica

ทุกคนคงคุ้นเคยกับ font ทั้ง 2 นี้
ลองดูสิว่า คุณสามารถแยกความแตกต่างระหว่าง
font ทั้ง 2 นี้ได้ไหม
arial or helvetica quiz
ถ้าอยากแยกได้ ก็ต้องตามไปดู article นี้
How to Spot Arial

แล้วถ้าอยากรู้ประวัติความเป็นมาของ Arial
ก็ต้องไปที่นี่ เขียนอ่านเพลินดี
The Scourge of Arial

Note: สำหรับผู้ที่ขี้เกียจอ่าน
font Arial เป็น ร่าง clone ของ Helvetica
เป็นการหลีกเลี่ยงลิขสิทธิ์ในสมัยก่อน
microsoft เริ่มใช้ Arial ใน version 3.1
โดยซื้อลิขสิทธิ์จาก Monotype
ส่วน Apple เลือกซึ้อลิขสิทธิ์ของ Helvetica

Related link from Roti

Wednesday, April 20, 2005

surrealist gallery

ผมชอบ blog ของ veerle ครับ
เธอ design ได้สวยดี ส่วนแฟนผมเขาบอกว่าสีทึมไปหน่อย
แต่ด้วยความที่ schema ของเธอเป็นสีกลาง ออกไปทึมๆ
เวลาที่มีรูปประกอบ blog
ไอ้สีกลางๆนี่แหล่ะจะช่วยขับให้รูปเปล่งประกายวิบๆออกมาเลย

และก็มีเนื้อหาที่ผมแอบเอาไปใช้ได้ เช่น
css ของ calendar widget

ส่วนที่ขอแนะนำให้ดูก็คือ
ตัว gallery นี้ครับ เป็นรูป style surrealist ของ Paul Rouge
ที่เธอออกแบบ ปกหนังสือให้
รูปสวยดี
ส่วนคนที่ไม่สนใจรูป ลองดู idea ในส่วน user interface ก็ได้ครับ

Note: เนื่องจากเธอเป็น designer ไม่ใช่ programmer
ดังนั้นบางเรื่องเช่น 2 level horizontal navigation in CSS with images
อาจจะดูทะแม่งๆไปบ้าง (ไม่ได้แยะเนื้อหา ออกจาก presentation จริงๆ)

Related link from Roti