วันอังคาร, พฤษภาคม 26, 2558

เซตอัพ Maven, Spring Boot (spring-boot:run) กับ JRebel

   มีโปรเจคหนึ่งของผมเป็น java web application คุมด้วย maven แล้วผมอยากจะเรียกคำสั่ง mvn spring-boot:run พร้อมใช้งาน jrebel ไปด้วย

1. สร้างไฟล์ rebel.xml ก่อน เอาไว้ที่ src/main/resources
2. อ้างอิงตามเอกสารของ zeroturnaround เราใส่ content ของไฟล์ตามนี้
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">
  <classpath>
    <dir name="[absolute path to]/target/classes/"/>
  </classpath>
</application>

4. หากมี jar file ที่อยากให้ jrebel reload ให้ด้วย (jar library ที่อยากให้มัน reload คือ jar ที่ทำขึ้นมาใช้จากอีกโปรเจคหนึ่ง)
ก้อเพิ่มแบบนี้

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">
  <classpath>
    <dir name="[absolute path to]/src/main/resources/"/>
    <dir name="[absolute path to]/target/classes/"/>
    <jar name="[absolute path to a jar file].jar"></jar>
  </classpath>
</application>

path ไปยัง jar library ผมใช้วิธีชี้ไปที่ .m2/repository ,ที่ maven โหลดมา cache ในเครื่องเรา
เช่น /Users/dahoba/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4.jar

5. เวลา execute mvn spring-boot:run เพิ่ม option แบบนี้

$ mvn spring-boot:run -Drun.agent=[/Users/dahoba/app/jrebel-nightly/jrebel]/jrebel.jar

- เพิ่ม -Drun.agent เข้าไป
- path ใน [ ] คือ absolute path ไปยัง jrebel.jar ที่ติดตั้งอยู่ในเครื่อง

เท่านี้เอง ใช้งาน jrebel ให้มันช่วย reload โปรเจค ที่เป็น spring-boot + maven ได้แล้ว



SOLVED : Sublime Text's plugin, Markdown HTML Preview open a blank window in Chrome under OSX

    Today, I'm just setup Sublime Text 3 and install MarkdownEditing, Markdown HTML Preview. I'm editing one of my markdown file and try to preview it by execute.

Ctrl+shift+p > Markdown Preview: Preview in Browser 

It's just open another blank window of Chrome browser, weird.

    I'm notice that I install Chrome.app in another disk (e.g. /Volumes/Macintosh HD). So, I try to config the markdown preview.

Open config file by go to menu Preferences > Package Settings > Markdown Preview > Settings - User. This will open the MarkdownPreview.sublime-settings file.

