วันเสาร์ที่ 25 ธันวาคม พ.ศ. 2553

ค้นหา Open Source ซอฟแวร์ในภาษาจาวา

โน๊ตไว้สั้นๆ กันลืมกับเว็บดีๆอย่าง java-source.net ไว้ค้นหา Open Source ซอฟแวร์ในภาษาจาวา มีการจัดหมดหมู่ไว้หาง่ายดี

วันเสาร์ที่ 18 ธันวาคม พ.ศ. 2553

ยกเลิกการแชร์ไฟล์ด้วยคำสั่ง net

เท้าความก่อนว่าทำไมจึงเกิดบล็อกนี้ขึ้น
ปกติการแชร์ไฟล์ใน Ubuntu ทำได้ง่ายๆโดยผ่าน nautilus ซึ่งเป็น file manager ที่มากับ Ubuntu อยู่แล้วเพียงแค่คลิ๊กขวาที่โฟลเดอร์เลือกแชร์ก็จบ แต่เกิดปัญหาเมื่อไปสั่งแชร์โฟลเดอร์ที่มีสัญลักษณ์พิเศษเข้า พอสั่ง create share มันจะแจ้งความผิดพลาดขึ้น
แต่พอ smb://localhost ปุ๊บอ้าวเฮ้ยทำไมไอ้ที่บอกว่าแชร์ไม่ได้กลับโผล่มาได้ไง nautilus ก็ยังแสดงโฟลเดอร์ว่าไม่ได้แชร์ ทีนี้จะปลดแชร์ได้ไงฟ่ะ

ค้นหาจนไปเจอคำสั่ง net ซึ่งสามารถจัดการเกี่ยวกับการแชร์ไฟล์ได้ รายละเอียดคำสั่งเกี่ยวแชร์ไฟล์มีดังนี้(ใช้ man ดู)
net usershare add sharename path [comment] [acl] [guest_ok=[y|n]] - to add or change a user defined share.
net usershare delete sharename - to delete a user defined share.
net usershare info [-l|--long] [wildcard sharename] - to print info about a user defined share.
net usershare list [-l|--long] [wildcard sharename] - to list user defined shares.

วิธียกเลิกแชร์ไฟล์ให้สั่ง
#net usershare list
เพื่อหาชื่อที่แชร์

ต่อจากนั้นค่อยสั่ง
#net usershare delete "myshare"
ตรง sharename ก็เอาชื่อที่ได้จากคำสั่งแรกใส่เข้าไปแต่ต้องครอบด้วยฟันหนู เพราะมันมีสัญลักษณ์พิเศษอยู่

หรืออีกวิธีให้เข้าไปลบใน /var/lib/samba/usershares/ ก็ได้เหมือนกัน (วิธีนี้ยังไม่ได้ลอง)

วันอาทิตย์ที่ 12 ธันวาคม พ.ศ. 2553

เชื่อม Struts กับ EJB3 ด้วย Spring

ลงไว้ที่ spring66 ด้วย ลงบล็อกส่วนตัวด้วยจะได้มีอะไรอัพเดทบ้าง =="

ได้มีโอกาศสอนการใช้ Struts 1.x ร่วมกับ EJB3 จริงๆอยากให้เค้าใช้ Spring MVC มากกว่า แต่กลัวเกิดปัญหาเรื่องความเชี่ยวชาญและความคุ้นเคยหากมาใช้ Spring MVC เดิมเค้าใช้ Struts อยู่แล้ว ไม่แน่ใจว่าระยะเวลาในการปรับให้เข้ากับเฟรมเวิร์คใหม่ด้วย เดี๋ยวมันจะออกทะเลเหมือนที่เกิดกับ Struts

ทีนี้การเชื่อม Struts กับ EJB3 จริงๆทำได้ไม่ยากคือ lookup JNDI ผ่าน InitialContext แต่การ lookup ทุกครั้งที่ใช้มันทำให้สมรรถนะออกมาไม่ดี วิธีส่วนใหญ่ที่ใช้กันคือสร้าง Delegate คลาสขึ้นมาเพื่อทำหน้าที่ในการติดต่อ EJB โดยเก็บ remote/local ที่ lookup เอาไว้ จะได้ไม่เสียเวลาเรียกใหม่

class  DelegateService {

private UserService userService;
//many EJB service
...

private DelegateService() {}

private static getEJB(String ejbName) {
.....
// process to call EJB (Session Bean)
.....
}
public static void getUserService() {
if (userService == null)
userService = getEJB("CustomerServiceBean/remote");
return userService;
}
...
}


เวลาเรียกใช้ Delegate ใน Action ก็จะได้ประมาณนี้

public class UserAction extends Action {
...
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
UserService service = DelegateService.getUserService();
...
}
}


ซึ่งตรงนี้เราจะใช้ Spring จัดการ โดยให้ String ติดต่อไปยัง EJB แทนหลังจากนั้นเอาอินสแตนท์ที่ได้ฉีดให้กับ Struts action โค้ดจะออกมาสะอาดขึ้น ตัว Action ก็ไม่ขึ้นกับ Delegate คลาส การทำ Unit testing ทำได้ง่ายขึ้นเยอะ และนอกจากนี้ยังสามารถใช้ Spring เป็นจุดเชื่อมต่อกับเทคโนโลยีหรือเฟรมเวิร์คอื่นได้อีกด้วย เขียนจาวาไม่ใช้ spring บาปใช่มั๊ย ^__^
Struts action ก็จะออกมาประมาณนี้

@Service("/users")
public class UserAction extends Action {
@Autowired
private UserService service;
...
}


ในตัวอย่าง UserAction เป็น Struts action และเป็น Spring bean ด้วย(จาก Annotation Service ของ Spring) ส่วน UserService คืออินเทอร์เฟสคลาสซึ่งอิมพลิเม็นท์อาจเป็น Session bean หรือเป็น POJO Service ที่อยู่ในฝั่ง web เองก็ได้ขึ้นกับการคอนฟิค Spring ว่าจะให้ฉีดอะไรลงมา

เข้าเรื่องการเชื่อม Spring เข้ากับ Struts มีสองวิธี

1. ActionSupport Classes
เริ่มด้วยวิธีง่ายๆก่อน Spring ได้เตรียม WebApplicationContextUtils เพื่อดึง bean ภายใต้ Spring context อีกที

ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
MyService service = (MyService) ctx.getBean("myService");


ต้องคอนฟิค Spring context ใน web.xml ด้วย

<web-app>
...
<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<context-param><!-- Doesn't need but config for mapping other config -->

<param-name>contextConfigLocation</param-name><!-- This parameter is specified as a list of paths -->

<param-value>

/WEB-INF/applicationContext.xml

</param-value>

</context-param>

</web-app>


เพื่อให้ง่ายต่อการใช้งาน Spring ได้เตรียมคลาสสำหรับ Struts action พื้นฐานต่างๆไว้คือ ActionSupport, DispatchActionSupport, LookupDispatchActionSupport และ MappingDispatchActionSupport คลาสเหล่านี้มีเครื่องมืออำนวจความสะดวกต่างๆเช่นเมธตอด getWebApplicationContext() เพื่อเรียก WebApplicationContext

public class UserAction extends DispatchActionSupport {

public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
if (log.isDebugEnabled()) {
log.debug("entering 'delete' method...");
}
WebApplicationContext ctx = getWebApplicationContext();
UserManager mgr = (UserManager) ctx.getBean("userManager");
// talk to manager for business logic
return mapping.findForward("success");
}
}


จะเห็นได้ว่าวิธีนี้เรียบง่ายแต่ไม่ค่อยมีพลังเท่าไหร่ ซึ่งในวิธีหลังนี้เราจะสร้าง Struts action ให้เป็น Spring bean ทำให้สามารถใช้ความสามารถต่างของ Spring กับ Action ของเราได้เช่นทำ Dependency Injection, AOP ฯลฯ

2. ContextLoaderPlugin
วิธีนี้ Struts action จะถูกสร้างและจัดการโดย Spring ทำให้สามารถใช้ความสามารถต่างๆของ Spring กับ Struts action ของเราได้

Spring เตรียม plugin สำหรับ Struts เพื่อโหลด Spring context โดยคอนฟิค struts-config.xml ดังนี้

<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/>


กรณีไม่กำหนดไฟล์คอนฟิค Spring จะใช้ค่าพื้นฐานดังนี้ /WEB-INF/${action}-servlet.xml ซึ่ง action คือชื่อ servlet-name ของ ActionServlet ของ Struts ใน web.xml นั่นเอง หากต้องการระบุไฟล์คอนฟิคก็ทำได้ดังนี้

<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/action-servlet.xml,/WEB-INF/applicationContext.xml"/>
</plug-in>


