S-JIS[2003-07-06/2024-03-22]変更履歴
JavaアプリケーションはJavaソースを(C言語やC++等と同様に)コンパイルし、コンパイルして出来たファイルを実行するもの。
(実際にはJavaで作った全てのプログラムがコンパイル・実行するものだけれども、ここではJavaアプレットやサーブレットと区別する意味で「Javaアプリケーション」と呼んでいる)
javacコマンドでコンパイルし、javaコマンドで実行する。
実行は、クラス内のmainメソッド(基本的にはpublic static void main(String[] args)、あるいはString... args)から行われる。
JDK1.5から、main()が実行される前にメソッドpremain()を呼ぶこともやろうと思えば出来るようになった。[2007-11-12]
| |
>javacソースファイル名>javaクラス名
>javacパッケージ名\ソースファイル名>javaパッケージ名.クラス名
例えば「c:\java\sample1\pac\func\Start.java」というソースファイルが「packagepac.func;」という宣言をしている場合、コンパイルは
>cdc:\java\sample1\pac\func>javacStart.java
>cdc:\java\sample1>javacpac\func\Start.java
のどちらでも出来るが、実行はパッケージのルートディレクトリーに移動して
>cdc:\java\sample1>javapac/func/Start
>cdc:\java\sample1>javapac.func.Start
で行う。(実行する時には拡張子“.class”は不要。ファイル名を指定するのではなく、クラス名を指定する為)
他の場所で実行すると、下のようなエラーになる。
>cdc:\java\sample1\pac\func>javaStartException in thread "main"java.lang.NoClassDefFoundError:Start (wrong name:pac/func/Start) at java.lang.ClassLoader.defineClass0(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:486) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:111) at java.net.URLClassLoader.defineClass(URLClassLoader.java:248) at java.net.URLClassLoader.access$100(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:297) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286) at java.lang.ClassLoader.loadClass(ClassLoader.java:253) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
Start.classというクラスファイル自体は見つけたが、javaコマンドの引数には「Start」しか書かれていない為、JavaVMはデフォルトパッケージ(パッケージ無し)の「Start」というクラスを想定していた。
にも関わらず(Start.class内に保持されている)実際のクラスは「pac.func.Start」というパッケージ付きのクラスなので、一致していない。
というエラー。[2008-12-20]
また、クラスパスを指定することで、カレントディレクトリーを移動する必要はなくなる。[2006-05-14]
>java-cpc:\java\sample1pac.func.Start
jarファイル化した場合は、クラスパスにそのjarファイルを指定する。
(jarファイルを作るには、build.xmlを作っておくのが便利)[2006-06-17]
>java-cpc:\java\sample1.jarpac.func.Start
なお、(Windows版には)javaコマンドに似たjavawコマンドというものがある。[2007-06-30]
これは、実行時にコンソール(ウィンドウ)を開かない。なので、javawを使って実行した場合はSystem.out.println()で出力したメッセージはどこにも出ない。
Java11から、1ファイルのみで構成された(publicクラスしか無い)ソースコード(Single-File Source-Code Program)は(コンパイルせずに)直接javaコマンドで実行できるようになった。[2018-10-01]
public class Hello {public static void main(String... args) {System.out.println("hello");}}> java Hello.java
※ソースファイル内に他クラスが含まれていて、それを呼んでいると駄目。(通常のソースコードでは、publicでないクラスを同じソースファイルに含めることが出来る)
Java22から、複数ファイルのソースコード(Multi-File Source-Code Programs)の場合でもjavaコマンドで実行できるようになった。[2024-03-22]
ソースファイル内に「他のソースファイルにあるクラス」が含まれている場合、それも一緒にコンパイルされる。
public class MultiExample { public static void main(String... args) { var sub = newMultiSub(); sub.execute(); }}public classMultiSub { public void execute() { System.out.println("MultiSub.execute"); }}> cd multi> java MultiExample.java
パッケージ宣言がある場合、ソースファイルから直接実行するには、ソースファイルもその構成に沿ったディレクトリーに配置されている必要がある。
(javacでコンパイルする場合は、ソースファイルは必ずしもパッケージ宣言に沿ったディレクトリーに置かれている必要は無いのだが、javaコマンドで直接実行する場合は、パッケージ宣言とソースファイルのディレクトリー構成が一致していなければならない)
package com.example;import com.example.sub.*;public class MultiExample { public static void main(String... args) { var sub = newMultiSub(); sub.execute(); }}package com.example.sub;public classMultiSub { public void execute() { System.out.println("MultiSub.execute"); }}> cd multi2> java com/example/MultiExample.java
なお、実行開始するjavaファイルと同じ場所にExampleSub.javaがあると、import文よりそのファイルが優先される。
このとき、そのファイルのパッケージ宣言がディレクトリー構成と一致していないと、コンパイルエラーになる。
大規模なアプリケーションになってくると、クラスを複数のjarファイルから取ってきて使用したりする。[2009-02-20]
その場合、全てのjarファイルがクラスパスに入っている必要がある。
起動オプションでは、区切り文字(Windowsではセミコロン「;」、UNIXではコロン「:」)で区切ることにより、複数のjarファイル(やディレクトリー)を指定することが出来る。
>javac-classpath C:\sample\lib\abc.jar;C:\sample\lib\def.jar 〜>java-classpath C:\sample\lib\abc.jar;C:\sample\lib\def.jar 〜
>javac-classpath /sample/lib/abc.jar:/sample/lib/def.jar 〜>java-classpath /sample/lib/abc.jar:/sample/lib/def.jar 〜
いちいちパスを列挙するのは大変なので、DOSのfor文・UNIXのfor文等を使って(バッチ(シェル)化して)jarファイル名を集めてくるようにすることも多い。
| Windows | UNIX |
|---|---|
@echo offgoto main:addset CP=%CP%;%1exit/b:mainset CP=for %%i in (C:\sample1\lib\*.jar) docall:add %%ifor %%i in (C:\sample2\lib\*.jar) docall:add %%iecho %CP%java-cp %CP% 〜 | #!/bin/bashadd(){CP=$CP:$1}CP=for i in/sample1/lib/*.jar; doadd $i; donefor i in/sample2/lib/*.jar; doadd $i; doneecho $CPjava-cp $CP 〜※パスにスペースが含まれていないのが前提 |
for文をまとめることも出来る。for %%i in (C:\sample1\lib\*.jarC:\sample2\lib\*.jar) docall:add %%i | for文をまとめることも出来る。for i in\/sample1/lib/*.jar\/sample2/lib/*.jardoadd $i; done※doの直前の行の末尾には行継続文字「\」を付けてはいけない |
JDK1.6からはクラスパスの指定にワイルドカードを使えるようになった為、「特定ディレクトリーに入っている全てのjarファイル」に関しては、自分で(バッチやシェルで)用意する必要は無くなった。[2010-01-09]
javacコマンドでもjavaコマンドでも使用可能。
| 例 | 備考 | 参考 | |
|---|---|---|---|
| Windows | javac-cpC:\sample1\lib\*;C:\sample2\lib\* ファイル名 java-cp.;C:\sample1\lib\*;C:\sample2\lib\* クラス名 | ||
| UNIX | javac-cp"/sample1/lib/*:/sample2/lib/*" ファイル名 java-cp".:/sample1/lib/*:/sample2/lib/*" クラス名 | UNIXで「*」を使う際には、念の為にクォーテーションで囲んでおく方がいいかな。 (「*」に何らかの文字がくっついているとクォーテーションは不要なようだが) |
クラスパスワイルドカード「*」はjavacやjavaコマンドが解釈し、そのディレクトリーの拡張子「jar」のファイルの具体的なファイル名に展開される。
例えば「sample/a.jar」「sample/b.jar」「sample/c.zip」が在る場合、「sample/*」は、「sample/a.jar;sample/b.jar」(Windowsの場合)となる。
システムプロパティーjava.class.pathで取得されるのは展開された状態になる。
部分マッチするような指定は出来ない。すなわち「*.jar」や「*.zip」、「a*.jar」「a*」といった指定は展開/検索対象にならない。
「class C1」があり、「class C2 extends C1」で「class C3 extends C2」のとき、C3をコンパイルする為には、C2の他にC1もクラスパスに入っている必要がある。[2009-02-02]
C3.javaのコンパイルの際にC1.classがクラスパスに入っていないと、以下のようなコンパイルエラーになる。
classes3> javac-cp ../classes2 C3.javaC3.java:2: C1 にアクセスできません。C1 のクラスファイルが見つかりませんpublic class C3 extends C2 { ^エラー 1 個ちなみに、Eclipse3では以下のようなエラーになる。
(C3に対して)型 C3 の階層は不整合です
(C2に対して)型 C1 を解決できません。 必要な .class ファイルから間接的に参照されています
C1とC2のクラスパスを両方指定してやるとコンパイルできる。
classes3> javac-cp ..\classes2;..\classes1 C3.java
実行時に(C3と)C2のクラスパスだけ入れていてC1のクラスパスが入っていないと、以下のような例外が発生する。
classes3> java-cp .;..\classes2 C3Exception in thread "main"java.lang.NoClassDefFoundError: C1 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source)〜
C3のソース上には(C2が依存している)C1は出てこないので、厄介なエラーだなぁ。
javacコマンドで拡張子javaのファイルをコンパイルすると、拡張子classのファイル(バイトコード)が生成される。
ドキュメントには書かれていないが、javacコマンドは、コンパイルが成功すると0、失敗すると1を返すようだ。(Windows→%ERRORLEVEL%、UNIX→$?)
| オプション | 説明 | 更新日 |
|---|---|---|
| -encoding MS932 | ソース内の文字列がShiftJISであることを明示する(MS932はSJISの一種で、もっと厳密な体系)。 普通は自動的に判別してくれるので、指定不要。厳密に言えば、ソース内の文字がUNICODE以外のときは明示的に指定しなきゃいけないらしいけど…。 | |
| -d ディレクトリ | コンパイルした結果(classファイル)を格納するディレクトリを指定する。 ここで指定したディレクトリの下に、package文で指定したパッケージの構成と同じサブディレクトリが作られる。 逆に、ソースファイル自身はパッケージと同じディレクトリ構成に居る必要はない。実際は同じ階層を構築することが多いが。 この指定が無いと、classファイルはjavaファイルと同じ場所に作られる。 | |
-classpath クラスパス;… | クラスパス(CLASSPATH)を指定する。 コンパイル時に使用(参照)するクラスの在るディレクトリーやjarファイルを、パス区切り(Windowsの場合はセミコロン「 ;」、UNIXならコロン「:」)で複数指定できる。→Eclipseのビルドパス JDK1.6では、クラスパスワイルドカード「*」が使えるようになった。 | 2010-01-09 |
-cp クラスパス;… | -classpathと同じだが、JDK1.5以降。 | 2009-02-02 |
| -source バージョン | コンパイルするソースが準拠しているJDKのバージョン(使用する文法のバージョン)を指定する。 これにより使える文法が変わってくる。例えばアサーションを使う時には1.4以上を指定する必要があるし、enum等のJDK1.5の新機能を使う時は1.5以上(1.5または5)を指定する必要がある。 JDK1.6準拠なら1.6(または6)を指定する。(Eclipse3.2では5.0/6.0という表記。Eclipse3.4では1.5/1.6) →省略時のバージョン | 2010-01-09 |
| -target バージョン | コンパイルして出来たclassが実行できるJavaVMのJREのバージョンを指定する。値は-sourceと同様。 →省略時のバージョン | 2007-05-15 |
| --release バージョン | Java9以降。-sourceおよび-targetを同時に指定するのと同じ。 ただし、バージョンの指定方法は6, 7, 8等。(1.6や1.7という書き方は出来ない) | 2017-09-22 |
| -parameters | メソッド(やコンストラクター)の引数名をclassファイルに保持する。JDK1.8以降。 →Paramerters#getName() | 2014-03-20 |
| -g | デバッグ情報(ローカル変数の名前とか)をclassファイルに含める。 | 2020-03-21 |
| -Jオプション | javacが使用するjavaコマンド(javacと同バージョンのjava)へのオプションを指定する。 (例えば「javac -J-version」は、「java -version」の意味。複数のバージョンのJDKがインストールされている場合、「javac -J-version」と「java -version」では、異なる実体(バージョン)のjavaコマンドが実行される可能性が有る) | 2007-05-15 |
| どうも、javacも内部ではjavaコマンドを使ってコンパイル用クラスを実行しているようだ。 例えば「 javac Sample.java」→「java com.sun.tools.javac.Main Sample.java」といった感じ。「 javac -J-version」を実行すると、実際は「java -version com.sun.tools.javac.Main」となり、-versionではその他の引数は無視されるので正しく実行されるようだ。試しに「 javac-J-cp-JC:\temp-JSample zzz」を実行してみると、「java -cp C:\temp Sample com.cun.tools.javac.Main zzz」となって実行されているっぽい。(この例では、Sampleクラスが実行され、その第1引数が「com.sun.tools.javac.Main」になる!) | 2009-11-14 | |
| -version | JDK1.6以降。javacのバージョンを表示する。 Java8までは標準エラーに出力されていたが、Java9で標準出力に出力されるようになった。 | 2017-09-22 |
| --version | Java9以降。-versionと同じ。 | 2017-09-22 |
| -verbose | 使用するクラス等の詳細情報を表示する。 | 2010-01-10 |
| -Xlint | 推奨の警告を有効にする。細かいエラーチェックを行い、警告を出してくれる。→使用例 →ソース上で警告を抑止する方法 | 2007-06-12 |
→Antのjavac
→Sunのjavac - Javaプログラミング言語コンパイラ
→実行時コンパイルクラス(JavaCompiler)
-sourceや-targetを省略した場合は、コンパイラー(javac)のバージョンに応じたバージョンになる。[2008-07-16]
(Java9で、-sourceと-targetを同時に指定できる--releaseが追加になった。[2017-09-22])
→-sourceと-targetの組み合わせの例
-sourceに1.4を指定して-targetに1.5を指定した場合、使用できる文法はJDK1.4までの文法だが、出来上がるクラスファイルはJRE1.5向けになる。
すなわち、Stringの+演算子はStringBuilderに置き換えられる。
-sourceに1.4を指定して-targetも1.4だった場合、(JDK1.5以降のjavacであっても)Stringの+演算子はStringBufferに置き換えられる。
ただし、コンパイル時に指定している標準ライブラリー(JDK)が1.5のものだった場合、JDK1.5で追加されたクラスやメソッド(System.out.printf()やjava.util.Queue)は使用できる。
Sample14.java:
importjava.util.Queue;import java.util.LinkedList;public class Sample14 {public static void main(String[] args) {Queue q = newLinkedList();q.add("abc");q.add("def");System.out.printf("%s, %s%n", new Object[]{"abc", "def"});//可変長引数は配列形式で呼び出せる}}可変長引数「printf("%s, %s%n", "abc", "def")」はJDK1.5以降でないと使えない(「-source 1.4」では使えない)が、
配列形式の呼び出し「printf("%s, %s%n", new Object[]{"abc", "def"})」であればJDK1.4でも使える。
コンパイル:
>which javacjavac=C:\Program Files\Java\jdk1.6.0\bin\javac.exe…使うのはJDK1.6のコンパイラー>javac-source 1.4-target 1.4 Sample14.java…JRE1.4用にコンパイル>javap -v Sample14Compiled from "Sample14.java"public class Sample14 extends java.lang.ObjectSourceFile: "Sample14.java"minor version:0major version:48…クラスファイルのバージョンはJRE1.4〜
実行:
>java-version:1.4 Sample14…JRE1.4のjavaコマンドで実行Exception in thread "main"java.lang.NoClassDefFoundError:java/util/Queue>java-version:1.5 Sample14…JRE1.5のjavaコマンドで実行abc, def
JDK1.4の標準ライブラリーにはjava.util.Queueは存在しないので、実行時にNoClassDefFoundErrorが発生する。
(コンパイル時にはJDK1.6のコンパイラーを使用しているので、JDK1.6のライブラリーが使われている(すなわちjava.util.Queueが存在しているのでエラーにならない))
しかしJDK1.5のライブラリーを使ってわざわざJDK1.4向けにコンパイルしても、JRE1.5以降のjavaコマンドでしか実行できないので、意味無いよなー(苦笑)
JDK1.4のjavacに「-classpath "C:\Program Files\Java\jdk1.5.0_09\jre\lib\rt.jar"」を指定しても、バージョン違いのエラー「クラスファイルのバージョン 49.0 は不正です。48.0 であるべきです。」になってコンパイルできないし。
「java -help」や「java -X」でヘルプが表示される。
ドキュメントには書かれていないが、javaコマンドは、実行が成功すると0(System.exit()で値を設定していればその値)、失敗すると(例外が発生すると)1を返すようだ。(Windows→%ERRORLEVEL%、UNIX→$?)
| オプション | 説明 | 更新日 |
|---|---|---|
-version | 実行されるJavaVMのバージョン(1.4とか1.6とか)を標準エラーに表示して終了する。→例 | 2007-05-15 |
--version | 実行されるJavaVMのバージョン(1.4とか1.6とか)を標準出力に表示して終了する。(Java9以降) | 2017-09-22 |
-version:バージョン | 実行するJavaVMのバージョンを指定する。Java9で廃止になった。 | 2017-09-22 |
-showversion | 実行されるJavaVMのバージョン(1.4とか1.6とか)を標準エラーに表示して続行する。 | 2010-01-09 |
--show-version | 実行されるJavaVMのバージョン(1.4とか1.6とか)を標準出力に表示して続行する。(Java9以降) | 2017-09-22 |
-cp クラスパス;…-classpath クラスパス;… クラスパス;… | クラスパス(CLASSPATH)を指定する。 実行時に使用するクラスの在る、ディレクトリーやjarファイルを パス区切り(Windowsの場合はセミコロン「 ;」、UNIXならコロン「:」)で複数指定できる。JDK1.6では、クラスパスワイルドカード「*」が使えるようになった。 ここで指定されたクラスパスはシステムプロパティーjava.class.pathで取得できる。 Java9から「--class-path」でも指定できるようになった。 | 2017-09-22 |
-jar実行可能jarファイル | 実行可能jarファイルを実行する。 | 2009-01-15 |
-client | クライアントのVMで実行(デフォルト) (Java8からは-serverがデフォルトになった) | 2020-11-16 |
-server | サーバーのVMで実行(メモリーを大量に使う代わりに速くなる) Java9で廃止になった。 -serverオプションの意味→阪田 浩一さんのJavaコードが速く実行される秘密 - JITコンパイラ入門(JJUG CCC 2020 Fall講演資料) | 2020-11-16 |
-hotspot | マシンにネイティブなコードに変換して実行(クライアントとして) …でもJRE1.4以降では無意味(-clientの指定と同じ)らしい。 | 2008-08-10 |
-ea | アサーションを有効にする。「-ea」の代わりに「-enableassetions」でも可。 | |
-Dシステムプロパティー=値 | システムプロパティーを設定する。設定したプロパティーはSystem#getProprty()で取得できる。 | 2008-07-30 |
-Djava.system.class.loader=クラス | クラスローダーを指定する。 | 2007-11-12 |
-javaagent:jarファイル=値 | 事前実行クラス(premain()のあるクラス)を指定する。(JDK1.5以降) | 2007-11-12 |
-agentlib | →デバッグ実行の指定(JDK1.5以降) | 2009-01-15 |
-p モジュールパス;…--module-path モジュールパス;… | モジュールのディレクトリーを指定する。(Java9以降) | 2017-09-22 |
--upgrade-module-path モジュールパス;… | 2017-09-22 | |
--add-modules モジュール名,… | 2017-09-22 | |
--list-modules | 参照可能なモジュールの一覧を表示する。(Java9以降) | 2017-09-22 |
-d モジュール名--describe-module モジュール名 | モジュールの説明を表示する。(Java9以降) | 2017-09-22 |
--dry-run | JavaVMを作成してメインクラスをロードするが、実行はしない。検証用。(Java9以降) | 2017-09-22 |
--validate-modules | モジュール(の競合やエラー)を検証する。(Java9以降) | 2017-09-22 |
-XX:+ShowCodeDetailsInExceptionMessages | NullPointerExceptionの詳細メッセージが出るようになる。(Java14) (Java15ではこれを付けなくても詳細メッセージが表示される。) | 2020-09-29 |
| オプション | 説明 | 例 |
|---|---|---|
-verbose:class | クラスがロードされた時に、そのことを出力する。[2010-01-09] | |
-verbose:gc | GCが実行された時、その状態を標準出力に出力する。 | |
-Xms<size> | 初期ヒープサイズの指定。空きメモリーの80%くらいがよい。 | -Xms256m |
-Xmx<size> | 最大ヒープサイズの指定。初期ヒープサイズと同じがよい。 | -Xmx256m |
-XX:NewSize=<size> | GC新規割当サイズ。ヒープサイズの1/4〜1/3がよい。 | |
-XX:MaxNewSize=<size> | GC新規割当時の最大サイズ。NewSizeと同じがよい。 | |
-XX:SurvivorRatio=<値> | GC新規割当領域比率。2(推奨)〜8。 | |
-Xincgc | GCの実行時間を10ms以内に抑えるオプション。サーバー向けではない | |
-Xdebug | デバッグ実行の指定(JDK1.4)。JDK1.5で-agentlibに変わった。[2009-01-15] |
1つのマシンに複数バージョンのJREがインストールされている場合、実行したいバージョンをjavaコマンドの-versionオプションで指定することが出来る。[2007-06-28]
※この機能はJava9で廃止になった。[2017-09-22]
> java -version:1.6 Test> java -version:1.6.0 Test> java -version:1.6.0_01 Test> java -version:1.6.0_1 Test
エラーとなる例:
> java -version:1.4.2 TestUnable to locate JRE meeting specification "1.4.2"…1.4.0はOKなのに、1.4.2は存在していてもNG 存在しているバージョンを完全に指定(1.4.2_13)すればOK
JDKのjavapというコマンドを使用することで、コンパイルされたclassファイルの情報を見ることが出来る。[2007-05-26]
→classファイルのバージョン
>javap 〔オプション〕 クラス名
クラス名の指定の仕方は、javaコマンドで実行するクラスを指定する方法と同様。
つまりクラスファイルの置かれているルートディレクトリーからパッケージ名付き(FQCN)でクラス名を指定する。
>cd C:\temp\classes>javap jp.hishidama.sample.Sample
しかしjavaコマンドと異なり、そのクラスファイルがある場所で実行することも出来る。[2010-01-15]
(あくまでもファイル名指定ではなくクラス名指定なので、拡張子「.class」は付けない)
>cd C:\temp\classes\jp\hishidama\sample>javap Sample
あとは、クラスパスを指定することも出来る。[2010-01-15]
>javap-classpath C:\tmep\classes jp.hishidama.sample.Sample
標準のクラス(java.lang.String等)は、クラスパス等を特に指定しなくても、javapが実行できる場所ならどこでも参照できる。[2007-09-26]
>javap java.lang.String
| オプション | 説明 |
|---|---|
| -help | javapのオプション一覧を表示する。 |
| -public -protected -package -private | それぞれの属性(ものによっては下位レベルも含む)のメンバーだけ表示する。 |
| -c | 逆アセンブル。インストラクションコードを表示する。 |
| -s | メンバーのシグニチャーを表示する。JNIでメソッドやフィールドを扱いたいときに便利。 |
| -verbose -v | 詳細な情報表示。実行可能バージョンやコンスタント(定数)プール等も表示される。 |
| -classpath | クラスパスの指定。(-cpオプションは無い)[2010-01-15] |
クラス名(パッケージ名)や、どんなメンバー(メソッド・フィールド)が存在しているかを知るだけなら オプションは何も付ける必要はない。
逆コンパイルしてJavaソースの形で見たいならば、jadが便利。
→Sunのjavap - Javaクラスファイル逆アセンブラ
→package-info.classのアノテーションを確認する例
jpsは、JDK1.5から使えるようになったらしい、実行中のJavaアプリケーションのプロセスIDを表示するツール。[2009-12-12]
Windowsのtasklist、UNIXのpsのJavaプログラム専用バージョンといったところか。
tasklistで「tasklist|findstr java」とやると、普通にjava.exeやjavaw.exeで実行しているものは出てくるが、eclipse.exeやrmiregistry.exeで実行したものは出てこないので、jpsの方が便利。
| オプション | 説明 | 実行例 |
|---|---|---|
| -help | ヘルプ(オプション一覧)が表示される。 | > jps -helpusage: jps [-help] jps [-q] [-mlvV] [<hostid>]Definitions: <hostid>: <hostname>[:<port>] |
| なし | プロセスIDと実行クラス名が表示される。 (右の例の2720はEclipse3.4) | > jps2588 Jps2664 RegistryImpl2720 |
| -l | 実行クラス名が完全修飾名(FQCN)で表示される。 | > jps -l1780 sun.tools.jps.Jps2664 sun.rmi.registry.RegistryImpl2720 |
| -q | プロセスIDのみ表示される。 (実行クラス名が表示されない) | > jps -q318026642720 |
| -v | 詳細情報(実行時オプション)が表示される。 | > jps -v2664 RegistryImpl -Denv.class.path=.;C:\Program Files\Java\jdk1.6.0_13\lib\tools.jar;〜 -Dapplication.home=C:\Program Files\Java\jdk1.6.0_13 -Xms8m2652 Jps -Denv.class.path=.;C:\Program Files\Java\jdk1.6.0_13\lib\tools.jar;〜 -Dapplication.home=C:\Program Files\Java\jdk1.6.0_13 -Xms8m2720 -Dosgi.requiredJavaVersion=1.5 -Xms256m -Xmx256m -Declipse.cvs.anon=true -javaagent:dropins/MergeDoc/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar -XX:MaxPermSize=256m |
| -lv | -lと-vの組み合わせ。 |
jpsの仕組みは、各Javaアプリケーションが作成した情報ファイルをただ集めてきて表示しているだけらしい。[2010-03-25]
したがって、Javaアプリケーション実行時のTMPとjps実行時のTMPが異なると、jpsはプロセス情報を収集することが出来ない。(プロセスIDが表示されない)
jstackは、スレッドダンプを表示するツール。[2009-12-12]
UNIXではJDK1.5から、WindowsではJDK1.6から提供されるようになったらしい。
Windowsの場合、Javaプログラムを実行しているコンソールで「Ctrl+Break(またはCtrl+Pause)」を押すと、そのプログラムのスレッドダンプが出力される。
UNIXの場合はJavaプログラムを実行しているコンソールで「Ctrl+\」。または「SIGQUITを送る」、つまり「kill -QUITプロセスID」を実行するとスレッドダンプが出力される。
が、jstackは、それを行う専用のツール。
> jstackプロセスID
プロセスIDはjps辺りで調べる。
なお、「jstack -h」または「jstack -help」でヘルプが表示される。
jconsoleは、実行中のJavaプログラムの状態を表示するツール。[2009-12-12]
このツールはGUI、すなわちウィンドウアプリ。(コンソールという名前のくせに…)
実行時オプションからCPUの使用時間、スタックの状態など、色々な情報が見られる。
JDK1.5で導入されたが、JDK1.6でさらに改善されたらしい。
> jconsole> jconsoleプロセスID
オプション無しでjconsoleを起動すると、最初に実行中のJavaアプリの一覧が表示され、そこから監視したい対象に接続することが出来る。