วันอังคาร, มกราคม 27, 2558

แก้ปัญหาสร้าง base box ไม่ได้ ด้วย vagrant 1.7.1 บน OSX Yosemite (Workaround)

บันทึก แก้ปัญหา vagrant 1.7.1 บน OSX Yosemite สร้าง vagrant base box ไม่ได้

พอ execute คำสั่งแบบนี้

$ vagrant package --basebox trusty64 

เจอ errror keyword แบบนี้ wrong number of arguments (2 for 1) (ArgumentError)

/opt/vagrant/embedded/gems/gems/vagrant-1.7.1/lib/vagrant/machine.rb:153:in `action': wrong number of arguments (2 for 1) (ArgumentError)
    from /opt/vagrant/embedded/gems/gems/vagrant-1.7.1/plugins/commands/package/command.rb:83:in `package_vm'
    from /opt/vagrant/embedded/gems/gems/vagrant-1.7.1/plugins/commands/package/command.rb:66:in `package_base'
    from /opt/vagrant/embedded/gems/gems/vagrant-1.7.1/plugins/commands/package/command.rb:42:in `execute'
    from /opt/vagrant/embedded/gems/gems/vagrant-1.7.1/lib/vagrant/cli.rb:42:in `execute'
    from /opt/vagrant/embedded/gems/gems/vagrant-1.7.1/lib/vagrant/environment.rb:301:in `cli'
    from /opt/vagrant/bin/../embedded/gems/gems/vagrant-1.7.1/bin/vagrant:174:in `<main>'

    ตามไปดูที่ github ของ vagrant ณ วันที่เขียนนี้ยังไม่ได้ release ตัวแก้ที่ใช้ได้จริงออกมา, ใช้  vagrant 1.7.2 ก็ยังใช้ไม่ได้นะ

workaround ตอนนี้คือให้ไปแก้ไขไฟล์นี้
/opt/vagrant/embedded/gems/gems/vagrant-1.7.1/plugins/commands/package/command.rb

ใช้ vi แล้วแก้ไข ที่เพิ่มขึ้นมาคือ code ส่วน สีน้ำเงิน

$ sudo vi /opt/vagrant/embedded/gems/gems/vagrant-1.7.1/plugins/commands/package/command.rb

 79           acc["package.#{k}".to_sym] = v
 80           acc
 81         end
 82
 83         vm.action(:package, **opts)

คราวนี้เรียกคำสั่งเพื่อทำการ pack box file ได้แล้ว ไม่มี error อีก

Workaround fixed from github: https://github.com/mitchellh/vagrant/issues/4962

วันศุกร์, มกราคม 23, 2558

SOLVED: แก้ไข exception ComponentLookupException เวลา execute MojoTest

    ทำ maven plugin ขึ้นมาเพื่อให้ทีมฯใช้งาน เราก็จะเขียน test plugin ของเราด้วย

  link นี้ข้อมูลเก่า ไม่เห็นใครใน github เขียนแบบที่แนะนำเอาไว้เลย...ข้ามไป
https://cwiki.apache.org/confluence/display/MAVENOLD/Maven+Plugin+Harness

  link ที่ได้มาจากหน้าแรกของการ googling คือ Cookbook: How To Use Maven Plugin Testing Harness? ข้อมูลยังใหม่อยู่ จะเห็นว่าอัพเดตเมื่อปี 2014 นี่เอง ผมก็ทำตามที่เค้าแนะนำ คือ

1. ให้ใช้ plugin ตัวนี้ maven-plugin-testing-harness
<project>
  ...
  <dependencies>
    <dependency>
      <groupId>org.apache.maven.plugin-testing</groupId>
      <artifactId>maven-plugin-testing-harness</artifactId>
      <scope>test</scope>
    </dependency>
    ...
  </dependencies>
  ...
</project>

2.  เขียน test class ขึ้นมา ซึ่งเราต้อง extends AbstractMojoTestCase และใน class ต้อง override setUp() ด้วย, มี method สำหรับ test class ของเรา ในเอกสารมันก็บอกแค่นี้

public class MyMojoTest
    extends AbstractMojoTestCase
{
...
protected void setUp()
        throws Exception
    {
        // required
        super.setUp();

        ...
    }
...
public void testSomething()
        throws Exception
    {
...
}
...
}

3. สร้าง pom สำหรับ test, แก้ไข pom ของ plugin project

4. ทดลองสั่ง

$mvn clean test

มึน!ครับ ได้ Exception แบบนี้
...
org.codehaus.plexus.component.repository.exception.ComponentLookupException: java.util.NoSuchElementException
      role: org.apache.maven.repository.RepositorySystem
  roleHint:
at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:257)
at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:245)
at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:239)
at org.codehaus.plexus.PlexusTestCase.lookup(PlexusTestCase.java:206)
at org.apache.maven.plugin.testing.AbstractMojoTestCase.setUp(AbstractMojoTestCase.java:126)
... 

คือตามที่ทำตัวหน้า แค่เรียกตัว method setup ก็พังแล้ว -_-" 

    นั่งงมอยู่นานครับ ทำไมๆๆ ไม่อยากให้เสียเวลาเหมือนกับผม จึงมาเขียนเอาไว้ครับ เราจะต้องเพิ่ม dependency อีกหนึ่งตัวสำหรับการ test นี้ maven-compat;ที่ทำตัวหนาไว้
...
<dependency>
    <groupId>org.apache.maven.plugin-testing</groupId>
   <artifactId>maven-plugin-testing-harness</artifactId>
   <version>3.1.0</version>
   <scope>test</scope>
 </dependency>
<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-compat</artifactId>
    <version>3.1.1</version>
</dependency>
...

   ส่วน dependecy junit ผมเลือกใช้ version 4.10 มันมี warning บอกให้ใช้ version ที่ใหม่กว่านี้ ก็เลยเปลี่ยนซะ

เพิ่ม depency maven-compat แล้ว ก็ไปต่อได้แล้วครับ มันจะวิ่งเข้า test method เราแล้ว 



วันพฤหัสบดี, มกราคม 22, 2558

ใส่ build time ใน MANIFEST.MF ให้ jar file ที่ build ด้วย maven 3

    ทำ library package เป็น jar file ออกมาแล้วอยากให้มี build time อยู่ใน jar file ด้วย ข้อมูลแบบนี้เค้าจะใส่ไว้ใน MANIFEST ไฟล์กัน ไฟล์มันจะชื่อ MANIFEST.MF

ถ้าลองแกะออกมาดูจาก jar file จะเห็นcontent ประมาณนี้ 

Manifest-Version: 1.0
Built-By: siritas_s
Build-Jdk: 1.7.0_25
Created-By: Apache Maven 3.1.0
Archiver-Version: Plexus Archiver

    ค้นๆ ไปเจอ Cookbook: How To Add Build Time To A JAR Manifest? นี้ นั่งทดลองอยู่ตั้งนานทำไมมันไม่ได้ซักที(วะ) ผมสรุปเองว่ามันเป็นวิธีที่เก่าแล้ว สมัย maven 2 ล่ะมั้ง แถมต้องใส่โน่นนี่ยึบยั่บใน pom

   วิธีสำหรับ maven 3.x สั้นกระชับ ตามนี้เลย

ถ้าใน build ยังไม่มี plugin id maven-jar-plugin ตัวนี้ก็ใส่เข้าไปใต้ <build>

<build>
...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
    <archive>
        <manifestEntries>
            <Build-Time>${maven.build.timestamp}</Build-Time>
        </manifestEntries>
    </archive>
    </configuration>
    </plugin>
...
</build>

เพิ่ม config ใน pom แล้ว สั่ง mvn clean package ใหม่  ลองแกะออกมาดูจาก jar file จะเห็นcontent ประมาณนี้

Manifest-Version: 1.0
Build-Time: 20150122-1421
Built-By: siritas_s
Build-Jdk: 1.7.0_25
Created-By: Apache Maven 3.1.0
Archiver-Version: Plexus Archiver

ถ้าอยากเปลี่ยน date format ของ build time ก็เพิ่ม property ตามนี้เข้าไปใต้ <project>
<project>
...
<properties>
    <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>

</properties>
...
</project>

Happy แล้ว กลับไปทำงานต่อละ

วันพุธ, มกราคม 14, 2558

แก้ปัญหา: DocumentException: Table 'name' does not exist ...

แก้ปัญหา DocumentException: Table 'name' does not exist ...

    แอพพลิเคชั่นที่พัฒนาอยู่ ใช้ maven จัดการ มันมี function หนึ่งของแอพนี้ที่ต้องยุ่งกับการสร้างเอกสาร PDF
   เวลารัน test มันจะมาตายตอนจะทดสอบการสร้างเอกสาร PDF โดยสังเกตว่ามี exception แบบนี้ 

com.itextpdf.text.DocumentException: Table 'name' does not exist in file:/workspace/anApplication/target/classes/fonts/arial.ttf


   กูกลิ้งไปๆมาๆก็มาเจอว่าเจ้า maven นี่หวังดี ตอน compile source code มันก็มา copy resource ที่เป็นฟอนต์ของเราไปให้ที่โฟลเดอร์ target ด้วย แต่มันดันทำให้ property 'name' ในฟอนต์แต่ละตัวมันหายไป (มีคนเค้าเอาซอฟต์แวร์แก้ไขฟอนต์มาเปิดดู เลยรู้ว่ามันหายไปจริงๆ) และถ้าก้อปปี้ฟอนต์ไฟล์จากโฟลเดอร์ resource ไปทับภายใต้โฟลเดอร์ target เอง ฟอนต์นี้มันก็จะใช้ได้ไม่มีปัญหา,ไม่มี exception ข้างต้น

  เกิดจาก maven มันเห็นว่า ttf เป็นไฟล์ที่ต้องทำการ filtering ด้วย (การ filtering ถ้าเกิดกับ text ไฟล์ก็คือการเอาข้อความจริงไปแทนที่ variable ที่อยู่ในไฟล์ให้เลย) วิธีแก้ก็ต้องอย่าให้ maven มันมา filtering ไฟล์ฟอนต์ของเรา

แก้ไขที่ pom.xml 
* ใส่ plugin maven-resouces-plugin
* ถ้ามี plugin ตัวนี้อยู่แล้วก้อใส่ nonFilteredFileExtensions เพิ่มเข้าไป 

...
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
      <configuration>
        <nonFilteredFileExtensions>
          <nonFilteredFileExtension>ttf</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
      </configuration>
</plugin>
...

วันศุกร์, มกราคม 02, 2558

วิธี ใช้ Google Drive icon สีขาวบน Yosemite dark menu bar






ตั้งแต่ upgrade macbook มาเป็น Yosemite ก็ต้องรำคาญกับ icon ของ Google Drive บน menu bar สีดำ เพราะสีมันกลืนกัน ดูยาก


ใครอยากเปลี่ยนให้มันดูง่ายๆ ทำตามได้เลยครับ :)

อ่อ script นี้จะใช้งานได้ มีข้อแม้ว่า Google Drive.app ต้องติดตั้งไว้ที่ folder Applications

สร้างไฟล์ fix-google-drive-dark-mode-icons.sh เนื้อหาตามข้างล่าง ไว้ที่ ~/Desktop
ถ้าคุ้นเคยกับการใช้ shell script กันอยู่แล้ว คุณจะไว้ที่ไหนก็ได้ ตั้งชื่อไฟล์ว่าอะไรก็ได้ ;)

#!/bin/bash

function switch_files {
    mv $1.png $1.tmp.png
    mv $1-inverse.png $1.png
    mv $1.tmp.png $1-inverse.png
    mv $1@2x.png $1@2x.tmp.png
    mv $1-inverse@2x.png $1@2x.png
    mv $1@2x.tmp.png $1-inverse@2x.png
}  

RUNNING=`ps aux | grep '/Google Drive' | grep -v grep | wc -l | bc`
if [ "$RUNNING" = "1" ]; then
    killall 'Google Drive'
    while [ "$RUNNING" = "1" ]; do
        sleep 1
        RUNNING=`ps aux | grep '/Google Drive' | grep -v grep | wc -l | bc`
    done
fi
sleep 3

cd '/Applications/Google Drive.app/Contents/Resources/'
switch_files mac-animate1
switch_files mac-animate2
switch_files mac-animate3
switch_files mac-animate4
switch_files mac-animate5
switch_files mac-animate6
switch_files mac-animate7
switch_files mac-animate8
switch_files mac-error
switch_files mac-inactive
switch_files mac-normal
switch_files mac-paused
open '/Applications/Google Drive.app'

เสร็จแล้ว เปิด Terminal

$ chmod +x ~/Desktop/fix-google-drive-dark-mode-icons.sh

$ ~/Desktop/fix-google-drive-dark-mode-icons.sh

เมื่อ execute script แล้ว รอสักครู่ เมื่อ prompt return กลับมาเป็นอันเสร็จ

ขอบคุณ คุณ gboudreau จาก reddit