หลังจากคอนฟิค plugin เสร็จขั้นตอนต่อไปเป็นการแม็พระหว่าง Struts กับ Spring มีสองวิธี แต่ทั้งคู่ใช้วิธีการแม็พที่เหมือนกันคือ Struts จะใช้ action path แม็พเข้ากับ bean name ของ Spring

struts-config.xml
<action path="/users" .../>


action-servlet.xml
<bean name="/users" class="com.whatever.struts.UserAction" .../>


2.1 DelegatingRequestProcessor
วิธีนี้อาศัยการปรับแต่ง controller ของ Struts โดยเซ็ต processorClass ใหม่ซึ่ง Spring เตรียมไว้คือ DelegatingRequestProcessor

struts-config.xml
<controller>
<set-property property="processorClass"
value="org.springframework.web.struts.DelegatingRequestProcessor"/>
</controller>


action path จะถูกแม็พเข้ากับ bean name ของ Spring การคอนฟิค action ของ Struts จึงไม่จำเป็นต้องกำหนด action type

<action path="/user" type="com.whatever.struts.UserAction"/>
<action path="/user"/><!-- type ไม่จำเป็น -->


ถ้าใช้ Struts module ต้องเติม module prefix หน้า bean name ของ Spring ด้วยเช่น <action path="/user"/> ที่มี module ชื่อ admin จะต้องกำหนด bean name ดังนี้ <bean name="/admin/user"/>

ถ้าใช้ Tiles กับ Struts ให้เปลี่ยน DelegatingRequestProcessor ไปใช้ DelegatingTilesRequestProcessor

2.2. DelegatingActionProxy
ใช้กรณีที่มีการปรับแต่ง controller ด้วย RequestProcessor ตัวอื่นทำให้ไม่สามารถใช้ DelegatingRequestProcessor หรือ DelegatingTilesRequestProcessor ได้ ทางแก้ก็คือแก้ไข RequestProcessor ใหม่เลียนแบบ DelegatingRequestProcessor หากไม่สามารถทำได้ ให้ใช้ DelegatingActionProxy เป็น action type แทนดังนี้

<action path="/user" type="org.springframework.web.struts.DelegatingActionProxy"/>


จบการเชื่อม Spring กับ Struts ขอสรุปอีกทีเป็นตัวอย่างการใช้วิธี 2.1 ร่วมกับ Spring Annotation
web.xml คอนฟิค Struts ตามปกติ

struts-config.xml
คอนฟิค plugin
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/applicationContext.xml"/>
</plug-in>

คอนฟิค controller
<controller>
<set-property property="processorClass"
value="org.springframework.web.struts.DelegatingRequestProcessor"/>
</controller>

คอนฟิค action
<action path="/user" ...>
<forward name="success" .../>
<forward name="failure" .../>
</action>


applicationContext.xml
<context:component-scan base-package="com.whatever.struts.actions" /> <!-- ระบุแพคเกจที่จะให้ Spring เข้ามองหา -->
<jee:remote-slsb id="userService" business-interface="com.whatever.ejb.service.UserService" jndi-name="UserServiceBean/remote" /><!-- lookup หา EJB -->


com.whatever.struts.actions.UserAction.java
@Service("/users") // สร้าง Struts Action ให้เป็น Spring bean และแม็พเข้ากับ action path ของ Struts
public class UserAction extends Action {
@Autowired
private UserService service;
...
}


ใช้ maven กำหนด library ที่จะใช้
pom.xml
...
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-core</artifactId>
<version>${org.apache.struts}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-taglib</artifactId>
<version>${org.apache.struts}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-struts</artifactId>
<version>${org.springframework.version}</version>
<exclusions>
<exclusion>
<groupId>struts</groupId>
<artifactId>struts</artifactId>
</exclusion>
</exclusions>
</dependency>
...


สั้นๆง่ายๆ แต่มีง่ายกว่านี้คือใช้ Spring MVC ซะ ชาบูๆ

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

Workaround and Fixed SWT XPCOM error in Eclipse helios(3.6) on Ubuntu lucid (10.04)

ตั้งแต่ลง Ubuntu 10.04 เปิด eclipse สร้าง workspace ใหม่ ขณะกำลังโหลด splashscreen เจอมันปิดตัวเองเฉยเลย ลองเรียก eclipse ด้วย workspace เดิมอีกรอบก็ไม่มีปัญหา

