DEV Community

Pramoth Suwanpech
Pramoth Suwanpech

Posted on • Edited on

Spring Boot executable jar ทำงานยังไง

ใน Linux เราสามารถรันโปรแกรมแบบนี้

ls -al #lookup ls in PATH
./myprgram # รัน myprogram ที่อยู่ใน current directory
Enter fullscreen mode Exit fullscreen mode

ทราบกันไหมครับว่าเราสามารถรัน spring boot jar เหมือนที่เรารันโปรแกรมในshell ได้แบบเดียวกันด้วย ถ้าเรา config spring-boot-maven-plugin executable=true

./myjar.jar 
#เราใส่ . ไปเพราะว่า Linux ไม่ได้เพิ่ม working directory เข้าไปใน PATH เหมือน Windows
# เราจึงต้องระบุพาธ(relative path)ของไฟล์ที่จะรันเอง
Enter fullscreen mode Exit fullscreen mode

ปกติแล้ว เราจะไม่สามารถรัน .jar ไฟล์แบบนี้ได้ เพราะ jar ไม่ใช่ shell script หรือโปรแกรม แต่มันคือ archive ไฟล์ (zip format) แล้วมันรันแบบนั้นได้ยังไง!!!

# ปกติเรารัน jar ที่มี main-class ระบุใน manifest แบบนี้
java -jar myjar.jar
Enter fullscreen mode Exit fullscreen mode

คำตอบก็คือ ใน 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
Enter fullscreen mode Exit fullscreen mode

จากนั้น เอา 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
Enter fullscreen mode Exit fullscreen mode

ลองดูใน 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
Enter fullscreen mode Exit fullscreen mode

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)