classpath คืออะไรและฉันจะตั้งได้อย่างไร


324

ฉันแค่อ่านบรรทัดนี้:

สิ่งแรกที่รูปแบบ () วิธีการคือโหลดเทมเพลต Velocity จาก classpath ที่ชื่อว่า output.vm

โปรดอธิบายความหมายของ classpath ในบริบทนี้และฉันควรกำหนด classpath อย่างไร

คำตอบ:


530

เมื่อการเขียนโปรแกรมใน Java คุณทำให้คลาสอื่นพร้อมใช้งานสำหรับคลาสที่คุณกำลังเขียนโดยใส่อะไรแบบนี้ไว้ที่ด้านบนของซอร์สไฟล์ของคุณ:

import org.javaguy.coolframework.MyClass;

หรือบางครั้งคุณ 'นำเข้าจำนวนมาก' โดยพูดว่า:

import org.javaguy.coolframework.*;

ดังนั้นภายหลังในโปรแกรมของคุณเมื่อคุณพูดว่า:

MyClass mine = new MyClass();

Java Virtual Machine จะทราบตำแหน่งที่จะค้นหาคลาสที่คอมไพล์ของคุณ

มันเป็นไปไม่ได้เลยที่จะให้ VM มองผ่านทุก ๆ โฟลเดอร์บนเครื่องของคุณดังนั้นคุณต้องจัดเตรียมรายการสถานที่ที่จะดูให้กับ VM ทำได้โดยใส่ไฟล์โฟลเดอร์และ jar ใน classpath ของคุณ

ก่อนที่เราจะพูดถึงวิธีการตั้งค่า classpath ให้พูดคุยเกี่ยวกับไฟล์. class แพ็คเกจและไฟล์. jar

อันดับแรกให้คิดว่า MyClass outputเป็นสิ่งที่คุณสร้างขึ้นเพื่อเป็นส่วนหนึ่งของโครงการของคุณและมันก็เป็นในไดเรกทอรีในโครงการของคุณเรียกว่า ไฟล์. class จะเป็น at output/org/javaguy/coolframework/MyClass.class(พร้อมกับไฟล์อื่น ๆ ในแพ็คเกจนั้น) ในการที่จะไปที่ไฟล์นั้นพา ธ ของคุณจะต้องมีโฟลเดอร์ 'output' ไม่ใช่โครงสร้างแพ็กเกจทั้งหมดเนื่องจากคำสั่งการนำเข้าของคุณจะให้ข้อมูลทั้งหมดกับ VM

ตอนนี้สมมติว่าคุณรวม CoolFramework เข้ากับไฟล์. jar แล้ววาง CoolFramework.jar นั้นลงในไดเรกทอรี lib ในโครงการของคุณ ตอนนี้คุณจะต้องใส่lib/CoolFramework.jarclasspath ของคุณ VM จะมองเข้าไปในไฟล์ jar เพื่อหาorg/javaguy/coolframeworkส่วนและค้นหาคลาสของคุณ

ดังนั้น classpaths ประกอบด้วย:

  • ไฟล์ JAR และ
  • พา ธ ไปยังด้านบนของลำดับชั้นแพ็กเกจ

คุณจะกำหนด classpath ของคุณได้อย่างไร

วิธีแรกที่ทุกคนดูเหมือนว่าจะเรียนรู้คือตัวแปรสภาพแวดล้อม บนเครื่องยูนิกซ์คุณสามารถพูดสิ่งที่ชอบ:

export CLASSPATH=/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/

บนเครื่อง Windows คุณต้องไปที่การตั้งค่าสภาพแวดล้อมของคุณและเพิ่มหรือปรับเปลี่ยนค่าที่มีอยู่แล้ว

วิธีที่สองคือการใช้-cpพารามิเตอร์เมื่อเริ่มต้น Java เช่นนี้:

java -cp "/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/"  MyMainClass

ตัวแปรนี้เป็นวิธีที่สามซึ่งมักจะทำกับไฟล์.shหรือ.batที่คำนวณ classpath และส่งผ่านไปยัง Java ผ่าน-cpพารามิเตอร์

มี "gotcha" ที่กล่าวมาทั้งหมด ในระบบส่วนใหญ่ (Linux, Mac OS, UNIX และอื่น ๆ ) อักขระโคลอน (':') เป็นตัวแยกคลาสพา ธ ใน windowsm ตัวคั่นคือเครื่องหมายอัฒภาค (';')

ดังนั้นวิธีที่ดีที่สุดที่จะทำคืออะไร?

การตั้งค่าสิ่งต่าง ๆ ทั่วโลกผ่านตัวแปรสภาพแวดล้อมไม่ดีโดยทั่วไปด้วยเหตุผลเดียวกันกับที่ตัวแปรทั่วโลกไม่ดี คุณเปลี่ยนตัวแปรสภาพแวดล้อม CLASSPATH เพื่อให้โปรแกรมหนึ่งทำงานได้และคุณจะต้องเลิกโปรแกรมอื่น

-cp เป็นวิธีที่จะไป โดยทั่วไปฉันต้องแน่ใจว่าตัวแปรสภาพแวดล้อม CLASSPATH ของฉันเป็นสตริงว่างที่ฉันพัฒนาเมื่อใดก็ตามที่เป็นไปได้ดังนั้นฉันจึงหลีกเลี่ยงปัญหา classpath ทั่วโลก (เครื่องมือบางอย่างไม่พอใจเมื่อ classpath ทั่วโลกว่างเปล่าแม้ว่า - ฉันรู้จักสองล้านล้าน ดอลลาร์ J2EE และเซิร์ฟเวอร์ Java ที่ให้สิทธิการใช้งานพร้อมดอลลาร์ซึ่งมีปัญหาประเภทนี้ด้วยเครื่องมือบรรทัดคำสั่ง)


12
อีกบล็อกที่อธิบายอย่างดีเกี่ยวกับPATH และ CLASSPATH ใน Java คืออะไร - Path vs ClassPath
KNU

ในไพ ธ อนนั้นมีโฟลเดอร์ชื่อ Lib ที่คุณสามารถเก็บโมดูลใด ๆ เพื่อใช้เมื่อใดก็ได้ด้วยคำสั่งการนำเข้าอย่างง่าย สิ่งนี้แตกต่างจากการตั้งค่าตัวแปรสภาพแวดล้อม CLASSPATH เป็นไดเรกทอรีสำหรับแพ็คเกจ Java ของบุคคลที่สามหรือไม่ แม้ว่ามันจะเป็นโลก แต่ก็ไม่จำเป็นต้องเปลี่ยนตัวแปรอื่นนอกเหนือจากการเพิ่มแพ็คเกจเพิ่มเติม
Josie Thompson

คำตอบที่ดี แต่สำหรับคนโง่ที่นี่: ทำไมคุณไม่จำเป็นต้องใช้คำสั่ง -cp สำหรับทุกคลาสใหม่ที่คุณสร้าง? นี่จะแก้ไขได้อย่างอัตโนมัติโดยระบบของคุณใช่ไหม แต่อย่างไร บางครั้งฉันพบปัญหาที่ไม่พบ "บางสิ่ง" ใน classpath ของฉัน - ฉันเดาว่ามันเป็นเช่นนั้นเพราะฉันไม่ได้เพิ่มลงใน cp แต่ทำไมข้อผิดพลาดดังกล่าวเกิดขึ้นเพียงบางครั้งแทนที่จะเป็นเสมอ? ฉันถามสิ่งนี้เพราะจริงๆแล้วฉันไม่ได้รวมอะไรด้วยตนเองกับคำสั่ง -cp และจะไม่ทราบว่าจะทำอย่างไรกับข้อผิดพลาดแบบนั้น
Vic Torious

