Java: Làm cách nào tôi có thể biên dịch toàn bộ cấu trúc thư mục của mã?


84

Trường hợp sử dụng rất đơn giản. Tôi nhận được các tệp nguồn được tạo bằng Eclipse. Vì vậy, có một cấu trúc thư mục sâu, trong đó bất kỳ lớp Java nào có thể tham chiếu đến một lớp Java khác trong cùng một thư mục con, anh chị em hoặc cha mẹ.

Làm cách nào để biên dịch toàn bộ nội dung này từ thiết bị đầu cuối bằng javac?


Vì tò mò, bạn đang sử dụng hệ điều hành nào - Windows, Linux, Mac, v.v.? Điều này có thể giúp trả lời câu hỏi
Zach L

1
Tôi đã không biên dịch java trên dòng lệnh trong một vài năm nhưng tôi nghĩ nếu bạn chỉ cần chuyển tệp chứa main () của mình sang javac, nó sẽ tìm kiếm tất cả các tệp khác mà nó cần để biên dịch vì tất cả các tệp phụ thuộc của bạn có thể được phát hiện bắt đầu từ tệp chứa main ().
Endophage

Câu trả lời:


59

Bạn phải biết tất cả các thư mục hoặc có thể sử dụng ký tự đại diện ..

javac dir1/*.java dir2/*.java dir3/dir4/*.java dir3/dir5/*.java dir6/*src/*.java

2
tôi đã tìm ra nó: chỉ cần liệt kê tất cả các tệp .java sau javac bằng cách sử dụng tên hoặc ký tự đại diện của chúng.
euphoria83

52
Hoặc chỉ sử dụng javac $(find . -name "*.java").
Georg Schölly

48

Với Bash 4+, bạn có thể chỉ cần bật sao cầu

shopt -s globstar

và sau đó làm

javac **/*.java

4
hoặc sử dụng zsh với oh-my-zsh :)
DmitrySandalov

40

Nếu tất cả những gì bạn muốn làm là chạy lớp chính của mình (mà không biên dịch các .javatệp mà lớp chính không phụ thuộc vào), thì bạn có thể làm như sau:

cd <root-package-directory>
javac <complete-path-to-main-class>

hoặc là

javac -cp <root-package-directory> <complete-path-to-main-class>

javac sẽ tự động giải quyết tất cả các phụ thuộc và biên dịch tất cả các phụ thuộc.


4
Đây là giải pháp làm việc dễ dàng nhất cho đến nay. Tại sao mọi người không thích nó?
Alphaaa

11
Có lẽ vì tính đơn giản của nó bỏ qua thực tế là nhiều công việc biên dịch cho thư viện hoặc mã hỗ trợ sẽ không có phương thức chính liên kết đến tất cả các phụ thuộc bắt buộc. Đó là một câu trả lời hay, nhưng không phải là câu trả lời tôi sẽ sử dụng trong bất kỳ khuôn khổ / cơ sở mã công cộng nào.
Ajax

4
IMHO, khuôn khổ hoặc bất kỳ dự án công cộng nào khác nên sử dụng một số loại quản lý xây dựng. Kiểu biên dịch này chỉ có ý nghĩa đối với các dự án tư nhân nhỏ.
svenwltr

@Ajax nhưng nếu đó là trường hợp, bạn cũng có thể sử dụng các -sourcepath .tùy chọn và sau đó đặt tên cho tập tin chính cho tác dụng tương tự
coderatchet

1
Ai nói rằng có một chính? Ai nói rằng không có bốn nguồn điện? Có phải mọi lớp bạn muốn trong đầu ra của mình đều được tham chiếu bởi main (và không sử dụng META-INF / services hoặc kỹ thuật tải dịch vụ khác). Nếu tất cả những gì bạn đang làm là kiểm tra một tệp chính, thì phương pháp này vẫn ổn, tuy nhiên, nó không giải quyết được nhiệm vụ hoàn chỉnh là "biên dịch tất cả các tệp java trong một thư mục nhất định". Hệ thống xây dựng thích hợp là số 1, các công cụ cli như find . -type f -name "*.java" | xargs javac số 2 và phương pháp này chỉ khi có một điểm nhập phương thức chính duy nhất bao gồm toàn bộ ứng dụng.
Ajax

12

Tôi sẽ theo gợi ý của Jon và sử dụng Ant, vì đây là một nhiệm vụ khá phức tạp.

Tuy nhiên, nếu bạn quyết tâm lấy tất cả trong một dòng trong Terminal, trên Linux, bạn có thể sử dụng lệnh find . Nhưng tôi không khuyến khích điều này chút nào, vì không có gì đảm bảo rằng Foo.java sẽ được biên dịch sau Bar.java, ngay cả khi Foosử dụng Bar. Một ví dụ sẽ là:

find . -type f -name "*.java" -exec javac {} \;

Nếu tất cả các lớp của bạn chưa được biên dịch, nếu có một lớp khai thác hoặc trình điều khiển chính (về cơ bản là lớp chứa phương thức chính của bạn), việc biên dịch riêng lớp chính đó sẽ biên dịch hầu hết các dự án, ngay cả khi chúng nằm trong các thư mục khác nhau, vì Javac sẽ cố gắng hết khả năng của mình để giải quyết các vấn đề phụ thuộc.


1
trên windows người ta có thể sử dụng find_gnu . -type f -name "*.java" | xargs javacsau khi phiên bản gnu của find.exe được đổi tên thành find_gnu.exe. Tôi nhận gnu find.exe của mình từ msysgit.
n611x007 21/11/12

Hoặc trên lô thuần Windows: for /f "usebackq" %f in (``dir /s /b *.java``) do javac %f(sử dụng dấu ngoặc kép đơn trong dir /s /bnhưng tôi không thể tìm cách định dạng nó đúng cách).
Matthieu

Tôi nghĩ rằng findgiải pháp có vấn đề vì nó biên dịch từng lớp java riêng biệt, làm cho nó rất chậm.
AlikElzin-kilaka

12

Sau đây là phương pháp tôi tìm thấy:

1) Tạo danh sách các tệp có đường dẫn tương đối trong tệp (giả sử FilesList.txt) như sau (phân tách bằng dấu cách hoặc phân cách dòng):

foo/AccessTestInterface.java
foo/goo/AccessTestInterfaceImpl.java

2) Sử dụng lệnh:

javac @FilesList.txt -d classes

Thao tác này sẽ biên dịch tất cả các tệp và đặt các tệp lớp bên trong thư mục lớp.

Bây giờ, cách dễ dàng để tạo FilesList.txt là: Đi tới thư mục gốc nguồn của bạn.

dir *.java /s /b > FilesList.txt

Nhưng, điều này sẽ điền vào đường dẫn tuyệt đối. Sử dụng trình soạn thảo văn bản "Replace All" đường dẫn đến thư mục nguồn (bao gồm \ ở cuối) bằng "" (tức là chuỗi trống) và Lưu.


đây là "mẹ đẻ" cách hơn, như hỗ trợ javac một "mẻ" tập tin
lovespring

Cách tiếp cận "dir * .java / s / b> FilesList.txt" sẽ không hoạt động nếu đường dẫn chứa khoảng trắng. javac sẽ phàn nàn về FilesList.txt
aderesh

10

Các câu trả lời hiện có dường như chỉ liên quan đến bản thân các tệp * .java chứ không phải cách dễ dàng thực hiện điều đó với các tệp thư viện có thể cần thiết cho việc xây dựng.

Một tình huống một dòng tuyệt vời mà đệ quy nhận được tất cả các tệp * .java cũng như bao gồm các tệp * .jar cần thiết để xây dựng là:

javac -cp ".:lib/*" -d bin $(find ./src/* | grep .java)

Ở đây tệp bin là đích của các tệp lớp, lib (và có thể là thư mục làm việc hiện tại) chứa các tệp thư viện và tất cả các tệp java trong thư mục src và bên dưới được biên dịch.


Tôi đang gặp sự cố khi biên dịch mã nguồn khách hàng được tạo bởi swagger
Eenvincible

9

Bạn sẽ phải sử dụng một cái gì đó như Ant để thực hiện điều này một cách có thứ bậc:

http://ant.apache.org/manual/Tasks/javac.html

Bạn sẽ cần tạo một tập lệnh xây dựng với mục tiêu được gọi là biên dịch có chứa những điều sau:

<javac sourcepath="" srcdir="${src}"
         destdir="${build}" >
    <include name="**/*.java"/>
</javac>

Sau đó, bạn sẽ có thể biên dịch tất cả các tệp bằng cách chạy:

 ant compile

Ngoài ra, nhập dự án của bạn vào Eclipse và nó sẽ tự động biên dịch tất cả các tệp nguồn cho dự án đó.


Thật không may, điều này được thực hiện trên một máy chủ không hỗ trợ kiến.
euphoria83

2

Có một cách để thực hiện việc này mà không cần sử dụng ký tự ống dẫn, rất tiện lợi nếu bạn đang chuyển một quy trình từ ngôn ngữ lập trình khác để thực hiện việc này:

find $JAVA_SRC_DIR -name '*.java' -exec javac -d $OUTPUT_DIR {} +

Mặc dù nếu bạn đang ở trong Bash và / hoặc không ngại sử dụng tẩu, thì bạn có thể làm:

find $JAVA_SRC_DIR -name '*.java' | xargs javac -d $OUTPUT_DIR

2

Giải pháp Windows: Giả sử tất cả các tệp có trong thư mục con 'src' và bạn muốn biên dịch chúng thành 'bin'.

for /r src %i in (*.java) do javac %i -sourcepath src -d bin

Nếu src chứa tệp .java ngay bên dưới nó thì việc này sẽ nhanh hơn

javac src\\*.java -d bin

1
công trình, nhưng superslow - javac được gọi với một tập tin duy nhất cho mỗi cuộc gọi, vì vậy nếu bạn có rất nhiều trong số họ ...
St.Shadow
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.