コマンドラインでのJavaの操作

現在、誰もコンソールでプログラムを作成していません。 お気に入りのIDEを使用して、開発者は他の人のコンピューターに不快感を感じます。

AntとMavenの作業を理解することに決めたので、コンソールにそれらがないとアプリケーションをビルドできないことがわかりました。

この記事では、インターネット上の各チームの支援を求めないように、デモアプリケーションの設計のすべての段階に適合するようにしました。



シンプルから...



通常、各プログラムは個別のディレクトリに含まれています。 このディレクトリに少なくとも2つのフォルダー、srcとbinを作成するという規則に従います。 最初のコードにはソースコードが含まれ、2番目のコードにはコンパイル結果が含まれます。 これらのフォルダには、パッケージ固有のディレクトリ構造が含まれます。



単一ファイル



追加のフォルダなしで実行できます。

HelloWorld.javaファイル自体を取得します。
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }
      
      





このファイルがあるディレクトリに移動して、コマンドを実行します。

 javac HelloWorld.java
      
      



HelloWorld.classファイルがこのフォルダーに表示されます。 したがって、プログラムはコンパイルされます。 実行するには

 java -classpath . HelloWorld
      
      





ソースからバイナリファイルを分離する



ここで、ディレクトリを使用して同じことを行います。 HelloWorldディレクトリを作成し、その中にsrcとbinの2つのフォルダーを作成します。

コンパイル中

 javac -d bin src/HelloWorld.java
      
      



ここでは、バイナリファイルは別のbinフォルダーに保存され、ソースと混同しないことを示しました。



打ち上げ

 java -classpath ./bin HelloWorld
      
      





パッケージを使用します



そして、突然、プログラムは単なるHelloWorldでなくなります。 パッケージには明確で一意の名前を付けるのが最適です。 これにより、このプログラムは名前の競合なしに別のプロジェクトに追加されます。 いくつかの記事を読んだ後、パッケージ名にドメイン名が必要であると考えるかもしれません。 そうではありません。 ドメインは、一意性を実現する便利な方法です。 ドメインが存在しない場合は、サイトのアカウント(ru.habrahabr.myloginなど)を使用します。 ユニークです。 パッケージ名は小文字でなければならないことに注意してください。 また、特殊文字の使用は避けてください。 プラットフォームとファイルシステムが異なるために問題が発生します。



クラスをcom.qwertovsky.helloworldというパッケージに入れます。 これを行うには、ファイルの先頭に行を追加します

 package com.qwertovsky.helloworld;
      
      



srcディレクトリで、ファイルパスがsrc / com / qwertovsky / helloworld / HelloWorld.javaのようになるように追加のディレクトリを作成します。

コンパイル中

 javac -d bin src/com/qwertovsky/helloworld/HelloWorld.java
      
      



ディレクトリ構造は、srcのようにbinディレクトリに自動的に作成されます。

  HelloWorld '---bin ' '---com ' '---qwertovsky ' '---helloworld ' '---HelloWorld.class '---src '---com '---qwertovsky '---helloworld '---HelloWorld.java
      
      





打ち上げ

 java -classpath ./bin com.qwertovsky.helloworld.HelloWorld
      
      





プログラムに複数のファイルがある場合



プログラムを変更します。



HelloWorld.java
 package com.qwertovsky.helloworld; public class HelloWorld { public static void main(String[] args) { int a=2; int b=3; Calculator calc=new Calculator(); System.out.println("Hello World!"); System.out.println(a+"+"+b+"="+calc.sum(a,b)); } }
      
      





Calculator.java
 package com.qwertovsky.helloworld; import com.qwertovsky.helloworld.operation.Adder; public class Calculator { public int sum(int... a) { Adder adder=new Adder(); for(int i:a) { adder.add(i); } return adder.getSum(); } }
      
      





Adder.java
 package com.qwertovsky.helloworld.operation; public class Adder { private int sum; public Adder() { sum=0; } public Adder(int a) { this.sum=a; } public void add(int b) { sum+=b; } public int getSum() { return sum; } }
      
      





コンパイル中

 javac -d bin src/com/qwertovsky/helloworld/HelloWorld.java src\com\qwertovsky\helloworld\HelloWorld.java:9: cannot find symbol symbol : class Calculator location: class com.qwertovsky.helloworld.HelloWorld Calculator calc=new Calculator(); ^ src\com\qwertovsky\helloworld\HelloWorld.java:9: cannot find symbol symbol : class Calculator location: class com.qwertovsky.helloworld.HelloWorld Calculator calc=new Calculator(); ^ 2 errors
      
      





コンパイルには、使用するクラス(Calculatorクラス)のソースコードを含むファイルが必要であるため、エラーが発生しました。 -sourcepathスイッチを使用して、ファイルのあるディレクトリをコンパイラに示す必要があります。

コンパイル中

 javac -sourcepath ./src -d bin src/com/qwertovsky/helloworld/HelloWorld.java
      
      





打ち上げ

 java -classpath ./bin com.qwertovsky.helloworld.HelloWorld Hello Word 2+3=5
      
      





結果が驚くべき場合



デバッガーを実行することが可能です。 これにはjdbがあります。

最初に、-gスイッチを使用してコンパイルし、デバッガーが情報を取得できるようにします。

 javac -g -sourcepath ./src -d bin src/com/qwertovsky/helloworld/HelloWorld.java
      
      





デバッガーを実行する

 jdb -classpath bin -sourcepath src com.qwertovsky.helloworld.HelloWorld Initializing jdb ... >
      
      





デバッガーは内部ターミナルを起動してコマンドを入力します。 後者のヘルプは、helpコマンドを使用して表示できます。

Calculatorクラスの9行目にブレークポイントを指定します

 > stop at com.qwertovsky.helloworld.Calculator:9 Deferring breakpoint com.qwertovsky.helloworld.Calculator:9. It will be set after the class is loaded.
      
      





実行のために実行します。

 > run run com.qwertovsky.helloworld.HelloWorld Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable > VM Started: Set deferred breakpoint com.qwertovsky.helloworld.Calculator:9 Hello World! Breakpoint hit: "thread=main", com.qwertovsky.helloworld.Calculator.sum(), line=9 bci=0 9 Adder adder=new Adder();
      
      





自分の方向を決めるために、カーソルが現在置かれているソースコードを表示できます。

 main[1] list 5 public class Calculator 6 { 7 public int sum(int... a) 8 { 9 => Adder adder=new Adder(); 10 for(int i:a) 11 { 12 adder.add(i); 13 } 14 return adder.getSum();
      
      





変数aが何であるかを学びます。

 main[1] print a a = instance of int[2] (id=340) main[1] dump a a = { 2, 3 } main[1] stop at com.qwertovsky.helloworld.operation.Adder:19 Deferring breakpoint com.qwertovsky.helloworld.operation.Adder:19. It will be set after the class is loaded.
      
      





実行を継続します。

 main[1] cont > Set deferred breakpoint com.qwertovsky.helloworld.operation.Adder:19 Breakpoint hit: "thread=main", com.qwertovsky.helloworld.operation.Adder.add(), line=19 bci=0 19 sum+=b; main[1] list 15 } 16 17 public void add(int b) 18 { 19 => sum+=b; 20 } 21 22 public int getSum() 23 { 24 return sum; main[1] print sum sum = 0 main[1] print b b = 2
      
      





現在の行のコードを実行して、合計が2になり始めたことを確認しましょう。

 main[1] step > Step completed: "thread=main", com.qwertovsky.helloworld.operation.Adder.add(), line=20 bci=10 20 } main[1] print sum sum = 2
      
      





Adderクラスから、それを呼び出したCalculatorクラスに上がります。

 main[1] step up > Step completed: "thread=main", com.qwertovsky.helloworld.Calculator.sum(), line=10 bci=36 10 for(int i:a)
      
      





ブレークポイントを削除する

 main[1] clear com.qwertovsky.helloworld.operation.Adder:19 Removed: breakpoint com.qwertovsky.helloworld.operation.Adder:19 main[1] step > Step completed: "thread=main", com.qwertovsky.helloworld.Calculator.sum(), line=12 bci=30 12 adder.add(i);
      
      





次のコマンドを使用して、メソッドの呼び出しを回避できます。

 main[1] next > Step completed: "thread=main", com.qwertovsky.helloworld.Calculator.sum(), line=10 bci=36 10 for(int i:a) main[1] next > Step completed: "thread=main", com.qwertovsky.helloworld.Calculator.sum(), line=14 bci=42 14 return adder.getSum();
      
      





式の値を確認し、実行を完了します。

 main[1] eval adder.getSum() adder.getSum() = 5 main[1] cont > 2+3=5 The application exited
      
      





テストするのは良いことです



JUnitを使用します。

 package com.qwertovsky.helloworld; import static org.junit.Assert.*; import java.util.Arrays; import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized.Parameters; @RunWith(value=org.junit.runners.Parameterized.class) public class TestCalculator { int expected; int[] arg; @Parameters public static Collection<int[][]> parameters() { return Arrays.asList(new int[][][]{ {{4}, {2, 2}} ,{{-1},{4, -5}} ,{{0},{0,0,0}} ,{{0},{}} }); } public TestCalculator(int[] expected, int[] arg) { this.expected=expected[0]; this.arg=arg; } @Test public void testSum() { Calculator c=new Calculator(); assertEquals(expected,c.sum(arg)); } }
      
      





コンパイル中

 mkdir test_bin javac -classpath lib/path/junit-4.8.2.jar -sourcepath ./src -d test_bin test/com/qwertovsky/helloworld/TestCalculator.java
      
      





始めます。 Windowsのクラスパス内のいくつかのパスの区切り文字として、Linuxでは「;」、「:」を使用します。 Cygwinコンソールでは、両方のセパレーターが機能しません。 おそらく「;」で動作するはずですが、コマンド区切り文字として認識されます。

 java -classpath lib/path/junit-4.8.2.jar:./test_bin org.junit.runner.JUnitCore com.qwertovsky.helloworld.TestCalculator JUnit version 4.8.2 .... Time: 0,031 OK (4 tests)
      
      





ライブラリを作成する



Calculatorクラスは有用であることが証明されており、多くのプロジェクトで使用できます。 Calculatorクラスに関するすべてを別のプロジェクトに転送します。

  HelloWorld '---bin '---src '---com '---qwertovsky '---helloworld '---HelloWorld.java alculator '---bin '---src ' '---com ' '---qwertovsky ' '---calculator ' '---Calculator.java ' '---operation ' '---Adder.java '---test '---com '---qwertovsky '---calculator '---TestCalculator.java
      
      





また、ソースコードのパッケージ名を変更します。 HelloWorld.javaでは、行を追加する必要があります

 import com.qwertovsky.calculator.Calculator;
      
      





コンパイルします。

 cd Calculator javac -sourcepath src -d bin src/com/qwertovsky/calculator/Calculator.java
      
      





jarアーカイブの作成

 jar cvf calculator.jar -C bin . added manifest adding: com/(in = 0) (out= 0)(stored 0%) adding: com/qwertovsky/(in = 0) (out= 0)(stored 0%) adding: com/qwertovsky/calculator/(in = 0) (out= 0)(stored 0%) adding: com/qwertovsky/calculator/Calculator.class(in = 497) (out= 373)(deflated 24%) adding: com/qwertovsky/calculator/operation/(in = 0) (out= 0)(stored 0%) adding: com/qwertovsky/calculator/operation/Adder.class(in = 441) (out= 299)(deflated 32%)
      
      





-Cスイッチを使用して、binディレクトリでプログラムを起動しました。



あなたは図書館が何を持っているかを知る必要があります



zip unpackerを使用してアーカイブを解凍し、ライブラリ内のクラスを確認できます。

クラスに関する情報は、javap逆アセンブラを使用して取得できます。

 javap -c -classpath calculator.jar com.qwertovsky.calculator.Calculator Compiled from "Calculator.java" public class com.qwertovsky.calculator.Calculator extends java.lang.Object{ public com.qwertovsky.calculator.Calculator(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public int sum(int[]); Code: 0: new #2; //class com/qwertovsky/calculator/operation/Adder 3: dup 4: invokespecial #3; //Method com/qwertovsky/calculator/operation/Adder."<init>":()V 7: astore_2 8: aload_1 9: astore_3 10: aload_3 11: arraylength 12: istore 4 14: iconst_0 15: istore 5 17: iload 5 19: iload 4 21: if_icmpge 42 24: aload_3 25: iload 5 27: iaload 28: istore 6 30: aload_2 31: iload 6 33: invokevirtual #4; //Method com/qwertovsky/calculator/operation/Adder.add:(I)V 36: iinc 5, 1 39: goto 17 42: aload_2 43: invokevirtual #5; //Method com/qwertovsky/calculator/operation/Adder.getSum:()I 46: ireturn }
      
      





結果から、クラスには空のコンストラクターに加えて、Adderクラスのaddメソッドがループで呼び出される別のsumメソッドが含まれていることがわかります。 sumメソッドが完了すると、Adder.getSum()が呼び出されます。

-cスイッチを使用しない場合、プログラムは変数とメソッドのみをリストします(-privateを使用した場合はall)。

 javap -private -classpath calculator.jar com.qwertovsky.calculator.operation.Adder Compiled from "Adder.java" public class com.qwertovsky.calculator.operation.Adder extends java.lang.Object{ private int sum; public com.qwertovsky.calculator.operation.Adder(); public com.qwertovsky.calculator.operation.Adder(int); public void add(int); public int getSum(); }
      
      





ライブラリにドキュメントを提供することをお勧めします



このために計算機のクラスを変更します。

 package com.qwertovsky.calculator; import com.qwertovsky.calculator.operation.Adder; /** * ,    * @author Qwertovsky * */ public class Calculator { /** *    * @param a   * @return  */ public int sum(int... a) { Adder adder=new Adder(); for(int i:a) { adder.add(i); } return adder.getSum(); } }
      
      





ドキュメントは、次のコマンドで作成できます。 エラーが発生した場合、プログラムは可能なオプションのリストを表示します。

 mkdir doc javadoc -d doc -charset utf-8 -sourcepath src -author -subpackages com.qwertovsky.calculator
      
      





結果は次のとおりです

画像



jarアーカイブに署名できます



ライブラリにデジタル署名する必要がある場合は、keytoolとjarsignerが役立ちます。

署名を生成します。

 keytool -genkey -keyalg rsa -keysize 2048 -alias qwertokey -keystore path/to/qwerto.keystore Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]: Valery Qwertovsky What is the name of your organizational unit? [Unknown]: Qwertovsky What is the name of your organization? [Unknown]: Qwertovsky What is the name of your City or Locality? [Unknown]: Tver What is the name of your State or Province? [Unknown]: Tverskaya obl. What is the two-letter country code for this unit? [Unknown]: RU Is CN=Valery Qwertovsky, OU=Qwertovsky, O=Qwertovsky, L=Tver, ST=Tverskaya obl., C=RU correct? [no]: y Enter key password for <qwertokey> (RETURN if same as keystore password): Re-enter new password:
      
      





証明書署名要求(CSR)を生成する

 keytool -certreq -file path/to/qwertokey.crt -alias qwertokey -keystore path/to/qwerto.keystore
      
      





受信したファイルの内容は、証明機関に送信されます。 証明機関から証明書を取得します。 ファイル(たとえば、qwertokey.cer)に保存し、リポジトリにインポートします

 keytool -import -trustcacerts -keystore path/to/qwert.keystore -alias qwertokey -file path/to/qwertokey.cer
      
      





jarアーカイブに署名する

 jarsigner -keystore path/to/qwerto.keystore calculator.jar qwertokey
      
      





qwertokey.cerファイルは、アーカイブを確認したい人に送信されます。 そうチェックされます

 jarsigner -verify -verbose -certs -keystore path/to/qwerto.keystore calculator.jar
      
      





ライブラリの使用



Calculatorライブラリクラスを使用するHelloWorldプログラムがあります。 プログラムをコンパイルして実行するには、ライブラリをアタッチする必要があります。

コンパイル中

 cd HelloWorld javac -sourcepath src -d bin -classpath path/to/calculator.jar src/com/qwertovsky/helloworld/HelloWorld.java
      
      





打ち上げ

 java -classpath bin:path/to/calculator.jar com.qwertovsky.helloworld.HelloWorld
      
      





プログラムをまとめる



これはさまざまな方法で実行できます。



最初の方法



 cd HelloWorld echo main-class: com.qwertovsky.helloworld.HelloWorld>manifest.mf echo class-path: lib/calculator.jar >>manifest.mf mkdir lib cp path/to/calculator.jar lib/calculator.jar jar -cmf manifest.mf helloworld.jar -C bin .
      
      





微妙な点があります。

並んで

 main-class: com.qwertovsky.helloworld.HelloWorld
      
      





最後にスペースを入れないでください。

2番目の微妙さは[3]で説明されています。同じ行に次の行への転送があるはずです。 これは、マニフェストがサードパーティのアーカイバーによってアーカイブされている場合です。

jarプログラムは、最後に改行がない限り、マニフェストの最後の行をマニフェストに含めません。

もう1つのポイント:マニフェストでは、行間に空行があってはなりません。 エラー「java.io.IOException:invalid manifest format」がスローされます。



echoコマンドを使用するときは、main-classを使用して行末のスペースのみを監視する必要があります。



第二の方法



 cd HelloWorld echo class-path: lib/calculator.jar >manifest.mf mkdir lib cp path/to/calculator.jar lib/calculator.jar jar -cmef manifest.mf com.qwertovsky.helloworld.HelloWorld helloworld.jar -C bin .
      
      





このメソッドでは、メインクラスにスペースがあるエラーを回避します。



第三の方法



 cd HelloWorld mkdir lib cd lib jar -xvf path/to/calculator.jar com/ created: com/ created: com/qwertovsky/ created: com/qwertovsky/calculator/ inflated: com/qwertovsky/calculator/Calculator.class created: com/qwertovsky/calculator/operation/ inflated: com/qwertovsky/calculator/operation/Adder.class cd .. cp -r bin/* lib/ jar -cef com.qwertovsky.helloworld.HelloWorld helloworld.jar -C lib . rm -r lib
      
      





実行可能ファイルに目的のライブラリのコードを含めました。



実行可能なjarファイルの実行



calculator.jarファイルは実行可能ではありません。 ただし、helloworld.jarは起動できます。

アーカイブが最初の2つの方法で作成された場合、同じディレクトリ内のその隣には、calculator.jarファイルを含むlibフォルダーがあります。 このような制限は、実行可能ファイルへの相対パスがclass-pathのマニフェストで指定されているという事実によるものです。

 cd Calculator ls ../HelloWorld/lib calculator.jar java -jar ../HelloWorld/helloworld.jar
      
      





3番目の方法を使用すると、必要なライブラリが実行可能ファイルに含まれます。 適切なライブラリを近くに置く必要はありません。 それは同じように始まります。

 java -jar ../HelloWorld/helloworld.jar
      
      





JavaEEアプリケーションの処理方法



同様に。 コンパイル用のライブラリのみを、使用するアプリケーションサーバーから取得する必要があります。 JBossを使用する場合、サーブレットをコンパイルするには、次のようにする必要があります。

 javac -classpath path/to/jboss/common/lib/jboss-servlet*.jar -d ./classes src/com/qwertovsky/app/servlets/MenuSt.java
      
      





JavaEEアプリケーションのアーカイブ構造は、特定の形式に準拠する必要があります。 例えば

  my.ear `---META-INF | `---manifest.mf `---lib | `---mylib.jar `---my.war | `---META-INF | | `---manifest.mf | `---WEB-INF | | `---lib | | | `---myweblib.jar | | `---classes | | | `---com | | | `---... | | `---web.xml | `---index.html | `---< - (, )> `---myejb.jar
      
      





サーバーごとにコマンドラインを使用してサーバーでアプリケーションを実行する方法は異なります。



この記事が、Javaをコマンドラインで操作するためのチートシートになることを願っています。 これらのスキルは、Antスクリプトの内容と意味を理解し、インタビュー中に「どのIDEがもっと好きですか」よりも難しい質問に答えるのに役立ちます。



続きを読む



1. エリオット・ラスティ・ハロルド。 「UNIXおよびMac OS Xでクラスパスを管理するためのガイドライン」

2. エリオット・ラスティ・ハロルド。 「Windowsでクラスパスを管理するためのガイドライン」

3. ユージン・マチューシキン、別名スキッピー。 リクベズ

4. レッスン:プログラムをJARファイルにパッケージ化する

5. ブライアンゲッツ。 「Javaの理論と実践:これを文書化する必要がありますか?」

6. Evgeny Matyushkin別名Skipy。 「独自のjavadocタグの作成」

7. Javaアーカイブの作成と使用

8. Sun Java署名

9.javac-Javaプログラミング言語コンパイラ

10. java-Javaアプリケーションランチャー

11. jdb-Javaデバッガー

12. javap-Javaクラスファイル逆アセンブラー

13. javadoc-Java APIドキュメントジェネレーター

14. jarsigner-JAR署名および検証ツール

15. jar-Javaアーカイブツール

16. keytool-鍵および証明書管理ツール




All Articles