Launch4j: วิธีกำหนด parameter ไปให้ app

จากโปรเจค Launch4j ในบทความก่อนหน้านั้น เราได้สร้าง app เล็กๆขึ้นมาแล้ว ต่อมาสมมุติว่าเราต้องการส่งพวก JVM parameter ไปให้ app ละทำไงดี

สมมุติโจทย์

สมมุติว่าโจทย์คือ “ให้ app เราพ่น log ออกมาได้และสามารถกำหนดได้ว่าจะให้พ่นแบบไหนยังไง” ในส่วนของ log ผมจะใช้ sfl4j+log4j ช่วยในการพ่นและก็จะกำหนดให้ app ไปอ่าน log4j.properties ตาม path ที่กำหนดเพื่อจะได้กำหนด format ของข้อความและ path ของ ไฟล์ log ได้

Code & Config

เริ่มจากเพิ่ม log library เข้าไปให้โปรเจคก่อน

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.6.1</version>
		</dependency>

จากนั้นก็ลองเขียน log ออกมาแล้ว run ซิ

package ninja.tumit.launch4jdemo;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Hello Launch4j!
 *
 */
public class App 
{
    
    Logger logger = LoggerFactory.getLogger(App.class);

    public void run() {
        try {
            logger.info( "Hello {}! on {}", "Launch4j",  System.getenv("computername"));
            System.in.read();            
        }catch(IOException e) {
            e.printStackTrace();
        }        
    }
    
    
    public static void main( String[] args ) {
        new App().run();
    }
}

log message แดงเถือก

message แดงเถือกกันเลย เพราะเรายังไม่ได้กำหนด properties อะไรให้ log library เลยดังนั้นก็ search หาตัวอย่าง log4j.properties มา ลองใส่เข้าไปใน resources เลย พลั๊กเข้าให้

log.file

run อีกทีควรจะโอเค จากนั้นทดลองเสร็จก็ pack เป็น exe โล้ด การกำหนด log4j.properties ให้ app นั้นต้องใช้ผ่าน JVM parameter ตอน run ด้วย parameter แบบนี้

-Dlog4j.configuration=file:e:\launch4jdemo\cfg\log4j.properties

และส่วนของ launch4j ก็สามารถกำหนด parameter ได้หลายวิธี แต่วิธีที่ผมเลือกใช้คือสร้างไฟ xxx.l4j.ini ในโฟลเดอร์ที่เราแปะ exe แล้วเราก็สร้างไฟล์แล้วใส่ไปเลย
log-cfg
แค่นี้เราก็สามารถส่ง JVM parameter ไปให้ app ของเราได้แล้ว

Launch4j: run Java แบบ exe + พก JRE ไปด้วย

โจทย์ที่ได้มา

หมายเหต: รอบนี้เฉพาะ Windows เท่านั้นนนนน !!!

รอบนี้โจทย์ที่ได้มาคือ “อยากใด้โปรแกรมจาวาเล็กๆไว้ run ได้แบบไม่ต้อง install Java” ก็ search ไปมาไปเจอตัวนึงน่าสนใจคือเจ้า Launch4j

จริงๆหลักๆแล้วเจ้า Launchb4j มันเอาไว้แปลงร่างจาก .jar ไปเป็น .exe ที่เหล่าวินโดเลี่ยนคุ้นเคยและยังมีความสามารถในการแอบแปะ jre ไปกับ exe ได้ด้วย โอเช เรามาลองกัน

เขียน App ง่ายๆขึ้นมาตัวนึง

ขั้นแรกเขียน App ง่ายๆขึ้นมาตัวนึงก่อน เพื่อดูว่ามันจะ run ได้ไหม

package ninja.tumit.launch4jdemo;

import java.io.IOException;

/**
 * Hello Launch4j!
 *
 */
public class App 
{
    public static void main( String[] args ) 
    {
        try {
            System.out.println( "Hello Launch4j!" );
            System.in.read();            
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}

App นี้ไม่ทำอะไรเลยนอกจากพ่นคำว่า “Hello Launch4j!” แล้วก็รอ enter แล้วจึงจะออกจากโปรแกรม

ใช้ Launch4j Maven Plugin

จากนั้นก็ไป search หาวิธีใช้เจ้า launch4j ก็ไปเจอโพสนึงใน Stackoverflow (แต่หา post นั้นไม่เจอซะละ) บอกวิธีใช้ Launch4j Maven Plugin ดีเลยเราใช้ Windows เราใช้ Maven ว่าแล้วก็ copy โครมมมใน pom.xml แก้นิดหน่อยให้เป็นของเราเองซะก็ได้หน้าตาประมาณนี้ประมาณนี้

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>ninja.tumit</groupId>
	<artifactId>launch4jdemo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>launch4jdemo</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>1.4</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<shadedArtifactAttached>true</shadedArtifactAttached> <!-- Make the shaded artifact not the main one -->
					<shadedClassifierName>shaded</shadedClassifierName> <!-- set the suffix to the shaded jar -->
				</configuration>
			</plugin>
			<plugin>
				<groupId>com.akathist.maven.plugins.launch4j</groupId>
				<artifactId>launch4j-maven-plugin</artifactId>
				<executions>
					<!-- Command-line exe -->
					<execution>
						<id>l4j-cli</id>
						<phase>package</phase>
						<goals>
							<goal>launch4j</goal>
						</goals>
						<configuration>
							<headerType>console</headerType>
							<outfile>target/launch4jdemo.exe</outfile>
							<jar>target/${artifactId}-${version}-shaded.jar</jar> <!-- 'shaded' is the value set on shadedClassifierName above -->
							<classPath>
								<mainClass>ninja.tumit.launch4jdemo.App</mainClass>
							</classPath>
							<jre>
								<path>../jre</path>
								<minVersion>1.6.0</minVersion>
								<maxVersion>1.8.0</maxVersion>
							</jre>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

</project>

อธิบาย pom กันซะหน่อย จุดที่น่าสนใจก็มี

  • maven-shade-plugin เป็นตัวช่วย pack พวก libs ที่เราต้องใช้ให้เป็น jar ตัวเดียวเก๋ๆ
  • launch4j-maven-plugin ตัวนี้แหละพระเอกของงานมันจะเอา jar ที่ pack เป็นหนึ่งเดียวแล้วไปทำเป็น exe โดย
    • outfile บอกว่าให้เป็น exe ชื่ออะไร เก็บที่ไหน
    • jar บอกว่าจะเอา jar ที่ไหนมาทำ (ก็เอา jar จาก shade ไง)
    • classPath.mainClass ก็ระบุไปว่าจะ execute main ตัวไหน
    • และ jre บอก path ของ jre โปรเจคนี้เราจะเอา jre ไปด้วยจะได้ไม่ต้องเสียเวลา install

ว่าแล้วก็ลอง pack กันเลย

mvn clean package

ถ้าไม่มีอะไรผิดพลาดเราก็จะเห็น launch4jdemo.exe ตัวเป็นๆที่ targat
launch4j-target

เอาไป run กัน

โดยเรากำหนด folder structure ง่ายๆดังนี้

launch4j-folders

  • bin เอาไว้เก็บ exe ก็ไป copy launch4jdemo.exe มาแปะ
  • jre เอาไว้เก็บ jre (จะอธิบายทำไม == ‘)
    ปล. สังเกตุ plugin config ใน <jre> เราถึงระบุว่าให้เป็น ../jre นั้นเอง แล้วก็ไป copy jre มาแปะซะ (folder bin กับ lib)

เราก็จะได้ exe ไว้ run Java app ของเราได้เลย

launch4jdemo-exe

======== จบ(ก่อนตอนนึง)จ้า ========

อ้างอิง: http://launch4j.sourceforge.net/ , https://github.com/lukaszlenart/launch4j-maven-plugin

Virtualbox: อยากให้มัน Full screen ที่จอสอง ทำไง?

วันนี้มา Blog สั้นๆ ง่ายๆ ที่พึ่งรู้ คือ เวลาเราใช้ Virtualbox แล้วเราอยากให้มันแสดงผลแบบ Full screen ก็ง่ายๆเลยกด View -> Switch to Fullscreen

virtualbox-full-screen

ประเด็นก็คือเวลาเรามีสองจอ และเราอยากให้มันแสดงแบบ Full screen ไปที่จอสองทำไงละ เพราะพอกดปุ๊บมันจะไป Full screen ที่จอแรกเสมอ

หลังจากทนใช้ไปซักพักทนไม่ไหวก็เลยไป search ก็เจอวิธีทันที ง่ายๆเลย ที่เมนูเล็กๆด้านล่างเวลาเราให้มันแสดงแบบ Full screen จะมีเมนู View อยู่ให้กด View -> Virtual Screen 1 ทีนี้เราก็เลือกได้แล้วว่าอยากให้มัน Full screen ที่จอไหนก็ตามสะดวกเลยครับ 🙂

virtualbox-full-screen-view

virtualbox-full-screen-2nd-screen

อ้างอิง :Full screen on a second monitor

ลาก่อย น้องเอี๊ยด (ในวันที่จักรยานหาย)

จริงๆว่าจะนอนแล้ว แต่ไหนๆวันนี้ก็ต้องจากกับ น้องเอี๊ยด (“เอี๊ยด” นี้มาจากเสียง “เอี๊ยดอ๊าด” เวลาปั่น) จักรยาน(ซื้อเอง)คันแรกของของตัวเอง เลยมาบล็อกเพื่อเป็นที่ระลึกหน่อย จริงแล้วอยากได้จักรยานมาปั่นนานมากแล้ว เห็นเขาปั่นกันเท่ๆ(แพงๆ)ทั้งนั้น แต่ด้วยความงกบวกกับความเป็นคนใจเย็น(หรือจะเรียกให้ถูกคือเป็นคนเฉื่อยชา) เลยไม่ได้ซื้อซักที่ สุดท้ายมาได้ซื้อเพราะต้องไปซื้อจักรยานใหม่ให้ลูกชายคนโต ณ ร้านจักรยานย่านบางแค.. ภรรเมีย: เอาไปด้วยเลยเปล่า? ข้าพเจ้า: (อยากได้แต่ยังงก) เอาเลยดีมะภรรเมีย: สรุปเอาไหม? ข้าพเจ้า: เอาเลยก็ได้ เอาสีนี้ๆ (ในใจลิงโล้ดดดด) จักรยานพับสนนราคา 3,000 บาทถ้วน เอาว่ะไม่แพงเกินไป แล้วก็ไปสอยไฟติดจักรยานมาจากสำเพ็งสองมาอีก 60 บาท สบายละๆ

WP_20150111_15_58_59_Pro
ได้มาแล้วๆ
WP_20150111_16_55_01_Pro
ได้คันใหม่พร้อมลูกชายคนโต ส่วนคนเล็ก “เก่าของพี่ ใหม่ของผม”

จากนั้นก็เริ่มปั่นไปรถไฟฟ้าแทนรถตู้ (ตอนปั่นเล่นที่คอนโดปรากฎน็อตล้อหลังหลวมต้องเอาไปร้านดูให้.. แต่ที่ฮาก็คือช่างที่ร้านถามว่า “มีใครไปหมุนน็อตเล่นหรือเปล่า?” คิดในใจ “ใครแม่งจะไปนั่งคลายน็อตเล่นวะ!” = =’) หลังจากนั้นก็เอาเลย ปั่นไปจอดที่รถไฟฟ้า สบายๆ 3-4 โล

WP_20150216_10_30_41_Pro
มี่ที่จอดล็อกล้อเรียบร้อย หารู้ไม่.. T-T

หลังจากปั่นอย่างสบายใจได้มา 2-3 เดือนแล้ววันสุดท้ายของข้าพเจ้ากับบน้องเอี๊ยดก็มาถึง ขณะลงรถไฟฟ้ามาอย่างสบายใจ ตรงมาที่จอดรถจักรยาน อืม..จักรยาน… จักรยาน… หาย!

WP_20150319_007
ไม่เหลืออะไรเลย จักรยานหายไปกับตา เหลือแต่ราวที่ว่างเปล่า ต้องกลับแท็กซี่เท่านั้น ~
2015-03-20 01_37_38-tumit (@tumit) _ Twitter
ปฎิกิริยาหลังหาจักรยานตัวเองไม่เจอ

จริงๆภรรเมียเคยทักแล้วว่าให้เอาไปให้สุดคือแบกขึ้นรถไฟฟ้าไปด้วยเลย แล้วไปจอดที่ทำงานแต่ด้วยความขี้เกียจแบกบวกโลกสวย(คนอื่นเขาก็จอดกันไม่เห็นหาย) เลยประมาท ทำให้น้องเอี๊ยดโดนสอยไปในที่สุด T-T

สุดท้าย… ก็ถือเป็นเรื่องเตือนใจว่าอย่าประมาทจอดรถไว้ที่จอดรถไฟฟ้า(ซึ่งคันใหม่คงไม่กล้าจอดแล้ว) ส่วนข้าพเจ้ากับน้องเอี๊ยดคงมีวาสนากันแค่นี้ ขอให้นางได้พบกับเจ้าของใหม่ใจดีๆ น่ารักๆ ใช้งานอย่างทะนุถนอม  ปล. รักและคิดถึงเสมอ (อดีต)เจ้าของ ~

เขียนชวาแบบไม่ขัดจังหวะด้วย DCEVM

DCEVM คืออะไร

The Dynamic Code Evolution Virtual Machine (DCE VM) is a modification of the Java HotSpot(TM) VM that allows unlimited redefinition of loaded classes at runtime

พูดง่ายๆคือเป็นตัวเสริมการทำงานของ (J)VM ให้สามารถโหลดคลาสใหม่ ณ runtime ทำให้เราสามารถ แก้ไข code แล้วไม่ต้องกด compile ใหม่ run ใหม่

ถ้าจะให้เห็นภาพก็ ดูที่ Video นี้เลย

สังเกตุได้ว่าระหว่างที่โปรแกรม run อยู่พอแก้ code ปุ๊บ active ปั๊บ (แจ่ม) เอาละมาลองเริ่มเลย

โหลด DCE VM มาก่อน

ผมโหลด DCE VM จาก http://dcevm.github.io/ (ตัวที่ใช้ลองเป็น Java 7 update 51, build 3)

โหลด JDK ให้ตรงกับ DCE VM

เพื่อความปลอดภัย ผมเลือกใช้ JDK7u51 ตามที่ DCE VM บอกว่า support โหลดได้จาก Java SE 7 Archive Downloads แล้ว install ซะ

ก็อปปี้ JDK ไว้ทำ DEC VM แล้ว install ซะ

เพื่อความสบายใจผมก็อปปี้ jdk ที่ install ไปไว้อีกที่เพื่อใช้ install DEC VM จากนั้นก็ install เลย

dcevm
ก็อปปี้ไว้ D: ซะ เปลี่ยนชื่อซะหน่อย
dcevm-install
install ซะ
2014-11-11 19_24_49-Dynamic Code Evolution VM Installer
เลือก jdk ที่เราก็อปปี้แล้ว install DCEVM เสร็จแล้วจะขึ้นแบบนี้

สร้าง Project แล้วลองเลย

ผมสร้าง Java project ด้วย Maven บน Eclise และ set ให้ project ใช้ dcevm ที่เรา install ไว้

jre

จากนั้นก็ลอกโค้ดตาม Youtube เลย

package com.tumit.dcevmdemo;

/**
 * DCEVM Test!
 *
 */
public class App {
    public static void main(String[] args) throws InterruptedException{
               
        while(true){
            A a = new A();
            System.out.println(a.doStaff());
            Thread.sleep(1000);
        }
        
    }
}

class A {

    private static int x;
    
    public String doStaff() {
        return "A" + x++;
    }
    
}

ลอง run (Ctrl+F11) เลย อ้าว! ไม่เห็นเปลี่ยน

run1
อ้าว! แก้แล้วทำไมไม่โหลดให้ใหม่

ลองไปลองมาก็มา อ๋อ.. ต้อง run แบบ debug mode (F11) เอาใหม่ๆ

run2
แก้จาก A เป็น B แล้ว save อ้าาา ใช้ได้ๆ

สรุป… ก็โอนะ

หลังจากลองคร่าวๆน่าสนใจเลย ผมลอง(เล็กๆ)แก้โปรเจค struts2+spring+hibernate ก็ช่วย reload พวก class กับ application resource ได้ ถือว่าน่าสนใจพอที่จะลองไปเล่นดูครับ 😀

jQuery Validation Plugin — ตอนที่ 1 ทดลองใช้

หลังจากไม่ได้เขียน Web มานานทำให้รู้สึกตกยุคสมัยกับเขามาก จนโปรเจคนึง เพื่อนโจ๊กบอกใช้ jQuery Validation อ้า..แจ๋วแฮะ โอเคมาเริ่มเลย

jQuery Validation Plugin คืออะไร?

มันก็คือ plugin เสริมของ Java Script Library ยอดนิยมอย่าง jQuery ช่วยให้เราเขียน validate input ฝั่ง client ที่ user กรอกใน form ได้ง่ายและสะดวกขึ่น

ตัวอย่างเช่น สมมุติว่าเรามี requirement ว่า “ให้สร้าง form ที่มี textbox ที่สำหรับใส่ username และห้ามเป็น blank” เราก็เริ่มจาก

สร้าง form

<form id="f" action="index.html">
    <input id="username" name="username" type="text" />
    <input type="submit" />
</form>

เราก็จะได้ form โง่ๆมาตัวนึง ซึ่งยังไม่ได้ validate อะไรเลย

2014-11-08 01_48_19-index.html_username=

ใส่ jquery validation libraly ลงไปใน html

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.js"></script>

แน่นอนเราต้องการจะใช้ library มันก็ต้องทำการ define ก่อนนว่าเราจะใช้ 1.jquery และ 2.jquery.validate ปล.สองอันนี้เขายอมให้ hot link ได้ครับ

กำหนดให้ form มีการ validate และระบุว่า field ไหน validate

<script>
$(document).ready(function(){     

    // 1. defind form have to validate
    $('#f').validate();         

    // 2. add rules for validate
    $('#username').rules('add', { required: true });
                
});
</script>

ข้อ1. ใน form เรามี form ที่ใช้ id ว่า ‘f’ เราก็บอกมันง่ายๆเลยว่าให้ ‘f’ validate ซะ ต่อมาข้อ 2. เรามี field ที่ใช้ id ว่า username ก็ระบุต่อไปว่า field username นั้นมี rules และจะเพิ่ม required rule ให้ ซึ่งหลังจากเราเพิ่มการ validate ลงไปและลอง submit เราก็จะได้..2014-11-08 02_41_54-index.htmlสรุป…

หลักๆคือเราสามารถ validate ได้ง่ายโดยแค่ระบุให้ได้ว่า field มีี rule อะไรบ้างเท่านั้นเอง ส่วน jquery validation นั้นมี rule อะไรเตรียมไว้บ้างนั้นเดี๋ยวค่อยมาดูกัน สุดท้ายท่าจบจะประมาณนี้

<!DOCTYPE html>
<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.js"></script>
        <script>
            $(document).ready(function(){     

                // defind form have to validate
                $('#form').validate();         

                // add rules for validate
                $('#username').rules('add', { required: true });
                
            });
        </script>
    </head>
    <body>
        <form id="form" action="index.html">
            <input id="username">
            <input type="submit">
        </form>
    </body>
</html>

อ้างอิง: http://jqueryvalidation.org/

Maven — ตอนที่ 1 เริ่มโปรเจค Java ด้วย Maven

เวลาเราจะตั้งต้น Java โปรเจคด้วย Maven มีได้หลายทาง แต่ก่อนผมใช้ m2e plug-in ของ Eclipse เพราะเห็นว่ามันสะดวกดี แต่…สุดท้ายก็ดวงตาเห็นธรรมว่าเราควรจะรู้แบบ command line ก่อนน่าจะดีกว่า รวมทังเคยเจอปัญหา maven plug-in บ้างตัว m2e ไม่ support ซะอีก

ว่าแล้วเราก็มาเริ่มเลยดีกว่า ก่อนอื่นก็เปิดเว็บของ @mkyong ก่อนเลย #เว็บนี้เขาดีจริงๆของบอก จัด Java Application มาก่อนเลยครับ

การขึ้น Java Project ด้วย Maven

command:

mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

eaxmple:

mvn archetype:generate -DgroupId=com.tumit -DartifactId=bmi-api -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

  • mvn — Maven bat command

  • archetype:generate — ใช้การ generate project ขึ้นมาจาก template

  • -DgroupId={project-packaging} — ชื่อ package ที่เป็น root เช่น com.tumit

  • -DartifactId={project-name} — ชื่อ project จริงๆ เช่น bmi-api

  • -DarchetypeArtifactId — maven-archetype-quickstart — template ที่จะเอามาใช้ตั้งต้นชื่อ maven-archetype-quickstart

  • -DinteractiveMode=false — ไม่ต้องให้ prompt ถามรายละเอียด ให้ใช้ default ไป

จากนั้นก็หา Folder โล่งๆซักทีนึงที่ไว้เก็บ code แล้ว launch command ตาม example เลย

mvn archetype:generate -DgroupId=com.tumit -DartifactId=bmi-api -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

จากนั้นก็จะได้ Java โปรเจคที่สร้างมาจาก Maven แล้ว จากนั้นก็เข้าไปที่ bmi-api folder ก็ลองเลยคำสั่งแรก mvn test

bmi-api>mvn test

ถ้าโอเคมันจะขึ้นประมาณนี้

[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time: 1:05.129s
[INFO] Finished at: Fri Aug 23 16:05:10 ICT 2013
[INFO] Final Memory: 11M/28M
[INFO] ————————————————————————

โอเค แล้วถ้าเป็นโปรเจค Web ละ?

ก็เหมือนเดิมแค่เปลี่ยนarchetypeArtifactId เป็นmaven-archetype-webapp เท่านั้นเอง

command:

mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

eaxmple:

mvn archetype:generate -DgroupId=com.tumit -DartifactId=bmi-web -DarchetypeArtifactId=maven-archetype-webapp-DinteractiveMode=false


References:

How to create a Java project with Maven— @mkyong