Ich verwende den Javac-Compiler, um Java-Dateien in meinem Projekt zu kompilieren. Die Dateien werden auf mehrere Pakete verteilt: com.vistas.util
, com.vistas.converter
, com.vistas.LineHelper
, com.current.mdcontect
.
Jedes dieser Pakete enthält mehrere Java-Dateien. Ich verwende Javac so:
javac com/vistas/util/*.Java com/vistas/converter/*.Java
com.vistas.LineHelper/*.Java com/current/mdcontect/*.Java
(in einer Zeile)
Wie kann ich den Compiler anstelle von so vielen Pfaden bitten, alle Java-Dateien aus dem übergeordneten Verzeichnis com rekursiv zu kompilieren?
Ich würde auch vorschlagen, eine Art Build-Tool zu verwenden ( Ant oder Maven , Ant wird bereits vorgeschlagen und ist einfacher zu beginnen) oder ein IDE, das Bewältigt die Kompilierung (Eclipse verwendet eine inkrementelle Kompilierung mit Abstimmungsstrategie, und Sie müssen nicht einmal die "Compile" - Tasten drücken).
Wenn Sie etwas für ein größeres Projekt ausprobieren müssen und keine geeigneten Build-Tools in der Nähe haben, können Sie immer einen kleinen Trick anwenden, den javac
bietet: Die zu kompilierenden Klassennamen können in einer Datei angegeben werden. Sie müssen lediglich den Namen der Datei mit dem Präfix @
an javac
übergeben.
Wenn Sie eine Liste aller *.Java
-Dateien in Ihrem Projekt erstellen können, ist das ganz einfach:
# Linux / MacOS
$ find -name "*.Java" > sources.txt
$ javac @sources.txt
:: Windows
> dir /s /B *.Java > sources.txt
> javac @sources.txt
sources.txt
-Datei jedes Mal neu generieren müssen, wenn Sie eine neue Quelle erstellen oder eine vorhandene Datei umbenennen, was ein Kinderspiel ist zu vergessen (also fehleranfällig) und lästige aufgabe.Auf lange Sicht ist es besser, ein Tool zu verwenden, das zum Erstellen von Software entwickelt wurde.
Wenn Sie eine einfache build.xml
-Datei erstellen, die beschreibt, wie die Software erstellt wird:
<project default="compile">
<target name="compile">
<mkdir dir="bin"/>
<javac srcdir="src" destdir="bin"/>
</target>
</project>
sie können die gesamte Software kompilieren, indem Sie den folgenden Befehl ausführen:
$ ant
Maven ist nicht so einfach einzurichten und damit zu arbeiten, aber es lohnt sich, es zu lernen. Hier ist ein großartiges Tutorial für Starten eines Projekts innerhalb von 5 Minuten .
Nun das, was Ihre Entwicklungsproduktivität steigern könnte. Es gibt ein paar Open-Source-Alternativen (wie Eclipse und NetBeans , ich bevorzuge die ersteren) und sogar kommerzielle (wie IntelliJ ), die recht sind beliebt und mächtig.
Sie können das Projektgebäude im Hintergrund verwalten, sodass Sie sich nicht mit allen Befehlszeilen-Dingen befassen müssen. Es ist jedoch immer praktisch, wenn Sie wissen, was tatsächlich im Hintergrund passiert , sodass Sie gelegentliche Fehler wie ClassNotFoundException
aufspüren können.
Für größere Projekte wird immer empfohlen, ein IDE und Build-Tool zu verwenden. Ersteres steigert Ihre Produktivität, während Letzteres die Verwendung unterschiedlicher IDEs für das Projekt ermöglicht (z. B. kann Maven Eclipse-Projektdeskriptoren mit einem einfachen Befehl mvn Eclipse:eclipse
generieren). Darüber hinaus ist es einfach, ein Projekt, das mit einem einzigen Zeilenbefehl getestet/erstellt werden kann, neuen Kollegen und beispielsweise einem Continuous Integration Server vorzustellen. Stück Kuchen :-)
find . -name "*.Java" -print | xargs javac
Ein bisschen brutal, funktioniert aber wie die Hölle. (Nur für kleine Programme verwenden, absolut nicht effizient)
Wenn Ihre Shell es unterstützt, würde so etwas funktionieren?
javac com/**/*.Java
Wenn Ihre Shell **
nicht unterstützt, dann vielleicht
javac com/*/*/*.Java
funktioniert (für alle Pakete mit 3 Komponenten - für mehr oder weniger anpassen).
Im Normalfall, in dem Sie Ihr gesamtes Projekt kompilieren möchten, können Sie javac einfach mit Ihrer Hauptklasse versehen und alle erforderlichen Abhängigkeiten kompilieren lassen:
javac -sourcepath . path/to/Main.Java
javac -cp "jar_path/*" $(find . -name '*.Java')
(Ich bevorzuge es, xargs nicht zu verwenden, da es sie aufteilen und javac mehrmals ausführen kann, jeweils mit einer Teilmenge von Java Dateien, von denen einige möglicherweise andere importieren, die nicht im selben javac-Befehl angegeben sind Linie)
Wenn Sie einen App.Java-Eintrittspunkt haben, ist der Freaker-Weg mit -sourcepath am besten. Es kompiliert jede andere Java Datei, die es benötigt, unter Berücksichtigung der Importabhängigkeiten. ZB:
javac -cp "jar_path/*" -sourcepath src/ src/com/companyname/modulename/App.Java
Sie können auch ein Zielklassendateiverzeichnis angeben: -d target/
.
Ich würde Ihnen raten, mit ant zu lernen, das für diese Aufgabe sehr gut geeignet ist und sehr gut verständlich und gut dokumentiert ist.
In der Datei build.xml müssten Sie einfach ein solches Ziel definieren:
<target name="compile">
<javac srcdir="your/source/directory"
destdir="your/output/directory"
classpath="xyz.jar" />
</target>
Ich benutze nur make mit einem einfachen Makefile, das so aussieht:
JAVAC = javac -Xlint:unchecked
sources = $(Shell find . -type f -name '*.Java')
classes = $(sources:.Java=.class)
all : $(classes)
clean :
rm -f $(classes)
%.class : %.Java
$(JAVAC) $<
Es kompiliert die Quellen einzeln und rekompiliert sie nur bei Bedarf.
der Befehl javac folgt keinem rekursiven Kompilierungsprozess. Sie müssen also bei Ausführung des Befehls entweder jedes Verzeichnis angeben oder eine Textdatei mit den Verzeichnissen angeben, die Sie einschließen möchten:
javac -classpath "${CLASSPATH}" @Java_sources.txt
Ich habe dies in einem Xcode-JNI-Projekt verwendet, um meine Testklassen rekursiv zu erstellen:
find ${PROJECT_DIR} -name "*.Java" -print | xargs javac -g -classpath ${BUILT_PRODUCTS_DIR} -d ${BUILT_PRODUCTS_DIR}