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.