Error message
Error while informing user about event loop exception:
org.eclipse.swt.SWTError: XPCOM error -2147467262
at org.eclipse.swt.browser.Mozilla.error(Mozilla.java:2089)
at org.eclipse.swt.browser.Mozilla.unhookDOMListeners(Mozilla.java:2453)

หลังจากเปิด Eclipse ได้สั่งสร้าง project ปัญญาอ่อนธรรมดา (new Java Project) กด finish พระเจ้า eclipse ค้าง ต้องสั่ง kill process กันเลยทีเดียวแต่เปิดใน workspace ดูจะพบ project ที่สร้างเสร็จแล้ว หลังจากนั้นเปิด Eclipse ใหม่ขึ้นมา import project เข้ามาลองสร้าง project ใหม่ก็ไม่เจอปัญหาอะไร ปัญหานี้จำได้ว่าไม่เจอ error message

อีกปัญหาลองเปิด JSP โดยใช้ web page editor เพื่อสร้างและแก้ไข JSP แบบ WYSIWYG ปกติไม่เคยเปิดใช้เลย กำลังจะโม้ให้คนอื่นหันมาใช้ eclipse ปรากฎว่าพอคลิ๊กที่ preview ก็เจอป๊อบอัพ error
Unhandled event loop exception
XPCOM error -2147467259

จริงๆแล้ว error นี้อาจเจอบน Eclipse เวอร์ชั่นก่อนหน้านี้ด้วยแต่ไม่ได้เปิดใช้ web page editor เลยไม่เจอ
Error message
!MESSAGE Unhandled event loop exception
!STACK 0
org.eclipse.swt.SWTError: XPCOM error -2147467259
at org.eclipse.swt.browser.Mozilla.error(Mozilla.java:2347)
at org.eclipse.swt.browser.Mozilla.initXULRunner(Mozilla.java:2310)


ทางแก้ที่หาๆมา
ปัญหาแรกก่อน เจอมาว่าให้เซ็ต XULRunnerPath ใน eclipse.ini
-Dorg.eclipse.swt.browser.XULRunnerPath=/usr/lib/xulrunner

แต่ /usr/lib/xulrunner มันไม่มีอยู่ในเครื่องนี่หว่า ที่มีอยู่คือ /usr/lib/xulrunner-1.9.2.8 ลองใช้ xulrunner-1.9.2.8 ก็เจอปัญหาเดิม
งั้นใช้ตามเค้า /usr/lib/xulrunner ปัญหาแรกหมดไปคงเพราะ eclipse หา XULRunner ไม่เจอมันเลยใช้ engine ของตัวเองแทน
ดังนั้นคิดว่า Eclipse เองรู้จัก XULRunner อยู่แล้วการไปแก้เป็นพาร์ทที่ไม่มีอยู่จริงเช่น /usr/lib/xulrunner ก็เพื่อให้ eclipse ใช้ engine ของตัวเองแทน

อีกวิธีในการแก้ปัญหานี้คือการลบ eclipse ภายใต้ ~/.mozilla ก่อนที่จะสร้าง workspace
rm -Rf ~/.mozilla/eclipse/

การแก้ปัญหาแรกด้วยการเซ็ตด้วยพาร์ทที่ผิดนี้จะมีปัญหากับการแก้ปัญหาที่สามด้วย ดังนั้นทางแก้ของปัญหานี้ใช้การลบ eclipse ภายใต้ ~/.mozilla ดีทีสุดหรือไม่ก็ยอมให้มันปิดตัวเองแล้วเรียกใหม่

ปัญหาที่สอง eclipse ค้างตอนสร้าง โปรเจคแรกใน workspace (สร้างโปรเจคถัดไปจะไม่เจอปัญหาแล้ว)
ไม่พบทางแก้ปัญหา คงต้องยอมค้าง แต่ปกติสร้าง project ผ่าน M2Eclipse plugin อยู่แล้ว(สร้าง project โดยใช้ Maven) จะไม่เจอปัญหานี้ หรือไม่ก็ทำยังไงก็ได้ให้มีสักโปรเจคอยู่ใน workspace นี้เช่นการ import project เข้ามาก็ช่วยได้

