ใน Linux เราสามารถรันโปรแกรมแบบนี้
ls -al #lookup ls in PATH
./myprgram # รัน myprogram ที่อยู่ใน current directory
ทราบกันไหมครับว่าเราสามารถรัน spring boot jar เหมือนที่เรารันโปรแกรมในshell ได้แบบเดียวกันด้วย ถ้าเรา config spring-boot-maven-plugin executable=true
./myjar.jar
#เราใส่ . ไปเพราะว่า Linux ไม่ได้เพิ่ม working directory เข้าไปใน PATH เหมือน Windows
# เราจึงต้องระบุพาธ(relative path)ของไฟล์ที่จะรันเอง
ปกติแล้ว เราจะไม่สามารถรัน .jar ไฟล์แบบนี้ได้ เพราะ jar ไม่ใช่ shell script หรือโปรแกรม แต่มันคือ archive ไฟล์ (zip format) แล้วมันรันแบบนั้นได้ยังไง!!!
# ปกติเรารัน jar ที่มี main-class ระบุใน manifest แบบนี้
java -jar myjar.jar
คำตอบก็คือ ใน Linux เราสามารถเพิ่ม binary file (ในที่นี้คือ jar) เข้าไปต่อท้าย shell script ได้ ทำให้เรารวม script java -jar myjar.jar
กับ jar ไฟล์เข้าด้วยกันได้ และยังสามารถ execute script ได้ด้วย
ตัวอย่างวิธีการทำคร่าวๆ
เตรียมไฟล์ shell script สำหรับรัน java -jar
#!/bin/sh
exec java -jar "$0" "$@" # $@ คือ all parameter ที่เราส่งมา ยกเว้นตัวที่ 0 ($0 คือชื่อไฟล์)
exit 0
#ไฟล์ run.sh
จากนั้น เอา jar file มาต่อท้าย shell script
cat run.sh myjar.original.jar > myjar.jar
change mode myjar.jar ให้สามารถ execute ได้
chmod +x myjar.jar
ทดลองรัน
❯ ./myjar.jar
Hello World
ลองดูใน content ของ myjar.jar
xxd -l 100 myjar.jar
00000000: 2321 2f62 696e 2f73 680a 6578 6563 206a #!/bin/sh.exec j
00000010: 6176 6120 202d 6a61 7220 2224 3022 2020 ava -jar "$0"
00000020: 2224 4022 0a65 7869 7420 300a 504b 0304 "$@".exit 0.PK..
00000030: 1400 0808 0800 2c79 1c51 0000 0000 0000 ......,y.Q......
00000040: 0000 0000 0000 0900 0400 4d45 5441 2d49 ..........META-I
00000050: 4e46 2ffe ca00 0003 0050 4b07 0800 0000 NF/......PK.....
00000060: 0002 0000
Note.
นอกจากเราจะรันมันด้วย shell แล้ว เรายังสามารถรันมันด้วย java -jar myjar.jar เหมือนปกติได้ด้วย (อันนี้ผมเข้าใจว่าเป็นความสามารถของ java เอาที่สามารถ skip content อื่นๆไปจนกว่าจะเจอ jar header ถึงทำการ parse)
ใครอยากลองทำเล่นก็ clone git https://github.com/pramoth/executable-jar มาเล่นได้เลยครับ
ส่วน spring boot จะใช้ script นี้ https://github.com/spring-projects/spring-boot/blob/2.3.x/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script
โดย spring-boot-maven-plugin เป็นคนเอาไปรวมกับ jar
อ้างอิง
https://coderwall.com/p/ssuaxa/how-to-make-a-jar-file-linux-executable
Top comments (0)