DEV Community

Pramoth Suwanpech
Pramoth Suwanpech

Posted on • Edited on

3 1

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

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay