Classpath là gì và làm cách nào để thiết lập nó?


324

Tôi chỉ đọc dòng này:

Điều đầu tiên mà phương thức format () thực hiện là tải một mẫu Velocity từ đường dẫn lớp có tên output.vm

Vui lòng giải thích ý nghĩa của classpath trong ngữ cảnh này và cách tôi nên thiết lập classpath.

Câu trả lời:


530

Khi lập trình bằng Java, bạn làm cho các lớp khác có sẵn cho lớp bạn đang viết bằng cách đặt một cái gì đó như thế này ở đầu tệp nguồn của bạn:

import org.javaguy.coolframework.MyClass;

Hoặc đôi khi bạn 'nhập hàng loạt' công cụ bằng cách nói:

import org.javaguy.coolframework.*;

Vì vậy, sau này trong chương trình của bạn khi bạn nói:

MyClass mine = new MyClass();

Máy ảo Java sẽ biết nơi tìm lớp biên dịch của bạn.

Sẽ không thực tế khi VM nhìn qua mọi thư mục trên máy của bạn, vì vậy bạn phải cung cấp cho VM một danh sách các địa điểm cần tìm. Điều này được thực hiện bằng cách đặt các tệp thư mục và tệp jar trên đường dẫn lớp của bạn.

Trước khi chúng ta nói về cách thiết lập đường dẫn lớp, hãy nói về các tệp. Class, gói và tệp .jar.

Trước tiên, hãy giả sử rằng MyClass là thứ bạn đã xây dựng như một phần của dự án của bạn và nó nằm trong một thư mục trong dự án của bạn được gọi output. Tệp. Class sẽ có tại output/org/javaguy/coolframework/MyClass.class(cùng với mọi tệp khác trong gói đó). Để có được tệp đó, đường dẫn của bạn chỉ cần chứa thư mục 'đầu ra', chứ không phải toàn bộ cấu trúc gói, vì câu lệnh nhập của bạn cung cấp tất cả thông tin đó cho VM.

Bây giờ, giả sử rằng bạn gói CoolFramework thành một tệp .jar và đặt CoolFramework.jar vào một thư mục lib trong dự án của bạn. Bây giờ bạn sẽ cần phải đưa lib/CoolFramework.jarvào classpath của bạn. VM sẽ xem xét bên trong tệp jar org/javaguy/coolframeworkvà tìm lớp của bạn.

Vì vậy, classpath chứa:

  • Tệp JAR và
  • Đường dẫn đến đầu phân cấp gói.

Làm thế nào để bạn thiết lập classpath của bạn?

Cách đầu tiên mọi người dường như học là với các biến môi trường. Trên một máy unix, bạn có thể nói một cái gì đó như:

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

Trên máy Windows, bạn phải vào cài đặt môi trường của mình và thêm hoặc sửa đổi giá trị đã có.

Cách thứ hai là sử dụng -cptham số khi khởi động Java, như thế này:

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

Một biến thể của điều này là cách thứ ba thường được thực hiện với một .shhoặc .battệp tính toán đường dẫn lớp và chuyển nó tới Java thông qua -cptham số.

Có một "gotcha" với tất cả các bên trên. Trên hầu hết các hệ thống (Linux, Mac OS, UNIX, v.v.), ký tự dấu hai chấm (':') là dấu phân cách đường dẫn. Trong windowsm, dấu phân cách là dấu chấm phẩy (';')

Vì vậy, cách tốt nhất để làm điều đó là gì?

Đặt công cụ trên toàn cầu thông qua các biến môi trường là xấu, thường là vì các loại lý do tương tự mà các biến toàn cục là xấu. Bạn thay đổi biến môi trường CLASSPATH để một chương trình hoạt động và cuối cùng bạn phá vỡ một chương trình khác.

-Cp là con đường để đi. Tôi thường đảm bảo rằng biến môi trường CLASSPATH của tôi là một chuỗi trống nơi tôi phát triển, bất cứ khi nào có thể, để tôi tránh các vấn đề về đường dẫn toàn cầu (một số công cụ không hài lòng khi đường dẫn toàn cầu trống - mặc dù tôi biết về hai nghìn phổ biến đô la được cấp phép máy chủ J2EE và Java có loại vấn đề này với các công cụ dòng lệnh của họ).


12
Một blog được giải thích rõ ràng khác về PATH và CLASSPATH trong Java - Path vs ClassPath
KNU

Trong python có một thư mục có tên Lib nơi bạn có thể lưu trữ bất kỳ mô-đun nào để sử dụng bất cứ lúc nào với một câu lệnh nhập đơn giản. Điều này có khác với việc đặt biến môi trường CLASSPATH thành một thư mục cho các gói java của bên thứ ba không? Mặc dù nó sẽ là toàn cầu, nhưng sẽ không cần phải thay đổi biến, ngoài việc thêm nhiều gói hơn.
Josie Thompson

Câu trả lời hay, nhưng đối với các hình nộm ở đây: Tại sao bạn không cần sử dụng lệnh -cp cho mỗi lớp mới bạn tạo? Điều này chắc chắn được giải quyết tự động bởi hệ thống của bạn phải không? Nhưng bằng cách nào? Đôi khi tôi gặp phải một vấn đề trong đó "cái gì đó" không thể tìm thấy trong đường dẫn lớp của tôi - tôi đoán là như vậy bởi vì tôi đã không thêm nó vào cp, nhưng tại sao đôi khi lại xảy ra lỗi như vậy? Tôi hỏi điều này bởi vì, thành thật mà nói, tôi chưa bao giờ bao gồm bất cứ điều gì bằng tay với lệnh -cp và không biết phải làm gì với một lỗi như thế
Vic Torious

2
@Vic Classpath cần chứa thư mục phía trên hệ thống phân cấp thư mục tương ứng với tên gói. Vì vậy, nếu tôi có org.javaguy.coolfw, với cấu trúc thư mục tương ứng /path/to/org/javaguy/coolfw/, đường dẫn lớp sẽ cần phải chứa /path/to/. Nếu tôi thêm một gói mới org.javaguy.hotfwtrong cùng một dự án, lớp kết quả (thường) sẽ kết thúc tại /path/to/org/javaguy/hotfw/. Điều này đòi hỏi classpath phải chứa /path/to/, cái mà nó đã làm. Vì vậy, gói mới (và các lớp có trong đó) không yêu cầu bổ sung mới cho đường dẫn lớp.
bắt đầu

@Vic Để biết ví dụ và giải thích cụ thể hơn, hãy xem Làm chủ Java CLASSPATH (theo nhận xét xuất sắc của KNU )
diễn ra vào

67

Hãy nghĩ về nó như câu trả lời của Java cho biến môi trường PATH - Các hệ điều hành tìm kiếm EXE trên PATH, Java tìm kiếm các lớp và gói trên đường dẫn lớp.


13

Đường dẫn lớp là đường dẫn mà Máy ảo Java tìm kiếm các lớp, gói và tài nguyên do người dùng định nghĩa trong các chương trình Java.

Trong ngữ cảnh này, format()phương thức tải một tệp mẫu từ đường dẫn này.


5

Classpath trong ngữ cảnh này chính xác là trong bối cảnh chung: bất cứ nơi nào VM biết nó đều có thể tìm thấy các lớp được tải và tài nguyên cũng vậy (chẳng hạn như output.vm trong trường hợp của bạn).

Tôi hiểu Velocity dự kiến ​​sẽ tìm thấy một tệp có tên output.vm ở bất cứ đâu trong "không có gói". Đây có thể là JAR, thư mục thông thường, ... Thư mục gốc của bất kỳ vị trí nào trong đường dẫn lớp của ứng dụng.


2

Đặt biến hệ thống CLASSPATH

Để hiển thị biến CLASSPATH hiện tại, hãy sử dụng các lệnh này trong Windows và UNIX (Bourne shell): Trong Windows: C:\> set CLASSPATH Trong UNIX: % echo $CLASSPATH

Để xóa nội dung hiện tại của biến CLASSPATH, hãy sử dụng các lệnh sau: Trong Windows: C:\> set CLASSPATH= Trong UNIX: % unset CLASSPATH; export CLASSPATH

Để đặt biến CLASSPATH, hãy sử dụng các lệnh sau (ví dụ): Trong Windows: C:\> set CLASSPATH=C:\users\george\java\classes Trong UNIX: % CLASSPATH=/home/george/java/classes; export CLASSPATH


1
Mặc dù các lệnh này có thể hữu ích để làm việc với các biến môi trường, nhưng điều này không trả lời câu hỏi
Hulk

1

Classpath là một biến môi trường của hệ thống. Cài đặt của biến này được sử dụng để cung cấp thư mục gốc của bất kỳ hệ thống phân cấp gói nào cho trình biên dịch java.


1

CLASSPATH là một biến môi trường (nghĩa là các biến toàn cục của hệ điều hành có sẵn cho tất cả các quy trình) cần thiết cho trình biên dịch Java và thời gian chạy để định vị các gói Java được sử dụng trong chương trình Java. (Tại sao không gọi PACKAGEPATH?) Điều này tương tự với một biến môi trường PATH khác, được sử dụng bởi trình bao CMD để tìm các chương trình thực thi.

CLASSPATH có thể được đặt theo một trong các cách sau:

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

Thành viên tĩnh của một lớp có thể được gọi trực tiếp mà không cần tạo đối tượng. Vì phương thức chính là Java ảo nên Máy có thể gọi nó mà không cần tạo bất kỳ phiên bản nào của lớp chứa phương thức chính, là điểm bắt đầu của chương trình.


0

Đối với người dùng linux và để tổng hợp và thêm vào những gì người khác đã nói ở đây, bạn nên biết những điều sau:

  1. $ CLASSPATH là những gì Java sử dụng để xem qua nhiều thư mục để tìm tất cả các lớp khác nhau mà nó cần cho tập lệnh của bạn (trừ khi bạn nói rõ ràng bằng cách khác với ghi đè -cp). Sử dụng -cp yêu cầu bạn theo dõi tất cả các thư mục theo cách thủ công và sao chép-dán dòng đó mỗi khi bạn chạy chương trình (không thích IMO).

  2. Ký tự dấu hai chấm (":") phân tách các thư mục khác nhau. Chỉ có một $ CLASSPATH và nó có tất cả các thư mục trong đó. Vì vậy, khi bạn chạy "xuất CLASSPATH = ....", bạn muốn bao gồm giá trị hiện tại "$ CLASSPATH" để thêm vào nó. Ví dụ:

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

    Trong dòng đầu tiên ở trên, bạn bắt đầu CLASSPATH chỉ bằng một 'dấu chấm' đơn giản, đó là đường dẫn đến thư mục làm việc hiện tại của bạn. Cùng với đó, bất cứ khi nào bạn chạy java, nó sẽ tìm trong thư mục làm việc hiện tại (thư mục bạn đang ở) cho các lớp. Trong dòng thứ hai ở trên, $ CLASSPATH lấy giá trị mà bạn đã nhập trước đó (.) Và nối thêm đường dẫn đến một dirver mysql. Bây giờ, java sẽ tìm trình điều khiển VÀ cho các lớp của bạn.

  3. echo $CLASSPATH

    là rất tiện dụng và những gì nó trả về sẽ đọc như một danh sách được phân tách bằng dấu hai chấm của tất cả các thư mục và các tệp .jar, bạn muốn java tìm kiếm các lớp mà nó cần.

  4. Tomcat không sử dụng CLASSPATH. Đọc những gì cần làm về điều đó ở đây: https://tomcat.apache.org/tomcat-8.0-doc/ class-loader-howto.html

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.