Java Language
Il comando Java - 'java' e 'javaw'
Ricerca…
Sintassi
java [ <opt> ... ] <class-name> [ <argument> ... ]
java [ <opt> ... ] -jar <jar-file-pathname> [ <argument> ... ]
Osservazioni
Il comando java
viene utilizzato per eseguire un'applicazione Java dalla riga di comando. È disponibile come parte di qualsiasi Java SE JRE o JDK.
Sui sistemi Windows ci sono due varianti del comando java
:
- La variante
java
avvia l'applicazione in una nuova finestra della console. - La variante
javaw
avvia l'applicazione senza creare una nuova finestra della console.
Su altri sistemi (ad esempio Linux, Mac OSX, UNIX) viene fornito solo il comando java
e non viene avviata una nuova finestra della console.
Il simbolo <opt>
nella sintassi denota un'opzione sulla riga di comando java
. Gli argomenti "Opzioni Java" e "Opzioni di ridimensionamento heap e stack" coprono le opzioni più comunemente utilizzate. Altri sono trattati nell'argomento Bandi JVM .
Esecuzione di un file JAR eseguibile
I file JAR eseguibili sono il modo più semplice per assemblare il codice Java in un singolo file che può essere eseguito. * (Nota editoriale: la creazione di file JAR deve essere coperta da un argomento separato). *
Supponendo di avere un file JAR eseguibile con percorso <jar-path>
, dovresti essere in grado di eseguirlo come segue:
java -jar <jar-path>
Se il comando richiede argomenti della riga di comando, aggiungili dopo il <jar-path>
. Per esempio:
java -jar <jar-path> arg1 arg2 arg3
Se è necessario fornire ulteriori opzioni JVM sulla riga di comando java
, devono andare prima dell'opzione -jar
. Si noti che l'opzione -cp
/ -classpath
verrà ignorata se si utilizza -jar
. Il classpath dell'applicazione è determinato dal manifest del file JAR.
Esecuzione di applicazioni Java tramite una classe "principale"
Quando un'applicazione non è stata pacchettizzata come JAR eseguibile, è necessario fornire il nome di una classe entry-point sulla riga di comando java
.
Esecuzione della classe HelloWorld
L'esempio "HelloWorld" è descritto in Creazione di un nuovo programma Java . Consiste in una singola classe chiamata HelloWorld
che soddisfa i requisiti per un punto di ingresso.
Supponendo che il file "HelloWorld.class" (compilato) si trovi nella directory corrente, può essere avviato come segue:
java HelloWorld
Alcune cose importanti da notare sono:
- Dobbiamo fornire il nome della classe: non il nome del percorso per il file ".class" o il file ".java".
- Se la classe è dichiarata in un pacchetto (come la maggior parte delle classi Java), il nome della classe che forniamo al comando
java
deve essere il nome completo della classe. Ad esempio seSomeClass
è dichiarato nel pacchettocom.example
, il nome completo dellacom.example.SomeClass
saràcom.example.SomeClass
.
Specifica di un percorso di classe
A meno che non stiamo usando la sintassi del comando java -jar
, il comando java
cerca la classe da caricare cercando nel classpath; vedi The Classpath . Il comando precedente si basa sul percorso di classe predefinito che è (o include) la directory corrente. Possiamo essere più espliciti a riguardo specificando il classpath da usare usando l'opzione -cp
.
java -cp . HelloWorld
Questo dice di fare la directory corrente (che è ciò che "." Si riferisce a) l'unica voce sul classpath.
Il -cp
è un'opzione che viene elaborata dal comando java
. Tutte le opzioni che sono intese per il comando java
dovrebbero essere prima del nome della classe. Qualsiasi cosa dopo la classe verrà trattata come un argomento della riga di comando per l'applicazione Java e verrà passata all'applicazione nella String[]
che viene passata al metodo main
.
(Se non viene fornita l'opzione -cp
, java
utilizzerà il classpath fornito dalla CLASSPATH
ambiente CLASSPATH
. Se tale variabile non è impostata o è vuota, java
utilizza "." Come percorso di classe predefinito.)
Classi di ingresso
Una classe entry-point Java ha un metodo main
con la seguente firma e modificatori:
public static void main(String[] args)
Sidenote: a causa di come funzionano gli array, può anche essere
(String args[])
Quando il comando java
avvia la macchina virtuale, carica le classi del punto di ingresso specificate e prova a trovare il main
. Se ha esito positivo, gli argomenti dalla riga di comando vengono convertiti in oggetti String
Java e assemblati in una matrice. Se main
viene invocato in questo modo, l'array non sarà null
e non conterrà alcuna voce null
.
Un metodo di classe punto di ingresso valido deve eseguire quanto segue:
- Essere nominato
main
(sensibile al maiuscolo / minuscolo) - Sii
public
estatic
- Avere un tipo di reso
void
- Avere un singolo argomento con un array
String[]
. L'argomento deve essere presente e non è consentito più di un argomento. - Sii generico: i parametri di tipo non sono ammessi.
- Avere una classe chiusa non generica, di livello superiore (non nidificata o interna)
È normale dichiarare la classe come public
ma non strettamente necessaria. Da Java 5 in poi, il tipo di argomento del metodo main
potrebbe essere un varargs String
invece di un array di stringhe. main
può facoltativamente lanciare delle eccezioni, e il suo parametro può essere chiamato qualsiasi cosa, ma convenzionalmente è args
.
Punti d'ingresso JavaFX
Da Java 8 in poi il comando java
può anche avviare direttamente un'applicazione JavaFX. JavaFX è documentato nel tag JavaFX , ma un punto di accesso JavaFX deve eseguire quanto segue:
- Estendi
javafx.application.Application
- Sii
public
e nonabstract
- Non essere generico o annidato
- Avere un costruttore di no-args esplicito o implicito
public
Risoluzione dei problemi del comando 'java'
Questo esempio copre errori comuni con l'uso del comando 'java'.
"Comando non trovato"
Se ricevi un messaggio di errore come:
java: command not found
quando si tenta di eseguire il comando java
, ciò significa che non vi è alcun comando java
sul percorso di ricerca dei comandi della shell. La causa potrebbe essere:
- non hai affatto installato Java JRE o JDK,
- non hai aggiornato la variabile di ambiente
PATH
(correttamente) nel file di inizializzazione della shell, o - non hai "originato" il file di inizializzazione pertinente nella shell corrente.
Fare riferimento a "Installazione di Java" per i passaggi che è necessario eseguire.
"Impossibile trovare o caricare la classe principale"
Questo messaggio di errore viene emesso dal comando java
se non è stato possibile trovare / caricare la classe del punto di ingresso che è stata specificata. In termini generali, ci sono tre grandi ragioni per cui questo può accadere:
- Hai specificato una classe del punto di ingresso che non esiste.
- La classe esiste, ma l'hai specificata in modo errato.
- La classe esiste e l'hai specificata correttamente, ma Java non riesce a trovarla perché il classpath non è corretto.
Ecco una procedura per diagnosticare e risolvere il problema:
Scopri il nome completo della classe del punto di ingresso.
- Se si dispone di codice sorgente per una classe, il nome completo è costituito dal nome del pacchetto e dal nome della classe semplice. L'istanza che la classe "Main" è dichiarata nel pacchetto "com.example.myapp" quindi il suo nome completo è "com.example.myapp.Main".
- Se si dispone di un file di classe compilato, è possibile trovare il nome della classe eseguendo
javap
su di esso. - Se il file di classe si trova in una directory, è possibile dedurre il nome completo della classe dai nomi delle directory.
- Se il file di classe si trova in un file JAR o ZIP, è possibile dedurre il nome completo della classe dal percorso del file nel file JAR o ZIP.
Guarda il messaggio di errore dal comando
java
. Il messaggio dovrebbe terminare con il nome completo della classe chejava
sta tentando di utilizzare.- Verifica che corrisponda esattamente al nome classe completo per la classe del punto di ingresso.
- Non dovrebbe terminare con ".java" o ".class".
- Non dovrebbe contenere barre o altri caratteri non legali in un identificativo Java 1 .
- L'intelaiatura del nome dovrebbe corrispondere esattamente al nome completo della classe.
Se stai usando il nome di classe corretto, assicurati che la classe sia effettivamente sul classpath:
- Calcolare il nome del percorso a cui il nome della classe corrisponde; consulta Mapping dei nomi di classe ai nomi di percorso
- Calcola qual è il percorso di classe; vedere questo esempio: diversi modi per specificare il classpath
- Osservare ciascuno dei file JAR e ZIP sul classpath per vedere se contengono una classe con il nome di percorso richiesto.
- Guarda ogni directory per vedere se il percorso si risolve in un file all'interno della directory.
Se il controllo del classpath a mano non ha riscontrato il problema, è possibile aggiungere le opzioni -Xdiag
e -XshowSettings
. Il primo elenca tutte le classi caricate e quest'ultima stampa le impostazioni che includono il classpath effettivo per JVM.
Infine, ci sono alcune cause oscure per questo problema:
- Un file JAR eseguibile con un attributo
Main-Class
che specifica una classe che non esiste. - Un file JAR eseguibile con un attributo
Class-Path
errato. - Se si incasinano 2 opzioni prima del nome della classe, il comando
java
può tentare di interpretarne uno come nomeclassifica. - Se qualcuno ha ignorato le regole di stile Java e ha utilizzato identificativi di pacchetto o classe che differiscono solo nel caso di lettere, e si sta eseguendo su una piattaforma che considera il caso di lettere nei nomi di file come non significativo.
- Problemi con gli omogei nei nomi delle classi nel codice o sulla riga di comando.
"Metodo principale non trovato nella classe <nome>"
Questo problema si verifica quando il comando java
è in grado di trovare e caricare la classe che è stata nominata, ma non è in grado di trovare un metodo entry-point.
Ci sono tre possibili spiegazioni:
- Se si sta tentando di eseguire un file JAR eseguibile, il manifest di JAR presenta un attributo "Main-Class" non corretto che specifica una classe che non è una classe del punto di ingresso valida.
- Hai detto al comando
java
una classe che non è una classe entry point. - La classe del punto di ingresso non è corretta; vedere le classi dei punti di ingresso per ulteriori informazioni.
Altre risorse
- Cosa significa "Impossibile trovare o caricare la classe principale"?
- http://docs.oracle.com/javase/tutorial/getStarted/problems/index.html
1 - Da Java 8 e java
successive, il comando java
associa in modo utile un separatore di file ("/" o "") a un punto ("."). Tuttavia, questo comportamento non è documentato nelle pagine di manuale.
2 - Un caso davvero oscuro è se copi e incolli un comando da un documento formattato in cui l'editor di testo ha usato un "trattino lungo" invece di un trattino normale.
Esecuzione di un'applicazione Java con dipendenze di libreria
Questa è una continuazione degli esempi "main class" e "eseguibili JAR" .
Le tipiche applicazioni Java sono costituite da un codice specifico dell'applicazione e da vari codici libreria riutilizzabili implementati o implementati da terze parti. Questi ultimi sono comunemente definiti come dipendenze delle librerie e sono generalmente pacchettizzati come file JAR.
Java è un linguaggio dinamicamente vincolato. Quando si esegue un'applicazione Java con dipendenze della libreria, la JVM deve sapere dove si trovano le dipendenze in modo che possa caricare le classi come richiesto. In generale, ci sono due modi per affrontare questo:
L'applicazione e le sue dipendenze possono essere riconfezionate in un singolo file JAR che contiene tutte le classi e le risorse richieste.
La JVM può sapere dove trovare i file JAR dipendenti tramite il percorso di classe di runtime.
Per un file JAR eseguibile, il percorso di classe runtime è specificato dall'attributo manifest "Class-Path". (Nota editoriale: questo dovrebbe essere descritto in un argomento separato sul comando jar
.) In caso contrario, il percorso di classe runtime deve essere fornito utilizzando l'opzione -cp
o utilizzando la CLASSPATH
ambiente CLASSPATH
.
Ad esempio, supponiamo di avere un'applicazione Java nel file "myApp.jar" la cui classe del punto di ingresso è com.example.MyApp
. Supponiamo inoltre che l'applicazione dipenda dai file JAR della libreria "lib / library1.jar" e "lib / library2.jar". Potremmo avviare l'applicazione usando il comando java
come segue in una riga di comando:
$ # Alternative 1 (preferred)
$ java -cp myApp.jar:lib/library1.jar:lib/library2.jar com.example.MyApp
$ # Alternative 2
$ export CLASSPATH=myApp.jar:lib/library1.jar:lib/library2.jar
$ java com.example.MyApp
(Su Windows, dovresti usare ;
invece di :
come separatore del classpath, e dovresti impostare la variabile (locale) CLASSPATH
usando set
piuttosto che export
.)
Mentre uno sviluppatore Java sarebbe a proprio agio con questo, non è "user friendly". Quindi è pratica comune scrivere un semplice script di shell (o un file batch di Windows) per nascondere i dettagli di cui l'utente non ha bisogno di essere informato. Ad esempio, se metti il seguente script di shell in un file chiamato "myApp", lo rendi eseguibile e lo metti in una directory sul percorso di ricerca del comando:
#!/bin/bash
# The 'myApp' wrapper script
export DIR=/usr/libexec/myApp
export CLASSPATH=$DIR/myApp.jar:$DIR/lib/library1.jar:$DIR/lib/library2.jar
java com.example.MyApp
allora potresti eseguirlo come segue:
$ myApp arg1 arg2 ...
Qualsiasi argomento sulla riga di comando verrà passato all'applicazione Java tramite l'espansione "$@"
. (Puoi fare qualcosa di simile con un file batch di Windows, anche se la sintassi è diversa.)
Spazi e altri caratteri speciali negli argomenti
Prima di tutto, il problema di gestire gli spazi negli argomenti NON è in realtà un problema Java. Piuttosto, è un problema che deve essere gestito dalla shell dei comandi che si sta utilizzando quando si esegue un programma Java.
Ad esempio, supponiamo di avere il seguente semplice programma che stampa la dimensione di un file:
import java.io.File;
public class PrintFileSizes {
public static void main(String[] args) {
for (String name: args) {
File file = new File(name);
System.out.println("Size of '" + file + "' is " + file.size());
}
}
}
Supponiamo ora di voler stampare la dimensione di un file il cui percorso ha spazi in esso; ad esempio /home/steve/Test File.txt
. Se eseguiamo il comando in questo modo:
$ java PrintFileSizes /home/steve/Test File.txt
la shell non saprà che /home/steve/Test File.txt
è in realtà un percorso. Invece, passerà 2 argomenti distinti all'applicazione Java, che tenterà di trovare le rispettive dimensioni dei file, e fallirà perché i file con quei percorsi (probabilmente) non esistono.
Soluzioni che utilizzano una shell POSIX
Shell POSIX includono sh
come derivati e quali bash
e ksh
. Se stai usando una di queste shell, allora puoi risolvere il problema citando l'argomento.
$ java PrintFileSizes "/home/steve/Test File.txt"
Le doppie virgolette attorno al nome del percorso dicono alla shell che dovrebbe essere passata come un singolo argomento. Le virgolette saranno rimosse quando questo accadrà. Ci sono un paio di altri modi per farlo:
$ java PrintFileSizes '/home/steve/Test File.txt'
Le virgolette singole (diritte) sono trattate come virgolette, tranne che sopprimono anche varie espansioni all'interno dell'argomento.
$ java PrintFileSizes /home/steve/Test\ File.txt
Un backslash sfugge allo spazio seguente e fa sì che non venga interpretato come un separatore di argomenti.
Per una documentazione più completa, comprese le descrizioni di come trattare altri caratteri speciali negli argomenti, fare riferimento all'argomento di citazione nella documentazione di Bash .
Soluzione per Windows
Il problema fondamentale per Windows è che a livello di sistema operativo, gli argomenti vengono passati a un processo figlio come una singola stringa ( origine ). Ciò significa che la responsabilità finale di parsing (o ri-analisi) della riga di comando ricade sul programma o sulle sue librerie di runtime. C'è molta incongruenza.
Nel caso Java, per farla breve:
Puoi mettere virgolette su un argomento in un comando
java
, e questo ti permetterà di passare argomenti con spazi al loro interno.Apparentemente, il comando
java
stesso sta analizzando la stringa di comando, e lo ottiene più o meno giustoTuttavia, quando si tenta di combinare questo con l'uso di
SET
e la sostituzione delle variabili in un file batch, diventa davvero complicato se vengono rimosse le virgolette.La shell
cmd.exe
apparentemente ha altri meccanismi di escape; es. raddoppiando le virgolette e usando^
escapes.
Per maggiori dettagli, fare riferimento alla documentazione del file batch .
Opzioni Java
Il comando java
supporta una vasta gamma di opzioni:
Tutte le opzioni iniziano con un trattino singolo o segno meno (
-
): la convenzione GNU / Linux di utilizzo--
per le opzioni "lunghe" non è supportata.Le opzioni devono apparire prima dell'argomento
<classname>
o-jar <jarfile>
per essere riconosciuti. Qualsiasi argomento dopo di essi verrà trattato come argomento da passare all'app Java in esecuzione.Le opzioni che non iniziano con
-X
o-XX
sono opzioni standard. Puoi fare affidamento su tutte le implementazioni Java 1 per supportare qualsiasi opzione standard.Le opzioni che iniziano con
-X
sono opzioni non standard e possono essere ritirate da una versione Java alla successiva.Le opzioni che iniziano con
-XX
sono opzioni avanzate e possono anche essere ritirate.
Impostazione delle proprietà del sistema con -D
L'opzione -D<property>=<value>
viene utilizzata per impostare una proprietà nell'oggetto Properties
del sistema. Questo parametro può essere ripetuto per impostare proprietà differenti.
Opzioni di memoria, Stack e Garbage Collector
Le opzioni principali per il controllo delle dimensioni di heap e stack sono documentate in Impostazione delle dimensioni di heap, PermGen e stack . (Nota editoriale: le opzioni di Garbage Collector devono essere descritte nello stesso argomento).
Abilitazione e disabilitazione delle asserzioni
Le opzioni -ea
e -da
rispettivamente abilitano e disabilitano il controllo delle assert
Java:
- Il controllo di tutte le asserzioni è disabilitato per impostazione predefinita.
- L'opzione
-ea
consente di verificare tutte le asserzioni - Il
-ea:<packagename>...
consente di verificare le asserzioni in un pacchetto e tutti i sotto- pacchetti. - Il
-ea:<classname>...
abilita il controllo delle asserzioni in una classe. - L'opzione
-da
disabilita il controllo di tutte le asserzioni - Il
-da:<packagename>...
disabilita il controllo delle asserzioni in un pacchetto e tutti i pacchetti secondari . - Il
-da:<classname>...
disabilita il controllo delle asserzioni in una classe. - L'opzione
-esa
consente di verificare tutte le classi di sistema. - L'opzione
-dsa
disabilita il controllo di tutte le classi di sistema.
Le opzioni possono essere combinate. Per esempio.
$ # Enable all assertion checking in non-system classes
$ java -ea -dsa MyApp
$ # Enable assertions for all classes in a package except for one.
$ java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat MyApp
Si noti che l'abilitazione al controllo delle asserzioni è suscettibile di alterare il comportamento di una programmazione Java.
- È responsabile rendere l'applicazione più lenta in generale.
- Può far sì che i metodi specifici impieghino più tempo per essere eseguiti, il che potrebbe cambiare il tempo dei thread in un'applicazione multi-thread.
- Può introdurre relazioni fortuite prima di quelle che possono causare la scomparsa delle anomalie della memoria.
- Una dichiarazione
assert
erroneamente implementata potrebbe avere effetti collaterali indesiderati.
Selezione del tipo di VM
I -client
e -server
opzioni consentono di scegliere tra due diverse forme di HotSpot VM:
- Il modulo "client" è ottimizzato per le applicazioni utente e offre un avvio più veloce.
- Il modulo "server" è ottimizzato per le applicazioni di lunga durata. Ci vuole più tempo per acquisire statistiche durante il "warm up" JVM, che consente al compilatore JIT di ottimizzare il codice nativo.
Per impostazione predefinita, la JVM verrà eseguita in modalità 64 bit, se possibile, in base alle funzionalità della piattaforma. Le opzioni -d32
e -d64
consentono di selezionare la modalità in modo esplicito.
1 - Controlla il manuale ufficiale per il comando java
. A volte un'opzione standard è descritta come "soggetto a modifiche".