2
@Vic classpath จำเป็นต้องมีไดเรกทอรีด้านบนลำดับชั้นไดเรกทอรีที่สอดคล้องกับชื่อแพคเกจ ดังนั้นถ้าฉันมีorg.javaguy.coolfwกับโครงสร้างไดเรกทอรีที่สอดคล้องกัน/path/to/org/javaguy/coolfw/, classpath /path/to/จะต้องประกอบด้วย ถ้าฉันจะเพิ่มแพคเกจใหม่org.javaguy.hotfwในโครงการเดียวกันชั้นที่เกิด (ปกติ) /path/to/org/javaguy/hotfw/จบลงที่ สิ่งนี้ต้องการ classpath ที่จะบรรจุ/path/to/ซึ่งมันได้ทำไปแล้ว ดังนั้นแพ็คเกจใหม่ (และคลาสที่มีอยู่ในนั้น) จึงไม่ต้องการการเพิ่มเติมใหม่ใน classpath
เริ่ม

@Vic สำหรับตัวอย่างที่เป็นรูปธรรมมากขึ้นและคำอธิบายให้ดูที่การเรียนรู้ Java CLASSPATH (ต่อการแสดงความคิดเห็นที่ดีเยี่ยมของ KNU )
tjalling

67

คิดว่ามันเป็นคำตอบของจาวากับตัวแปรสภาพแวดล้อม PATH - ระบบปฏิบัติการค้นหา EXE บนเส้นทาง, Java ค้นหาคลาสและแพ็คเกจบนคลาสพา ธ


13

classpath เป็นพา ธ ที่ Java Virtual Machine ค้นหาคลาสแพ็คเกจและทรัพยากรที่ผู้ใช้กำหนดเองในโปรแกรม Java

ในบริบทนี้format()วิธีโหลดไฟล์เทมเพลตจากพา ธ นี้


5

classpath ในบริบทนี้เป็นสิ่งที่อยู่ในบริบททั่วไป: ทุกที่ที่ VM รู้ว่าสามารถค้นหาคลาสที่จะโหลดและทรัพยากรเช่นกัน (เช่น output.vm ในกรณีของคุณ)

ฉันเข้าใจว่า Velocity ต้องการหาไฟล์ชื่อ output.vm ที่ใดก็ได้ใน "no package" นี่อาจเป็น JAR, โฟลเดอร์ปกติ, ... รากของตำแหน่งใด ๆ ใน classpath ของแอปพลิเคชัน


2

การตั้งค่าตัวแปรระบบ CLASSPATH

ในการแสดงตัวแปร CLASSPATH ปัจจุบันให้ใช้คำสั่งเหล่านี้ใน Windows และ UNIX (เชลล์เป้าหมาย): ใน Windows: C:\> set CLASSPATH ใน UNIX: % echo $CLASSPATH

ในการลบเนื้อหาปัจจุบันของตัวแปร CLASSPATH ให้ใช้คำสั่งเหล่านี้: ใน Windows: C:\> set CLASSPATH= ใน UNIX: % unset CLASSPATH; export CLASSPATH

ในการตั้งค่าตัวแปร CLASSPATH ให้ใช้คำสั่งเหล่านี้ (ตัวอย่าง): ใน Windows: C:\> set CLASSPATH=C:\users\george\java\classes ใน UNIX: % CLASSPATH=/home/george/java/classes; export CLASSPATH


1
แม้ว่าคำสั่งเหล่านี้อาจมีประโยชน์สำหรับการทำงานกับตัวแปรสภาพแวดล้อม แต่ก็ไม่ตอบคำถาม
Hulk


1

CLASSPATH เป็นตัวแปรสภาพแวดล้อม (เช่นตัวแปรทั่วโลกของระบบปฏิบัติการที่มีให้สำหรับกระบวนการทั้งหมด) ที่จำเป็นสำหรับคอมไพเลอร์ Java และรันไทม์เพื่อค้นหาแพ็คเกจ Java ที่ใช้ในโปรแกรม Java (ทำไมไม่เรียก PACKAGEPATH?) สิ่งนี้คล้ายกับตัวแปรสภาพแวดล้อม PATH อื่นซึ่งใช้โดยเชลล์ CMD เพื่อค้นหาโปรแกรมปฏิบัติการ

CLASSPATH สามารถตั้งค่าได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้:

CLASSPATH can be set permanently in the environment: In Windows, choose control panel  System  Advanced  Environment Variables  choose "System Variables" (for all the users) or "User Variables" (only the currently login user)  choose "Edit" (if CLASSPATH already exists) or "New"  Enter "CLASSPATH" as the variable name  Enter the required directories and JAR files (separated by semicolons) as the value (e.g., ".;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar"). Take note that you need to include the current working directory (denoted by '.') in the CLASSPATH.

To check the current setting of the CLASSPATH, issue the following command:

> SET CLASSPATH

CLASSPATH can be set temporarily for that particular CMD shell session by issuing the following command:

> SET CLASSPATH=.;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar

Instead of using the CLASSPATH environment variable, you can also use the command-line option -classpath or -cp of the javac and java commands, for example,

> java classpath c:\javaproject\classes com.abc.project1.subproject2.MyClass3

0

สมาชิกแบบสแตติกของคลาสสามารถถูกเรียกได้โดยตรงโดยไม่ต้องสร้างอินสแตนซ์ของวัตถุ เนื่องจากวิธีการหลักคือ Java virtual machine แบบสแตติกสามารถเรียกใช้ได้โดยไม่ต้องสร้างอินสแตนซ์ของคลาสที่มีเมธอดหลักซึ่งเป็นจุดเริ่มต้นของโปรแกรม


0

สำหรับผู้ใช้ linux และเพื่อสรุปและเพิ่มสิ่งที่ผู้อื่นพูดที่นี่คุณควรรู้สิ่งต่อไปนี้:

  1. $ CLASSPATH คือสิ่งที่ Java ใช้เพื่อค้นหาหลายไดเรกทอรีเพื่อค้นหาคลาสที่แตกต่างกันทั้งหมดที่มันต้องการสำหรับสคริปต์ของคุณ (เว้นแต่คุณจะบอกอย่างชัดเจนด้วย -cp override) การใช้ -cp ต้องการให้คุณติดตามไดเรกทอรีทั้งหมดด้วยตนเองและคัดลอกวางบรรทัดนั้นทุกครั้งที่คุณเรียกใช้โปรแกรม (ไม่ต้องการ IMO)

  2. อักขระโคลอน (":") แยกไดเรกทอรีต่าง ๆ มีเพียง $ CLASSPATH เดียวและมีไดเรกทอรีทั้งหมดในนั้น ดังนั้นเมื่อคุณเรียกใช้ "export CLASSPATH = .... " คุณต้องการรวมค่าปัจจุบัน "$ CLASSPATH" เพื่อผนวกเข้ากับมัน ตัวอย่างเช่น:

    export CLASSPATH=.
    export CLASSPATH=$CLASSPATH:/usr/share/java/mysql-connector-java-5.1.12.jar
    

    ในบรรทัดแรกข้างต้นคุณเริ่ม CLASSPATH ด้วย 'จุด' ง่ายๆซึ่งเป็นเส้นทางไปยังไดเรกทอรีการทำงานปัจจุบันของคุณ ด้วยสิ่งนั้นเมื่อใดก็ตามที่คุณเรียกใช้จาวามันจะดูในไดเรกทอรีการทำงานปัจจุบัน (อันที่คุณอยู่) สำหรับคลาส ในบรรทัดที่สองข้างต้น $ CLASSPATH คว้าค่าที่คุณป้อนก่อนหน้า (.) และต่อท้ายพา ธ ไปยังนักดำน้ำ mysql ตอนนี้ java จะมองหาไดรเวอร์และคลาสของคุณ

  3. echo $CLASSPATH

    มีประโยชน์มากและสิ่งที่ส่งคืนควรอ่านเช่นรายการที่คั่นด้วยโคลอนของไดเรกทอรีทั้งหมดและไฟล์. jar คุณต้องการให้จาวามองหาคลาสที่ต้องการ

  4. Tomcat ไม่ได้ใช้งาน CLASSPATH อ่านสิ่งที่ควรทำเกี่ยวกับที่นี่: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.