Add this configuration line (If there's only one config, just delete the comma at the end of the line) then Save it.

{
    "browser": "/Volumes/Macintosh HD/Applications/Google Chrome.app",
    ...
}

 
   Case closed :D the Markdown HTML Preview work as I expected.

วันพฤหัสบดี, พฤษภาคม 14, 2558

OSX: เปลี่ยน JDK version ง่ายด้วยคำสั่งเดียว; Switch JDK version easily in one command.


    เครื่อง macbook ของผมติดตั้ง Java (JDK) เอาไว้ 3 version 1.6, 1.7 และ 1.8 โปรแกรมที่พัฒนาตัวไหนเก่าหน่อยก็ต้องใช้ JDK 6 ถ้าใหม่ขึ้นมาอีกหน่อยก็จะใช้ JDK 7 สำหรับ  project ที่จะทำต่อจากนี้ก็จะเริ่มที่ JDK 8 เลย เพราะ JDK 6, JDK 7 มัน end of life ไปแล้ว, Oracle เลิก support แล้ว

ถ้าอยากรู้ว่าตอนนี้ macbook เราติดตั้ง JDK อะไรไว้บ้าง ใช้คำสั่งนี้

$ /usr/libexec/java_home -V


Matching Java Virtual Machines (5):

1.8.0_45, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home

1.8.0_31, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home

1.7.0_25, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home

1.6.0_65-b14-462, x86_64: "Java SE 6" /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

1.6.0_65-b14-462, i386: "Java SE 6" /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home


เราสามารถให้มันแสดง JAVA_HOME ของแต่ละ version ออกมาได้ด้วยคำสั่งแบบนี้ 

$ /usr/libexec/java_home -v 1.6

/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

เปลี่ยนเลข 1.6 เป็น version ที่ต้องการ ในกรณีในเครื่องผม เลขที่ใส่ได้ก็จะมี 1.6 1.7 หรือ 1.8

จากคำสั่งแบบนี้ ทำให้เราสามารถเซ็ต variable JAVA_HOME ให้กับแต่ละ project ที่เราใช้ได้
...
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
...

แล้วก็พบว่า ใน macbook แค่เราเปลี่ยน variable JAVA_HOME เวลาเรา execute java มันก็จะเป็น version ตาม JAVA_HOME เลย

เปลี่ยน JDK version ง่ายด้วยคำสั่งเดียว

ถ้าอยากทำคำสั่งให้เปลี่ยน JDK version ง่ายๆ ก็ใช้วิธีกำหนด alias เอาไว้
จะสร้างไฟล์ ~/.profile หรือ ~/.zshrc ถ้าคุณใช้ ohmyzsh เหมือนผม

ใส่ 3 บรรทัดนี้เข้าไป
...
alias jdk6="export JAVA_HOME=\$(/usr/libexec/java_home -v 1.6);echo '... Using JDK 6'"
alias jdk7="export JAVA_HOME=\$(/usr/libexec/java_home -v 1.7);echo '... Using JDK 7'"
alias jdk8="export JAVA_HOME=\$(/usr/libexec/java_home -v 1.8);echo '... Using JDK 8'"
...

พิมพ์คำสั่งนี้ เพื่อเริ่มใช้งาน alias ที่เพิ่งเพิ่มเข้าไปได้เลย

$ . ~/.zshrc

หรือ 

$ . ~/.profile

เวลาต้องการเปลี่ยน JDK version ก็แค่ execute command jdk6, jdk7 หรือ jdk8

$ jdk8
... Using JDK 8
$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

$ jdk7
... Using JDK 7
$ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

$ jdk6
... Using JDK 6
$ java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

... Happy coding ^ ^

Android TIPS: Using find command solving Titanium Backup backup problem.


TIPS: HOWTO find the zero-bytes filename under folderA then copy those files which have the same name from folderB to a new folder.

TL;DR

    เจอปัญหาเมื่อวานนี้ ผมอยากจะ flash rom ของ one plus one temasek's cm12.1 by katinatez
katinatez บอกว่าควรจะ clean flash เสมอ ซึ่งก็คือต้อง wipe factory reset+wipe dalvik cache
    ผมจึงทำการ backup apps ทั้งหมดด้วย Titanium Backup Pro ซึ่งใน post ที่แล้ว. หลังจาก clean flash เสร็จ หายนะก็มาเยือน พบว่า user apps หลายตัว (150 ตัว) ม้นกลายเป็น zero-bytes T_T อาการก็คือ กด restore แล้ว มันไม่มีวันทำเสร็จ

  ทางแก้เท่าที่นึกออกมีสองทาง คือ

1. ไล่ลงใหม่จาก Play Store  วิธีนี้เสียเวลามาก จึงนึกถึงวิธีต่อมา
2. หาทางเอา app backup กลับมา

   โชคดีที่มี backup ของ Titanium Backup ซึ่งสำรองออกมาไว้ใน hard disk เนื่องจากเพิ่ง convert partition เป็น F2FS ไป แต่ทีนี้จะทำอย่างไรละ ถึงจะ copy files ชื่อเดียวกันที่มี size 0 ใน backup  -ของ device จาก backup ที่อยู่ใน harddisk ออกมาได้ โดยไม่ต้องมานั่งไล่ทีละไฟล์

 ค้นไปมาได้คำสั่ง linux ใช้ find, xargs และ cp

Solution 
ขั้นตอน

1. Folder A (i.e.: titanium) มี backup folder ที่มีไฟล์ apk สมบูรณ์;

2. Folder B (i.e.: titanium2) backup folder ใน device ที่ apk เสียหาย

เอาออกมาจาก device ด้วยคำสั่ง
$ adb pull /sdcard/TitaniumBackup titanium2

3. ใช้คำสั่ง แบบนี้เพื่อหาไฟล์ที่มี size 0

$ find . -name '*apk.gz' -size 0
...
./at.mroland.android.apps.nfctaginfo-fbe0527a89f99a3d74bc385b51a294e2.apk.gz
./com.android.cellbroadcastreceiver-587c950124ea3e2d04bec29d1d1ca69d.apk.gz
./com.android.cellbroadcastreceiver-d7a84dcdb56f2c8ccc7468f53879e64d.apk.gz
./com.android.facelock-7b306c42af02a5de1d326f9ae42356a5.apk.gz
./com.android.facelock-a5d85c816569809e5c7ec5998ad79da4.apk.gz
./com.android.vending-cdc700d6cfb743abce9e22dd3fd16712.apk.gz
...

ไฟล์ backup ของ Titanium Backup จะมี extension เป็น apk.gz

4. เมื่อเจอแล้วว่าไฟล์ไหน size 0 บ้าง ทีนี้จะให้มันไป copy จาก folder ที่มี apk สมบูรณ์ไปพักไว้ที่ folder C ก่อนนำไปใช้

$ cd titanium2

$ mkdir recoverApp

$ find . -name '*apk.gz' -size 0 | xargs -I{} cp titanium/{} recoverApp/

เราจะได้ apps ที่สมบูรณ์มารออยู่ที่ recoverApp แล้ว


วันอังคาร, พฤษภาคม 12, 2558

แปลง partition เป็น F2FS แบบข้อมูลไม่หาย | Convert Android partitions to F2FS without data lost.

เรื่องมันมีที่มา

    ตอนนี้ใช้ Oneplus One อยู่ ลง ROM CM 12.1 เป็น unofficial build ของ temasek
ตัวนี้ [ROM][Bacon][5.1.1][Linaro 4.9 & 5.1]Temasek's UNOFFICIAL Build by katinatez วันหนึ่ง version 11.2 มันถูก build ออกมา พอผมเอามา flash  แล้วมันเกิด bootloop ใช้งานต่อไม่ได้ ไปนั่งไล่อ่าน changelog นาย katimatez เค้าไป merge เอา feature เกี่ยวกับ F2FS partition เข้ามารวมด้วย

    F2FS เลยเป็นตัวต้องสงสัย ว่าจะทำให้เรา boot ไม่ผ่าน เลยต้องไปหาว่าจะแปลง partition ของเราให้เป็น F2FS ได้ยังไง

The motive for F2FS was to build a file system that from the start, takes into account the characteristics of NAND flash memory-based storage devices (such as solid-state diskseMMC, and SD cards), which are widely used in computer systems ranging from mobile devices to servers.
F2FS on Wikipedia

ตาม FAQ ของ rom นี้ บอกไว้ว่า มันทำงานได้กับ ext4 เช่นกัน ซึ่งเราไม่ได้ใช้ F2FS อยู่แล้ว ก็ใช้งานได้มาตั้งแต่ version 10
This rom has a unified version for f2fs and ext4, which means no more modifying fstab or updater-script, just flash rom zip file!
Requirement is to format system partition to ext4, & data/cache formatted to f2fs.

* สำหรับท่านที่ไม่ได้ใช้ OPO วิธีการก็เหมือนกัน จะแตกต่างก็ตรง recovery image ที่ใช้ ท่านจะต้องไปหา recovery ที่ใช้สำหรับ Android รุ่นที่ท่านใช้ และรองรับ F2FS (เช่น philz touch หรือ TWRP) *

** ขั้นตอนในโพสต์นี้ต้องทำการเปลี่ยน recovery image ซึ่งทำให้ท่านต้องทำการ unlock bootloader หรือ root เครื่อง Android ซึ่งอาจจะทำให้ warranty ของเครื่องนั้นหมด ผู้เขียนไม่รับผิดชอบต่อความเสียหายที่อาจเกิดขึ้น **

สิ่งที่ต้องเตรียม

1. Recovery ตัวที่รองรับ F2FS
ผมใช้ตัวนี้ philz_touch_6.59.1-bacon.zip ของ katinatez หรือ
จะโหลดจาก backup ของผม
2. พื้นที่ว่างใน /sdcard สำหรับ backup partition data (/data)
3. พื้นที่ว่างใน hard disk สำหรับสำรอง backup file ในข้อ 2 และ backup จาก /sdcard เอง
*เนื่องจาก /sdcard มันเป็น link ชี้ไปที่ /data/media/0 เดี๋ยวเราจะ format /data เป็น F2FS ก็จะทำให้ของใน /sdcard ถูก format ไปด้วย

ขั้นตอนการทำ

1. Boot เข้าสู่ recovery mode เข้าเมนู Backup and Restore ทำการ backup /data partition

2. เมื่อมัน backup เสร็จ เราจะต้อง backup /data/media มายัง hard disk ของเรา จะใช้ MTP ผ่านทาง Window OS หรือ adb pull ก็ได้

3. ผมใช้ adb pull ใช้คำสั่ง
$ adb pull /data/media sd-backup

4. ช้าหรือเร็ว ขึ้นอยู่กับว่าของใน /sdcard มีไฟล์มากหรือเปล่า เมื่อ pull เสร็จแล้ว ให้เข้า menu Mount and Storage

5. เลือก toggle เปิดการ format แบบ F2FS ทำการ format partition /data และ /cache

6. ออกมาจากเมนูนั้น ตรวจสอบว่า mount /data อยู่หรือไม่

7. ถ้ามัน mount /data แล้ว ก็ทำการเอา backup คืนกลับเข้าไปใน /sdcard
ใช้คำสั่ง
$ adb push sd-backup /data/media/

สั่งแบบนี้ แล้วของใน sdcard มันจะอยู่ที่เดิม

8.อาจจะลองตรวจสอบอีกครั้งว่า folder 0 มันอยู่ที่ /data/media/0 หรือไม่ /data/media/0 จะถูก mount เป็น /sdcard นั่นเอง

9.ใช้เมนู Backup and Restore เพื่อเอา /data กลับคืนสู่ที่เดิม

10.ทดลอง reboot system

11.ถ้าเข้า OS ได้แล้ว แต่เจอปัญหาว่า apps ต่างๆมันเขียน /sdcard ไม่ได้ ให้ boot กลับมาที่ recovery อีกครั้ง
ใช้ชุดคำสั่งนี้พื่อแก้ไข
chown -R media_rw:media_rw /data/media/
find /data/media/ -type d -exec chmod 775 {} ';'
find /data/media/ -type f -exec chmod 664 {} ';'
เสร็จสิ้นกระบวนการ :)

ถ้ามีเวลามากกว่านี้จะลองทำ screen capture มาใส่ เพื่อให้ดูน่าอ่านยิ่งขึ้นนะครับ

อ้างอิง:
- [SCRIPT/FIX] Internal sdcard permissions (/data/media/)