วันอังคาร, มกราคม 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 แล้ว กลับไปทำงานต่อละ