Classpath ใน .bat ยาวเกิน 8K ทำไงดี????

เอาสาระน่ารู้เกี่ยวกับการเขียนโปรแกรมมาฝาก ขอมีสาระกะเค้าบ้าง

เนื่องจากวันก่อน เจอบัคเกี่ยวกับ .bat ไฟล์ไม่สามารถรันได้เพราะดันใส่ Classpath ยาวเกินไป

ตัวอย่าง:
=============================================
@echo off
set CLASSPATH=.;.\a.jar;.\b.jar ...........

...........................................
...........................................
...........................................
...........................................
...........................................
...........................................
...........................................
...........................................
...........................................      
;.\zzzzzzzzzzzzz.jar
echo %CLASSPATH%
java me.Hello

=============================================

ที่เป็นแบบนี้เพราะว่า Window ไม่ support classpath ที่ยาวๆ นะจ๊ะ (ยาวไปไม่อ่าน โอเค๊!)

เราจึงต้องทำการเปลี่ยนแปลงไฟล์นี้ใหม่

วิธีการแก้ก็หามาจาก Stackoverflow

คำแนะนำของเค้าคือ
1. ใช้ * (wildcards) แทนที่จะระบุ path ทุกตัว
หรือ
2. ใช้ Class-Path ใน Manifest ไฟล์เข้ามาช่วย

ซึ่งเราไม่สามารถเปลี่ยนแปลง classpath ได้ เพราะส่งมาจากที่อื่นอีกที ไม่ได้เขียนเอง จึงเลือกใช้วิธีที่สอง

เริ่มต้นกันดีกว่า
โดยเราจะสร้างไฟล์ .jar ขึ้นมาไฟล์นึง สมมติชื่อ path.jar
ข้างในไม่ต้องมี .class หรือ data ใดๆ ทั้งสิ้น
มีแค่ META-INF/MANIFEST.MF ไฟล์เดียวพอ
(วิธีการสร้างจากเว็บของ Oracle และ  เว็บนี้)

ข้างใน MANIFEST.MF ก็จะใส่ Class-Path ไปตัวนึง
เอา classpath ทั้งหมดใน .bat มาใส่ไว้ที่นี่แทน โดยใช้การเว้นวรรคเพื่อแบ่งแต่ละ path แทน ; หรือ :


โครงสร้าง path.jar จะประมาณนี้ 
=============================================

path.jar
 -- META-INF
     -- MANIFEST.MF

=============================================

หน้าตา MANIFEST.MF จะประมาณนี้ 

=============================================
Manifest-Version: 1.0
Class-Path: .\a.jar .\b.jar ...............

...........................................
....................... .\zzzzzzzzzzzzz.jar


=============================================
ต้องเว้นบรรทัด ให้อย่างน้อย 1 บรรทัดด้วยนะ
คือ ไฟล์ Manifest ต้องปิดท้ายด้วยการเว้น 1 บรรทัด

จากนั้นก็ลบ Classpath ใน .bat ออกได้เลยจ้า
เอา path ของ path.jar ตัวนี้ไปใส่แทน

หน้าตา .bat จะประมาณนี้ 

=============================================
@echo off
set CLASSPATH=.;.\path

echo %CLASSPATH%
java me.Hello

=============================================

อ๊ะ อ๊ะ เด๋วก่อน !
Class-Path ใน Manifest.mf นี้ก็มีข้อจำกัดเหมือนกัน
นั่นคือ มันรับได้แค่ 72 bytes ใน 1 บรรทัด

คำแนะนำจากเว็บ Stackoverflow อีกเช่นเคย
แนะนำให้เว้นบรรทัดลงมา แล้วใส่ space ไปข้างหน้า 1 space ในแต่ละบรรทัด

เลยลองแก้เป็นแบบนี้
=============================================
Manifest-Version: 1.0
Class-Path: .\a.jar
 .\b.jar 
 .\c.jar
 ...
 ...
 ...
 .\zzzzzzzzzzzzz.jar


=============================================


เจ๊งจ่ะ 5555
เพราะว่าอ่านตัวอย่างแล้วเข้าใจผิด 5555

ความจริงคือ ถ้าเราเว้นบรรทัดและเว้นวรรคข้างหน้า 1 ตัว จะเป็น Extra line ของ Manifest
เวลามันอ่านค่าก็จะเอาข้อความถัดจาก Extra line ไปต่อกะตัวข้างบน

สมมติเราใส่โดยเว้นบรรทัด แล้วเว้นวรรคตรงบรรทัดใหม่แค่ space เดียว

Class-Path: .\a.jar
 .\b.jar

เวลามันอ่าน มันจะเอาไปอ่านเป็น

Class-Path: .\a.jar.\b.jar

คือมันจะแทนที่ newline + 1 space ด้วย "" เวลาเอาไปใช้งานจริง
ดังนั้น ถ้าเราต้องการจะแยก 1 path 1 บรรทัด

ต้องใส่ 2 space ถึงจะได้ หรือใส่ 1 space หน้า-หลังก็ได้เช่นกัน

Class-Path: .\a.jar
  .\b.jar 

เพื่อที่มันจะเอาไปอ่านเป็น

Class-Path: .\a.jar .\b.jar

หมายความว่า ต่อให้ Path เดียวกัน แต่มันยาวเกิน เราก็สามารถตัด path นั้นออกมาให้สั้นลงได้

เช่น

Iamapathofclasspath.jar

เวลาเขียนใน Class-Path เราสามารถเขียนเป็น

Class-Path: .\Iam
 apathofclasspath.jar

คือขึ้นบรรทัดใหม่ แล้วใส่ 1 space

เพื่อเวลามันเอาไปใช้จะอ่านเป็น

Class-Path: .\Iamapathofclasspath.jar

เพื่อความสวยงาม เราจะใช้ 1 path 1 บรรทัดแทน แบบนี้

=============================================
Manifest-Version: 1.0
Class-Path:  .\a.jar
  .\b.jar 
  .\c.jar
  ...
  ...
  ...
  .\zzzzzzzzzzzzz.jar


=============================================

แต่เวลาสร้าง jar ด้วย ant มันจะทำแบบเช็คจำนวนใน 1 บรรทัด แล้วทำการตัดให้เอง เพราะงั้นบิวต์มา อาจจะไม่ได้หน้าตาสวยงามแบบนี้นะจ๊ะ มันไม่ใช่บัค

อาจจะกลายเป็นแบบนี้
=============================================
Manifest-Version: 1.0
Class-Path:  .\a.jar .\b.jar
  .\c.jar .\d.jar ... .\zzzz
 zzzzzzzzz.jar


=============================================

ยังไงก็ลองเอา jar ที่ได้ไปทดสอบก่อนน้าาาาา
แค่นี้ก็รัน .bat ที่มี Classpath เยอะๆ ได้แล้ว \^o^/

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

ʕ•ᴥ•ʔ ♡ ยืนงงในดงจีน ปี 2 : ประสบการณ์การซื้อยา Diamox ที่โรงพยาบาลเวชศาสตร์เขตร้อน

☞ ประสบการณ์ทำเควส "ตรวจสุขภาพ ศูนย์แพทย์พัฒนา" ☜

ประสบการณ์ยื่นขอวีซ่าจีน ด้วยตัวเอง <ก.ย 2561 & ส.ค 2562>