ปัญหาที่สาม เรื่อง web page editor เจอก็ตอนจะโม้ชาวบ้านนี่แหละพบว่าเป็นปัญหาเรื่องขาด libstdc++5 ซึ่งไม่มีบน repository ของ Ubuntu 10.04 ด้วยต้องไปเอาจากเวอร์ชั่น Jaunty มาใช้แทน หรือไม่ก็เอา package จาก debian มาใช้ก็ได้เหมือนกัน บน Ubuntu โดนเอาออกตั้งแต่ Karmic แล้ว
wget http://mirrors.kernel.org/ubuntu/pool/universe/g/gcc-3.3/libstdc++5_3.3.6-17ubuntu1_amd64.deb
wget http://mirrors.kernel.org/ubuntu/pool/universe/g/gcc-3.3/libstdc++5_3.3.6-17ubuntu1_i386.deb

สำหรับ 32-bit
sudo dpkg -i libstdc++5_3.3.6-17ubuntu1_i386.deb


สำหรับ 64-bit
บังคับลง i386 ก่อน
sudo dpkg --force-architecture -i libstdc++5_3.3.6-17ubuntu1_i386.deb

เสร็จแล้วย้าย lib ไปวางไว้ให้ถูกที่
sudo mv /usr/lib/libstdc++.so.5* /usr/lib32/

หมายเหตุ ขั้นตอนข้างบนนี้ใช้ dpkg -x แตก lib แล้วย้ายไปลง /usr/lib32/ ก็ได้เหมือนกัน

ต่อจากนั้นก็ลง package ของ 64-bit
sudo dpkg -i libstdc++5_3.3.6-17ubuntu1_amd64.deb

ตรวจสอบว่า lib ได้ตั้งตั้งไปเรียบร้อยแล้ว
sudo updatedb
locate libstdc++.so.
จะได้ตำแหน่งของ libstdc++.so ดังนี้
/usr/lib/libstdc++.so.5
/usr/lib/libstdc++.so.5.0.7
/usr/lib/libstdc++.so.6
/usr/lib/libstdc++.so.6.0.13
/usr/lib32/libstdc++.so.5
/usr/lib32/libstdc++.so.5.0.7
/usr/lib32/libstdc++.so.6
/usr/lib32/libstdc++.so.6.0.13

ก่อนใช้ eclipse ให้เคลียร์ workspace ทิ้งก่อนด้วยโดยลบ .metadata ที่อยู่ภายใต้ workspace ทิ้ง และลบ eclipse ภายใต้ ~/.mozilla ก่อน
rm -Rf ~/workspace/.metadata/
rm -Rf ~/.mozilla/eclipse/

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

Inconsistent lib between VLC and MPlayer

ก่อนหน้านี้ได้ลง VLC 1.1.3-0+exp0 จาก ppa:n-muench/vlc ปรากฎว่าตอนเรียก mplayer มี error

mplayer: relocation error: mplayer: symbol codec_wav_tags, version LIBAVFORMAT_52 not defined in file libavformat.so.52 with link time reference
ก็ไปค้น package ดูพบว่าได้ลง libavformat-extra-52 4:0.6-2ubuntu1~ppa1~lucid1 จาก ppa:n-muench/vlc ไปเรียบร้อยแล้วส่วน mplayer 2:1.0~rc3+svn20100416-0lucid3 ลงจาก ppa:medibuntu-maintainers/ppa มันก็ต้องการ libavformat เหมือนกัน

ถ้าจะบังคับมาใช้ libavformat ของ ppa:medibuntu-maintainers/ppa ก็อดใช้ VLC อีก หาไปหามามีคนแนะนำให้ใช้ mplayer จาก ppa:rvm/mplayer แทนก็จัดการติดตั้ง PPA ก่อน
#sudo add-apt-repository ppa:rvm/mplayer && sudo apt-get update
เสร็จแล้วก็ลง mplayer
แถม SMPlayer ไปอีกตัว
#sudo add-apt-repository ppa:rvm/smplayer && sudo apt-get update
เสร็จแล้วก็ติดตั้ง MPlayer กับ SMPlayer
#sudo apt-get install mplayer smplayer
เท่าที่ดูการคอมไฟล์ mplayer คิดว่าได้บิวด์ lib ที่เกี่ยวข้องรวมมาเรียบร้อยแล้ว ก็จะได้ smplayer กับ mplayer เวอร์ชั่นใหม่กว่า ppa:medibuntu-maintainers/ppa มาใช้แล้ว

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

Update Ubuntu Software Center

พอดีเปลี่ยน PPA ของ package ที่ลงเป็นที่ใหม่แล้ว Ubuntu Software Center มันยังจำ PPA ที่ลบไปอยู่
ใน Ubuntu Software Center ก็จะเจอ PPA สองที่ที่มี package เดียวกัน เดี๋ยวเวลาไล่ดู package ทีหลังเดี๋ยวจะงงซะอีกว่า package ที่ลงนี้มาจาก PPA ตัวไหน วิธีงายๆเลยใช้คำสั่ง
#sudo update-software-center


เอาที่มาหน่อยตอนแรกว่าจะหาว่าคอนฟิกของ Ubuntu Software Center อยู่ที่ไหนเพื่อเข้าไปลบตรงๆ เพราะก่อนหน้าที่ทั้งลบใน Software Source ก็แล้ว, ใช้ Ubuntu tweek สั่ง purge PPA ก็แล้ว, ลบ lists ใน /var/lib/apt ก็แล้วก็ยังไม่ออก ไปเจอว่า Ubuntu Software Center มันเรียกจาก /usr/share/software-center/software-center เสร็จแว๊บๆจอ update-software-center อยู่ที่เดียวกันเลยลองซะเลย รออัพเดทสักพักนึง ก็ได้ผลเป็นอย่างดี

ปล.ย้าย PPA จาก ppa:c-korn/vlc เป็น ppa:n-muench/vlc เพื่อจะลง vlc เวอร์ชั่นใหม่ ไม่อยากคอมไพล์เองแล้วต้องตามอัพเดทอีก
vlc จาก repository ของ Ubuntu เองอัพเดทช้าแรงงง ปัจจุบันเวอร์ชั่น 1.1.3 แล้ว

วันจันทร์ที่ 3 พฤษภาคม พ.ศ. 2553

คอนฟิก proxy ให้ svn

ให้แก้ไขไฟล์ ~/.subversion/servers ด้วยคำสั่ง
#gedit ~/.subversion/servers
เพิ่มรายละเอียดลงไปในส่วนของ [global] ตัวอย่าง
[global]
http-proxy-host = myproxyserver
http-proxy-port = 8080
http-proxy-username = foo
http-proxy-password = bar

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

EJB 3.0 @Stateless @EJB @Resource and JNDI clarity

EJB 3.0 @Stateless @EJB @Resource and JNDI clarity
การกำหนดชื่อของ Service
  • property name เทียบกับ ejb-jar.xml คือ ejb-name

  • property mappedName ใช้กำหนด global JNDI name
ตัวอย่าง
@Stateless // name() defaults to "A2"
public class A1 implements A { ... }

@Stateless(name="A2", mappedName="A2Global") // force product-specific JNDI name to "A1Global"
public class A2 implements A { ... }

การเรียกใช้
  • property name เทียบกับ ejb-jar.xml คือ ejb-ref-name ไว้สำหรับใช้เรียกผ่าน java:comp/env

  • property beanName เทียบกับ ejb-jar.xml คือ ejb-link

  • property mappedName เทียบกับ ejb-jar.xml คือ mapped-name ไว้เรียก global JNDI name
ตัวอย่าง
ภายใต้ application เดียวกัน(อยู่ภายใต้ ear เดียวกัน)
@EJB
private A a;

@EJB(beanName="A2")
private A a;

ต่าง application กัน
@EJB(mappedName="A1/local") // for JBoss
private A a;

@EJB(mappedName="A2Global")
private A a;

หมายเหตุ mappedName เป็น product-specific JNDI name ฉะนั้นระวังด้วยหาก application ต้องการความสามารถ portability ซึ่งใน EJB 3.1 ที่มีการกำหนดเรื่อง portable JNDI name ไว้ แนะนำให้ใช้ property lookup แทน

อ้างอิง
forums.sun.com
What is the relationship between @EJB and ejb-ref/ejb-local-ref?
Partial Deployment Descriptors

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

HTTP method in REST protocol with Dojo's JsonRestStore

มาดูกันว่า dojox.data.JsonRestStore ใช้ HTTP method ไหนทำอะไรบ้าง

  • HTTP GET request to retrieve data

  • PUT request to change items

  • DELETE request to delete items

  • POST request to create new items

JsonRestStore ของ Dojo ทำงานคล้ายกับ Datasource ฝั่ง server การเปลี่ยนแปลงข้อมูลบน JsonRestStore (CRUD) จะส่งการเปลี่ยนแปลงนั้นผ่าน REST ไปยัง server ให้เลย ดังนั้นจึงสะดวกมากที่จะเขียนโปรแกรม CRUD โดยใช้ REST

เบื้องหลัง JsonRestStore นั้นใช้ dojox.rpc.JsonRest ทำหน้าที่ REST service นั่นเอง
ส่วนรายละเอียดและการใช้งานสามารถอ่านเพิ่มจาก RESTful JSON + Dojo Data

วันพุธที่ 7 เมษายน พ.ศ. 2553

หลากหลายวิธีใช้ XHR ข้าม domain ด้วย Dojo toolkit

เกริ่นก่อน เดิมการใช้ dojo.xhr-() น่าจะรวมถึงใช้ XMLHttpRequest ตรงๆด้วย จะไม่สามารถเรียก resource หรือ service ต่าง domain กันได้เช่น

จากหน้า http://foo.com/index.html ต้องการเรียกไปที่ http://bar.com/xxx แบบนี้จะไม่สามารถทำได้

เมื่อมีปัญหาก็ต้องมีทางออก วิธีต่อไปนี้เป็นวิธีแก้ไขสำหรับ Dojo toolkit มีหลายๆวิธีดังนี้

สำหรับจาวาสคริปท์เพียวๆก็น่าจะมีเหมือนกันแต่พอดีใช้ framework นี้อยู่ ใช้จาวาสคริปท์บน framework มันใช้ง่ายดี ไม่ฮาร์ดคอเท่าเพียวจาวาสคริปท์ ที่ต้องกังวลอีกหลายๆเรื่องเช่น cross-browser เป็นต้น

วันจันทร์ที่ 8 มีนาคม พ.ศ. 2553

แก้ปัญหา GPG Error เวลา Update Ubuntu

เมื่อสั่ง update package index ด้วย Update Manager หรือ apt-get update แล้วเกิด error ดังเช่น
W: GPG error: http://ppa.launchpad.net karmic Release: The following signatures were invalid: BADSIG 584BD6410AAFAD78 Launchpad merlwiz79

วิธีแก้ไข
วิธีแรก ลอง update PGP key ใหม่ก่อนด้วยคำสั่ง
#sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 584BD6410AAFAD78

ตำแหน่งสีแดงให้แทนด้วย key ที่เตือนออกมา ถ้า add key ใหม่ได้ไม่มีปัญหา ก็จบไป แสดงว่า PGP key เปลี่ยน หลักจากนั้นสามารถ update package ได้เหมือนปกติ

แต่ถ้ามีข้อความ
gpg: requesting key 0AAFAD78 from hkp server keyserver.ubuntu.com
gpg: key 0AAFAD78: "Launchpad merlwiz79" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
แสดงว่า PGP key ไม่ได้เปลี่ยนแปลงให้แก้ไขด้วยวิธีที่สอง

วิธีที่สอง
ลบ package index ใน /var/lib/apt/lists/ แล้วให้ update ใหม่ ด้วยคำสั่งดังนี้
#sudo -i
#apt-get clean
#cd /var/lib/apt
#mv lists lists.old
#mkdir -p lists/partial
#apt-get clean
#apt-get update

เมื่อทำเสร็จแล้วจะลบ /var/lib/apt/lists.old/ ที่ backup ไว้ก็ได้

วันอาทิตย์ที่ 17 มกราคม พ.ศ. 2553

Sorting MP3 for Honda CIVIC 2010

ตาม topic เลยคืออยากให้เครื่องเสียงในรถเล่นไฟล์ MP3 จาก thumb drive ให้เหมือนกับที่เรียงในคอมฯ อุตส่าห์เปลี่ยนชื่อไฟล์เป็น 01, 02, ... ก็แล้ว เอามาเสียบฟังก็ยังไม่ยอมเล่นไฟล์เรียงตามตัวอักษร (alphabetical sort) เหมือนที่เห็นในคอม
ค้นไปเรื่อยๆเจอกับ FATSort ลงก็ง่ายๆเลย บน Linux - Ubuntu เปิด terminal ขึ้นมาสั่งติดตั้งด้วยคำสั่ง
#sudo apt-get install fatsort

โปรแกรมนี้จะทำหน้าที่เรียง FAT table ของไฟล์ใน thumb drive ตามตัวอักษร (alphabetical sort) แบบที่เห็นในคอม ซึ่งเครื่องเสียงในรถมันอ่านจาก FAT table นี่แหละ
เสียบ thumb drive เข้าไป copy เพลงลง thumb drive จะสร้างโฟล์เดอร์แยก album ก็ตามใจ หรือจะรวมๆเพลงเพราะๆไว้ในโฟล์เดอร์นึงแล้วเปลี่ยนชื่อไฟล์ด้วย 01, 02 ... เพื่อเรียงเพลงตามต้องการ
เสร็จแล้วก็ถึงคิวพระเอกของเรา FatSort ก่อนอื่นต้อง unmount thumb drive ก่อน ถ้าเทียบกับบน Windows คงเป็นการ save to remove storage device ก่อนจะถอด thumb drive (คนใช้ linux อยู่แล้วคงหาตำแหน่งของ device drive เป็นนะ ถ้าไม่เป็นก็ถามมา)
#umount /dev/sdc1

แล้วก็ FatSort
#sudo fatsort /dev/sdc1


แค่นี้ก็เรียบร้อย
สำหรับคนใช้ Windows ก็จะมีโปรแกรมสำหรับ Sorting FAT table ด้วยเหมือนกันชื่อ DriveSort รายละเอียดการใช้งาน Fixing the Honda Insight USB MP3 Sort Order

ขอบ่น Honda เรื่องการแก้ไขเสียง ต็อกๆ จากเครื่องยนต์หน่อยเหอะ ได้ยินคำล่ำลือเหมือนกันตอนแรกก็คิดว่าเป็นกันเยอะจริงหรอ ใครมาใส่ร้าย Civic สุดสวยของเรารึเปล่า ได้ข่าวเครื่องรุ่น 2010 แก้ปัญหาแล้ว ก็อุตส่าห์รอจนถอย Civic 2010 ออกมาตอนแรกประสบการณ์เยี่ยมจริงเครื่องนิ่มมากอัตราเร่งก็ดี ขับไปได้ 600 km. กว่าๆ มาแระต็อกๆ ไม่นึกว่าจะโดนกับตัวเองเซ็งโครต ขนาดช่วงนี้เห็นว่าเป็นช่วงรันอินขับแบบไม่เหยียบแล้วนะ

วันพุธที่ 6 มกราคม พ.ศ. 2553

BPEL or BPMN

เป็นอีกหนึ่งอย่างที่สนใจ หากมีเวลาว่าจะลองเล่นดูสักหน่อย แรกๆอ่านก็สับสนระหว่าง BPEL กับ BPMN ไปเจอความเห็นหนึ่ง เลยเอามาลงไว้ Re: Forking/contributing จากเรื่อง Open-Source BPEL takes the form of 'RiftSaw'
Depends on what you want. If you need to orchestrate services or build coarse grained WSDL services as a function of smaller grained WSDL services, then BPEL is the most obvious choice.

But if you need to manage human tasks or make the bridge between development and non technical people, then jPDL and BPMN are better suited.


Tom Baeyens
jBPM


อีกความเห็น Why use BPMN for BPEL? ของ Michael Rowley
ได้อธิบายว่าเนื่องจาก มาตราฐานของ WS-BPEL 2.0 ไม่ครอบคลุมถึง เครื่องหมาย, หรือสัญลักษณ์ต่างๆ(natation) และคงเป็นไปไม่ได้ที่จะสร้าง business process โดยเขียน BPEL ตรงๆด้วย XML ด้วยเหตุนี้ผู้ผลิตเครื่องมือ และนักพัฒนา BPEL จึงใช้ รูปภาพขึ้นมาแทน แต่เนื่องจากไม่มีมาตราฐานรองรับทำให้เครื่องมือของแต่ละเจ้าใช้ สัญลักษณ์แตกต่างกัน ซึ่งตรงนี้นี่เองที่ BPMN เข้ามาตอบโจทย์ตรงที่ทำความเข้าใจง่ายผู้ที่ไม่รู้จัก BPEL เลยหรือไม่รู้จัก BPMN เลย ก็สามารถทำความเข้าใจได้ และเมื่อใช้ BPMN ออกแบบเสร็จแล้วในการ implement ค่อยให้ผู้ที่เชี่ยวชาญ BPEL แต่ละค่ายไป implement ต่อไป ลองเข้าไปดูตามลิ้งค์มีตัวอย่าง BPEL ของ ActiveVOS, Eclipse BPEL Designer และ Oracle’s BPEL Process Manager จะเห็นว่ามีการใช้สัญลักษณ์ที่แตกต่างกัน

ปล.เหมือนคุ้นๆว่า Oracle มีเครื่องมือที่เปลี่ยน BPMN เป็น BPEL ได้ เคยเห็นแว็บๆนานแล้ว(ไม่แน่ใจ)