Zoeken…


Syntaxis

  • java [ <opt> ... ] <class-name> [ <argument> ... ]

  • java [ <opt> ... ] -jar <jar-file-pathname> [ <argument> ... ]

Opmerkingen

De java opdracht wordt gebruikt voor het uitvoeren van een Java-toepassing vanaf de opdrachtregel. Het is beschikbaar als onderdeel van elke Java SE JRE of JDK.

Op Windows-systemen zijn er twee varianten van het java commando:

  • De java variant start de toepassing in een nieuw consolevenster.
  • De javaw start de toepassing zonder een nieuw consolevenster te maken.

Op andere systemen (bijv. Linux, Mac OSX, UNIX) wordt alleen het java commando gegeven en wordt geen nieuw consolevenster geopend.

Het symbool <opt> in de syntaxis geeft een optie aan op de opdrachtregel van java . De onderwerpen "Java-opties" en "Opties voor heap- en stapelgrootte" hebben betrekking op de meest gebruikte opties. Anderen worden behandeld in het onderwerp JVM-vlaggen .

Een uitvoerbaar JAR-bestand uitvoeren

Uitvoerbare JAR-bestanden zijn de eenvoudigste manier om Java-code samen te voegen in een enkel bestand dat kan worden uitgevoerd. * (Noot redactie: het maken van JAR-bestanden moet in een afzonderlijk onderwerp worden behandeld.) *

Ervan uitgaande dat u een uitvoerbaar JAR-bestand met padnaam <jar-path> , zou u het als volgt moeten kunnen uitvoeren:

java -jar <jar-path>

Als de opdracht opdrachtregelargumenten vereist, voegt u deze toe na het <jar-path> . Bijvoorbeeld:

java -jar <jar-path> arg1 arg2 arg3

Als u extra JVM-opties op de java opdrachtregel moet -jar , moeten deze vóór de optie -jar . Merk op dat een -cp / -classpath optie wordt genegeerd als u -jar . Het klassenpad van de toepassing wordt bepaald door het JAR-bestandsmanifest.

Java-applicaties uitvoeren via een "hoofdklasse"

Wanneer een toepassing niet als uitvoerbare JAR is verpakt, moet u de naam van een entry-point-klasse java op de java opdrachtregel.

De klasse HelloWorld uitvoeren

Het voorbeeld "HelloWorld" wordt beschreven in Een nieuw Java-programma maken . Het bestaat uit een enkele klasse met de naam HelloWorld die voldoet aan de vereisten voor een instappunt.

Ervan uitgaande dat het (gecompileerde) bestand "HelloWorld.class" zich in de huidige map bevindt, kan het als volgt worden gestart:

java HelloWorld

Enkele belangrijke dingen om op te merken zijn:

  • We moeten de naam van de klasse opgeven: niet de padnaam voor het bestand ".class" of het bestand ".java".
  • Als de klasse in een pakket wordt gedeclareerd (zoals de meeste Java-klassen zijn), moet de klassenaam die we aan het java commando leveren de volledige klassenaam zijn. Als SomeClass bijvoorbeeld wordt gedeclareerd in het pakket com.example , is de volledige com.example.SomeClass .

Een klassenpad opgeven

Tenzij we de syntaxis van de java -jar opdracht gebruiken, zoekt de java opdracht naar de klasse die moet worden geladen door het klassepad te doorzoeken; zie The Classpath . De bovenstaande opdracht is afhankelijk van het standaardklassepad (of inclusief) de huidige map. We kunnen dit explicieter maken door het te gebruiken classpath op te geven met de optie -cp .

java -cp . HelloWorld

Dit zegt dat de huidige directory (waarnaar "." Verwijst) het enige item in het classpath wordt.

De -cp is een optie die wordt verwerkt door het java commando. Alle opties die bedoeld zijn voor het java commando moeten vóór de klassennaam staan. Alles wat na de les zal worden behandeld als een command line argument voor de Java-toepassing, en zal worden doorgegeven aan de toepassing in de String[] die aan de doorgegeven main methode.

(Als er geen -cp optie is opgegeven, gebruikt de java het classpath dat wordt opgegeven door de omgevingsvariabele CLASSPATH . Als die variabele niet is ingesteld of leeg is, gebruikt java "." Als standaard classpath.)

Ingangspunt klassen

Een Java entry-point klasse heeft een main methode met de volgende handtekening en modifiers:

public static void main(String[] args)

Sidenote: vanwege de manier waarop arrays werken, kan dit ook zijn (String args[])

Wanneer het java commando de virtuele machine start, laadt het de opgegeven entry-point klassen en probeert het main te vinden. Als dit lukt, worden de argumenten van de opdrachtregel geconverteerd naar Java String objecten en verzameld in een array. Als main op deze manier wordt aangeroepen, is de array niet null en bevat deze geen null items.

Een geldige entry-point class-methode moet het volgende doen:

  • Worden genoemd main (hoofdlettergevoelig)
  • Wees public en static
  • Voer een void retourtype in
  • Heb een enkel argument met een array String[] . Het argument moet aanwezig zijn en niet meer dan één argument is toegestaan.
  • Wees generiek: typeparameters zijn niet toegestaan.
  • Heb een niet-generieke insluitende klasse op het hoogste niveau (niet genest of innerlijk)

Het is gebruikelijk om de klasse public te verklaren, maar dit is niet strikt noodzakelijk. Java 5 verder, de main kunnen methode argumenttype zijn een String varargs plaats van een tekenreeksarray. main kan optioneel uitzonderingen genereren, en de parameter kan alles worden genoemd, maar conventioneel is het args .

JavaFX entry-punten

Vanaf Java 8 kan het java commando ook rechtstreeks een JavaFX-toepassing starten. JavaFX is gedocumenteerd in de JavaFX- tag, maar een JavaFX entry-point moet het volgende doen:

  • Verleng javafx.application.Application
  • Wees public en niet abstract
  • Niet generiek of genest zijn
  • Heb een expliciete of impliciete public no-args constructor

Problemen met de opdracht 'java' oplossen

Dit voorbeeld behandelt veelvoorkomende fouten bij het gebruik van de opdracht 'java'.

"Opdracht niet gevonden"

Als u een foutmelding krijgt zoals:

java: command not found

wanneer u probeert het java commando uit te voeren, betekent dit dat er geen java commando op het opdrachtzoekpad van uw shell staat. De oorzaak kan zijn:

  • je hebt helemaal geen Java JRE of JDK geïnstalleerd,
  • u hebt de omgevingsvariabele PATH niet (correct) bijgewerkt in uw shell-initialisatiebestand, of
  • u hebt niet het relevante initialisatiebestand in de huidige shell "gevonden".

Raadpleeg "Java installeren" voor de stappen die u moet nemen.

"Kon hoofdklasse niet vinden of laden"

Dit foutbericht wordt uitgevoerd door het java commando als het de opgegeven entry-class niet heeft kunnen vinden / laden. Over het algemeen zijn er drie brede redenen waarom dit kan gebeuren:

  • U hebt een ingangspuntklasse opgegeven die niet bestaat.
  • De klasse bestaat, maar u hebt deze onjuist opgegeven.
  • De klasse bestaat en u hebt deze correct opgegeven, maar Java kan deze niet vinden omdat het classpath onjuist is.

Hier is een procedure om het probleem te diagnosticeren en op te lossen:

  1. Ontdek de volledige naam van de entry-pointklasse.

    • Als u broncode voor een klasse hebt, bestaat de volledige naam uit de pakketnaam en de eenvoudige klassenaam. De instantie van de klasse "Main" wordt gedeclareerd in het pakket "com.example.myapp" en de volledige naam is "com.example.myapp.Main".
    • Als u een gecompileerd klassenbestand hebt, kunt u de javap vinden door javap erop uit te voeren.
    • Als het klassenbestand zich in een map bevindt, kunt u de volledige klassenaam afleiden uit de mapnamen.
    • Als het klassenbestand zich in een JAR- of ZIP-bestand bevindt, kunt u de volledige klassenaam afleiden uit het bestandspad in het JAR- of ZIP-bestand.
  2. Bekijk het foutbericht van het java commando. Het bericht moet eindigen met de volledige klassennaam die java probeert te gebruiken.

    • Controleer of deze exact overeenkomt met de volledige klassenaam voor de ingangspuntklasse.
    • Het moet niet eindigen met ".java" of ".class".
    • Het mag geen schuine strepen of andere tekens bevatten die niet legaal zijn in een Java-ID 1 .
    • De behuizing van de naam moet exact overeenkomen met de volledige klassenaam.
  3. Als u de juiste klassenaam gebruikt, moet u ervoor zorgen dat de klasse zich op het klassenpad bevindt:

Als het probleem niet is gevonden door het classpath handmatig te controleren, kunt u de opties -Xdiag en -XshowSettings . De eerste lijst toont alle klassen die zijn geladen en de laatste drukt instellingen af die het effectieve klassenpad voor de JVM bevatten.

Ten slotte zijn er enkele obscure oorzaken voor dit probleem:

  • Een uitvoerbaar JAR-bestand met een kenmerk Main-Class dat een klasse aangeeft die niet bestaat.
  • Een uitvoerbaar JAR-bestand met een onjuist Class-Path kenmerk.
  • Als je rotzooi op 2 de opties voor de classname, de java kan commando proberen om één van hen te interpreteren als de classname.
  • Als iemand regels in Java-stijl heeft genegeerd en pakket- of klasse-ID's heeft gebruikt die alleen in hoofdletters en kleine letters verschillen, en u op een platform werkt dat hoofdletters en kleine letters in bestandsnamen beschouwt als niet-significant.
  • Problemen met homoglyphs in klassennamen in de code of op de opdrachtregel.

"Hoofdmethode niet gevonden in klasse <naam>"

Dit probleem treedt op wanneer het java commando de klasse die u heeft genomineerd kan vinden en laden, maar vervolgens geen ingangspuntmethode kan vinden.

Er zijn drie mogelijke verklaringen:

  • Als u probeert een uitvoerbaar JAR-bestand uit te voeren, heeft het JAR-manifest een onjuist "Main-Class" -kenmerk dat een klasse opgeeft die geen geldige entry point-klasse is.
  • U hebt het java commando een klasse verteld die geen ingangspuntklasse is.
  • De ingangspuntklasse is onjuist; zie Invoerpuntklassen voor meer informatie.

Andere bronnen


1 - Vanaf Java 8 en later zal het java commando een scheidingsteken voor bestandsnamen ("/" of "") nuttig toewijzen aan een punt ("."). Dit gedrag is echter niet gedocumenteerd in de handleidingpagina's.

2 - Een echt obscuur geval is als u een opdracht uit een opgemaakt document kopieert en plakt waarbij de teksteditor een "lang koppelteken" heeft gebruikt in plaats van een gewoon koppelteken.

Een Java-toepassing uitvoeren met bibliotheekafhankelijkheden

Dit is een voortzetting van de voorbeelden "hoofdklasse" en "uitvoerbare JAR" .

Typische Java-applicaties bestaan uit een applicatiespecifieke code en verschillende herbruikbare bibliotheekcode die u hebt geïmplementeerd of die door derden is geïmplementeerd. Deze laatste worden meestal bibliotheekafhankelijkheid genoemd en worden meestal verpakt als JAR-bestanden.

Java is een dynamisch gebonden taal. Wanneer u een Java-toepassing met bibliotheekafhankelijkheden uitvoert, moet de JVM weten waar de afhankelijkheden zijn, zodat klassen naar wens kunnen worden geladen. In grote lijnen zijn er twee manieren om hiermee om te gaan:

  • De applicatie en zijn afhankelijkheden kunnen opnieuw worden verpakt in een enkel JAR-bestand dat alle vereiste klassen en bronnen bevat.

  • De JVM kan via het runtime classpath worden verteld waar de afhankelijke JAR-bestanden kunnen worden gevonden.

Voor een uitvoerbaar JAR-bestand wordt het runtime-classpath gespecificeerd door het manifestkenmerk "Class-Path". (Noot voor de redactie: dit moet worden beschreven in een afzonderlijk onderwerp bij de opdracht jar .) Anders moet het runtime classpath worden opgegeven met de optie -cp of met de omgevingsvariabele CLASSPATH .

Stel bijvoorbeeld dat we een Java-toepassing hebben in het bestand "myApp.jar" waarvan de toegangspuntklasse com.example.MyApp . Stel ook dat de toepassing afhankelijk is van JAR-bestanden van de bibliotheek "lib / library1.jar" en "lib / library2.jar". We kunnen de applicatie als volgt starten met de opdracht java op een opdrachtregel:

$ # 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

(In Windows gebruikt u ; plaats van : als scheidingsteken voor het klassenpad en stelt u de (lokale) variabele CLASSPATH met behulp van set plaats van export .)

Hoewel een Java-ontwikkelaar zich daar prettig bij zou voelen, is het niet "gebruiksvriendelijk". Het is dus gebruikelijk om een eenvoudig shellscript (of Windows-batchbestand) te schrijven om de details te verbergen die de gebruiker niet hoeft te weten. Als u bijvoorbeeld het volgende shellscript in een bestand met de naam "myApp" plaatst, het uitvoerbaar maakt en in een map op het opdrachtzoekpad plaatst:

#!/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

dan zou je het als volgt kunnen uitvoeren:

$ myApp arg1 arg2 ...

Alle argumenten op de opdrachtregel worden doorgegeven aan de Java-toepassing via de uitbreiding "$@" . (U kunt iets soortgelijks doen met een Windows-batchbestand, hoewel de syntaxis anders is.)

Spaties en andere speciale tekens in argumenten

Allereerst is het probleem van het omgaan met spaties in argumenten GEEN Java-probleem. Het is eerder een probleem dat moet worden opgelost door de opdrachtshell die u gebruikt wanneer u een Java-programma uitvoert.

Laten we als voorbeeld eens aannemen dat we het volgende eenvoudige programma hebben dat de grootte van een bestand afdrukt:

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());
        }
    }
}

Stel nu dat we de grootte van een bestand willen afdrukken waarvan de padnaam spaties bevat; bijv. /home/steve/Test File.txt . Als we de opdracht als volgt uitvoeren:

$ java PrintFileSizes /home/steve/Test File.txt

de shell weet niet dat /home/steve/Test File.txt eigenlijk één padnaam is. In plaats daarvan geeft het 2 afzonderlijke argumenten door aan de Java-toepassing, die zal proberen hun respectieve bestandsgrootten te vinden, en mislukken omdat bestanden met die paden (waarschijnlijk) niet bestaan.

Oplossingen met behulp van een POSIX-shell

POSIX-shells bevatten zowel sh als derivaten zoals bash en ksh . Als u een van deze shells gebruikt, kunt u het probleem oplossen door het argument te citeren .

$ java PrintFileSizes "/home/steve/Test File.txt"

De dubbele aanhalingstekens rond de padnaam vertellen de shell dat deze als een enkel argument moet worden doorgegeven. De aanhalingstekens worden verwijderd wanneer dit gebeurt. Er zijn een paar andere manieren om dit te doen:

$ java PrintFileSizes '/home/steve/Test File.txt'

Enkele (rechte) aanhalingstekens worden behandeld als dubbele aanhalingstekens, behalve dat ze ook verschillende uitbreidingen in het argument onderdrukken.

$ java PrintFileSizes /home/steve/Test\ File.txt

Een backslash ontsnapt aan de volgende ruimte en zorgt ervoor dat deze niet wordt geïnterpreteerd als argumentscheidingsteken.

Voor meer uitgebreide documentatie, inclusief beschrijvingen van hoe om te gaan met andere speciale karakters in argumenten, verwijzen wij u naar het citaatonderwerp in de Bash- documentatie.

Oplossing voor Windows

Het fundamentele probleem voor Windows is dat op OS-niveau de argumenten als één string ( bron ) aan een onderliggend proces worden doorgegeven. Dit betekent dat de uiteindelijke verantwoordelijkheid voor het parseren (of opnieuw parseren) van de opdrachtregel op elk programma of op de runtime-bibliotheken valt. Er is veel inconsistentie.

In het geval van Java, om een lang verhaal kort te maken:

  • U kunt dubbele aanhalingstekens om een argument in een java commando plaatsen, en daarmee kunt u argumenten met spaties doorgeven.

  • Blijkbaar ontleedt het java commando zelf de commandostring en krijgt het min of meer gelijk

  • Wanneer u dit echter probeert te combineren met het gebruik van SET en variabele substitutie in een batchbestand, wordt het erg ingewikkeld of dubbele aanhalingstekens worden verwijderd.

  • De cmd.exe shell heeft blijkbaar andere ontsnappingsmechanismen; bijv. dubbele aanhalingstekens en ^ escapes gebruiken.

Raadpleeg de documentatie over het batchbestand voor meer informatie.

Java-opties

Het java commando ondersteunt een breed scala aan opties:

  • Alle opties beginnen met een enkel koppelteken of minteken ( - ): de GNU / Linux-conventie van het gebruik van -- voor "lange" opties wordt niet ondersteund.

  • Opties moeten worden weergegeven vóór het argument <classname> of het argument -jar <jarfile> om te worden herkend. Alle argumenten erna worden behandeld als argumenten die worden doorgegeven aan de Java-app die wordt uitgevoerd.

  • Opties die niet beginnen met -X of -XX zijn standaardopties. U kunt op alle Java-implementaties 1 vertrouwen om elke standaardoptie te ondersteunen.

  • Opties die beginnen met -X zijn niet-standaardopties en kunnen worden teruggetrokken van de ene Java-versie naar de volgende.

  • Opties die beginnen met -XX zijn geavanceerde opties en kunnen ook worden ingetrokken.

Systeemeigenschappen instellen met -D

De -D<property>=<value> optie wordt gebruikt om een onroerend goed in het systeem in te stellen Properties object. Deze parameter kan worden herhaald om verschillende eigenschappen in te stellen.

Geheugen-, stapel- en afvalverzamelaaropties

De belangrijkste opties voor het regelen van de heap- en stapelgroottes zijn gedocumenteerd in De heap-, PermGen- en stapelgroottes instellen . (Noot voor de redactie: Garbage Collector-opties moeten in hetzelfde onderwerp worden beschreven.)

Beweringen in- en uitschakelen

De -ea en -da opties respectievelijk in- en uitschakelen Java assert controleren:

  • Alle beweringen worden standaard uitgeschakeld.
  • Met de optie -ea kunnen alle beweringen worden gecontroleerd
  • De -ea:<packagename>... maakt het mogelijk beweringen in een pakket en alle subpakketten te controleren .
  • De -ea:<classname>... maakt het mogelijk beweringen in een klasse te controleren.
  • De optie -da schakelt het controleren van alle beweringen uit
  • De -da:<packagename>... schakelt het controleren van beweringen in een pakket en alle subpakketten uit .
  • De -da:<classname>... schakelt het controleren van beweringen in een klasse uit.
  • Met de optie -esa kan alle systeemklassen worden gecontroleerd.
  • De optie -dsa schakelt het controleren uit voor alle systeemklassen.

De opties kunnen worden gecombineerd. Bijvoorbeeld.

$ # 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

Merk op dat het inschakelen van bewering controle het gedrag van een Java-programmering kan veranderen.

  • Het is aansprakelijk de toepassing in het algemeen langzamer maken.
  • Het kan ervoor zorgen dat specifieke methoden langer duren, waardoor de timing van threads in een toepassing met meerdere threads kan veranderen.
  • Het kan serendipitaire gebeurtenissen veroorzaken - vóór relaties die ervoor kunnen zorgen dat geheugenafwijkingen verdwijnen.
  • Een onjuist geïmplementeerd assert verklaring zou kunnen ongewenste neveneffecten hebben.

Het VM-type selecteren

Met de opties -client en -server kunt u kiezen tussen twee verschillende vormen van de HotSpot VM:

  • Het formulier "client" is afgestemd op gebruikerstoepassingen en biedt sneller opstarten.
  • De "server" -vorm is afgestemd voor langlopende applicaties. Het vastleggen van statistieken tijdens JVM "warming-up" duurt langer, waardoor de JIT-compiler beter kan werken aan het optimaliseren van de native code.

Standaard wordt de JVM indien mogelijk in 64bit-modus uitgevoerd, afhankelijk van de mogelijkheden van het platform. Met de opties -d32 en -d64 kunt u de modus expliciet selecteren.


1 - Raadpleeg de officiële handleiding voor het java commando. Soms wordt een standaardoptie beschreven als "onder voorbehoud".



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow