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 se SomeClass è dichiarato nel pacchetto com.example , il nome completo della com.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 e static
  • 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 non abstract
  • 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:

  1. 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.
  2. Guarda il messaggio di errore dal comando java . Il messaggio dovrebbe terminare con il nome completo della classe che java 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.
  3. 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


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 giusto

  • Tuttavia, 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".



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow