torutkのブログ

ソフトウェア・エンジニアのブログ

Java 21で(ちょびっと)スクリプト風なプログラミング

OpenJDK 21でお手軽なJavaプログラミング(JEP 445, 430)

2023年9月にリリースされるOpenJDK 21では、Previewの位置付け(正式な機能としての搭載ではなく、今後のバージョンで正式搭載する機能の事前仕様・実装を仮搭載し、広く使ってもらいフィードバックを得て改善し正式機能を目指す)ですが、次の機能が入っています。

JEP 445: Unnamed Classes and Instance Main Methods (Preview)

プログラム実行時の入り口(エントリポイント)となるmainメソッドを、クラス定義、static定義、引数定義しで記述

JEP 430: String Templates (Preview)

文字列の中に、変数や式を記述し実行時に変数の値や式の評価に置き換えるテンプレート機能

JEP 445

これまでJavaを実行する時のエントリポイントとなるmainメソッドを定義するには、クラスを定義し、そしてpublic staticなメソッドmainを引数定義付き定義する必要がありました。これを、mainメソッドについてはクラス定義をせずにトップレベルでstatic宣言無しに記述できるようにするものです。(詳細はもっと複雑です)

void main() {
    System.out.println("Hello, Java 21 world");
}

とはいえ、Javaはクラス無しでは実行できないので、コンパイル時にクラス(名前なしのパッケージの名前なしクラス->ファイル名に基づきクラスが生成される模様)が作られます。

JDK 21でのコンパイルと実行

JDK 21が利用できる環境である事を確認

% java --version
openjdk 21-ea 2023-09-19
OpenJDK Runtime Environment (build 21-ea+34-2500)
OpenJDK 64-Bit Server VM (build 21-ea+34-2500, mixed mode, sharing)

JEP 445はプレビュー機能なので、--enable-previewオプションを指定してコンパイル

% javac --enable-preview Hello.java                            
エラー: --enable-previewは-sourceまたは--releaseとともに使用する必要があります

おっと、エラーになりました。--releaseオプションに21を指定して再度コンパイルします。

% javac --enable-preview --release 21 Hello.java
ノート: Hello.javaはJava SE 21のプレビュー機能を使用します。
ノート: 詳細は、-Xlint:previewオプションを指定して再コンパイルしてください。

コンパイルできたかを確認します。

% ls
Hello.class Hello.java

では、実行します。

% java Hello                                    
エラー: メイン・クラスHelloのロード中にLinkageErrorが発生しました
    java.lang.UnsupportedClassVersionError: Preview features are not enabled for Hello (class file version 65.65535). Try running with '--enable-preview'

おっと、プレビュー機能は実行時も--enable-previewオプションが必要です。

MacBook level1 % java --enable-preview Hello     
Hello, Java 21 world.

無事実行できました。

mainメソッドは、従来は public static void main(String args) と、staticメソッドで引数にString配列を要求していましたが、このJEP 445では、

  • privateではないstatic void main(String args)
  • privateではないstatic void main()
  • privateではないvoid main(String[] args)
  • privateではないvoid main()

のいずれかが定義されているとそれをエントリポイントとして呼び出して実行します。(複数定義するときは上述の順番で先に見つかったmainが実行)

JEP 445補足
  • 無名クラスは無名パッケージに属するので、package文を記述するとコンパイルエラーに
  • 無名パッケージは無名モジュールに属する
JEP 430

文字列の中に、変数の値を入れたい、メソッドの実行結果(戻り値)を入れたい、といったときの簡単な機構が用意されました。

String person = "Tom";
String message = STR."Hello, \{person}."

STRは、Template Processorと呼ばれ、STRの後にドットに続けてテンプレート表現を記述します。テンプレート表現では、ダブルクォートで囲み、中に文字列と、バックスラッシュに波括弧で挟んだ中にJavaの式を記述します。式の中には、変数、メソッド呼び出しなどを記述できます。 このテンプレート表現は、文字列リテラルとは違い、中にダブルクォートをエスケープせずにダイレクトに記述してもOKでした。

String message = STR."Hello, Java \{System.getProperty("java.version")} world";

また、テンプレート表現は、波括弧の間が式になるので、ここに複数行に渡るJavaの式を記述することが可能です。 ダブルクォート3連で囲む複数行の文字列リテラルの書き方も可能です。

さらに、このSTRはimport文なしに使用可能です。

従来の文字列に変数や式の値を入れる方法

従来では、文字列同士を+演算子で結合して生成するとか、

String message = "Hello, " + person + ".";

Stringクラスのformatメソッドで、C言語のprintf風な書式文字列と適用する変数を指定するとか、

String message = String.format("Hello, %s.", person);

MessageFormatクラスのformatメソッドで、変数を埋め込みます。

String message = MessageFormat.format("Hello, {0}.", person);

StringBuilderを使う方法もありますが、割愛します。

JDK 21の開発環境

IntelliJ IDEA 2023.2.1 は、まだOpenJDK 21に対応していないので、JEP445のようにクラス定義がないトップレベルにメソッドを定義すると、エディターがエラーを訴えてきます。この状態では、Javaのサポート機能(補完など)が十分に動くことができません。インデントがうまくいかず、JEP445のコードの編集には耐えられないです。

これを無視することにしても、ビルドツールにGradleを使用していると、GradleもJDK 21に対応していないので、Gradleでビルドがエラーになってしまいます。

VSCodeのエディタも同様にJEP445の記述がエディタ上でエラー扱いとなっています。コード補完が効かず、ただこちらはインデントが崩れるまでには至りませんでした。

ということで、素のエディタが欲しくなってしまいます。

コンパイルせずに実行

OpenJDK 11から、単一のファイルだけで完結するJavaソースファイルをコンパイルせずにjavaコマンドで直接実行する機能が導入されています。

C:\work> java --enable-preview Hello.java
java --enable-preview Hello.java
エラー: --enable-previewは--sourceとともに使用する必要があります

おっと、エラーになってしまいました。--sourceオプションを付けて再度実行します。

C:\work> java --enable-preview --source 21 Hello.java
ノート: Hello.javaはJava SE 21のプレビュー機能を使用します。
ノート: 詳細は、-Xlint:previewオプションを指定して再コンパイルしてください。
Hello, Java SE 21 JEP445 world.

Java読書会「Practical Design Patterns for Java Developers」を読む会が始まります

今月からJava読書会「Practical Design Patterns for Java Developers」開始

Java読書会BOF主催のJava読書会は、今月から「Practical Design Patterns for Java Developers」を読み始めました。

洋書で266ページの分量です。 Packt Publishing の紙の本を買った人は、領収書などのエビデンスを提示するとPDF版の電子データを追加費用なしに入手することができます。例えば、Amazon.co.jpで本書の紙の本を購入した場合、本書の最後に書かれている「Download a free PDF copy of this book」に沿ってPacktのサイトにアクセスし、メールアドレスとAmazon.co.jpの領収証(電子、日本語混じり)を添付して申し込むと1日以内にダウンロードURLの記載されたメールが送られてきます。

このPDFは、図などがカラーになっているので、紙の本では白黒で判別しずらい図がわかりやすくなっています。 PDFの電子データは、Googleサイトなどで機械翻訳で日本語にすることができるので、読書会では日本語で読み進めることができます。Googleサイトの場合、無料枠はページ数上限ありますが、本書は範囲内でした。

メモリモデルの話に

最初は導入だなと読み進めていくと、Java言語のオブジェクト指向プログラミング言語の4本柱としてAPIE(抽象化:Abstraction、多態性:Polymorphism、継承:Inheritance、カプセル化:Encapsulation)の導入と、SOLID原則(単一責任原則:SRP、開放・閉鎖原則:OCP、リスコフ置換原則:LSP、インタフェース分離原則:ISP、依存性逆転原則:DIP)が出てきます。 ただ、ここはさらっと流されていて、その次にJMMJava Memory Model)の話が出てきます。まずJDKの構成から始まり(JDKのツールがいくつか抜粋で箇条書き紹介されていますが、最初のツールにjlinkが登場)、次にJVMの話でクラスロード、リンク、実行を解説、続いてメモリの構成(スタック、ヒープ、メソッド領域、プログラムカウンター、ネイティブスタック)、そしてメモリモデル(キャッシュと競合、volatile)、GCの解説となります。

SOLIDまではいかにもデザインパターン本かなと思いきや、ここからJDK、JavaVMのメカニズムに焦点が当たり、しばらく続いています。

ということで初日のPractical Design Patterns for Java Developersは、さらっとオブジェクト指向プログラミングJavaの4本柱とSOLID原則をちょこっと齧ったあと、JVMの話にダイブしていきました。

なかなか斬新です。

Java読書会「Java Memory Management」を読む会(第3回)開催

本日、Java読書会「Java Memory Management」を読む会(第3回)開催

ページ数が120ページと少ないこと、PDF版のGoogle翻訳で日本語朗読したことで、3回で読了となりました。

洋書でもPDF版が入手できると読書会の進行が日本語書籍並みになるのが良いですね。 日本語書籍では、なかなか読書会向きの候補がないのですが、英語を候補範囲にすると大きく広がります。

脱線気味のメモ

読書会の中で、少し脱線気味なアイテムのメモです。

ガベージコレクションとスレッド数

Javaプロセスは、使用するCPU数、メモリサイズがデフォルトでは大きいので、リソースを絞って実行したいときはJVMオプションで構成を変更します。書籍では、-XX:ParallelGCThreads オプションが紹介されていました。

MacBook Pro 2020(M1チップ)でのParallelGCThreadsのデフォルト値は8でした。 CPUが8コア(Pコア4、Eコア4)で、Javaから見えるCPUコア数は8となっています。

jshell> Runtime.getRuntime().availableProcessors()
$1 ==> 8

ParallelGCThreadsは、CPUコア数が8以上のときは8がデフォルト値となりますが、マシンのコアをフルに使いたくない場合はJVMオプションで少ない数を指定しておくのが良いです。

昨今のJDKでは、GCが多数用意され、実行時にどれを使うか選択ができます。

GC種類 GC指定オプション 備考
SerialGC -XX:+UseSerialGC
ParallelGC -XX:+UseParallelGC
G1GC -XX:+UseG1GC デフォルトのGC
ZGC -XX:+UseZGC

なお、複数のGCを指定すると、java起動時にエラーとなってしまいます。

 % java -XX:+UseSerialGC -XX:+UseParallelGC -version
 Error occurred during initialization of VM
 Multiple garbage collectors selected

書籍では記載が見当たらなかったGCに関するもう一つのオプションが-XX:ConcGCThreadsです。 ParallelGCは、アプリケーションスレッドを停止するstop-the-worldな処理に使うスレッド数の指定、ConcGCThreadsは、アプリケーションスレッドを実行しながら並行して行うGC処理に使うスレッド数の指定となります。

ガベージコレクションとそのオプションについては、オラクルの日本語ドキュメントが役立ちます。

ガベージ・コレクションのチューニングの概要

Java ドキュメント(ダウンロード版)の日本語版は?

Java SEのドキュメントは、オンラインとダウンロード版がありますが、日本語のダウンロード版は次のサイトから入手できます。

Java SE 日本語ドキュメント | Oracle 日本

ミリ秒未満のウェイトを入れたい

Java Memory Management」7章で、メモリリークするプログラムに VisualVM を接続してヒープ使用量とGCの活動をモニターする例を紹介しています。 実際に書籍のサンプルプログラムを動かして VisualVM から接続しようとしましたが、プログラムを起動するとあっという間にOutOfMemoryErrorを発生します。サンプルプログラムは、次のようにforループ内でノーウェイトでオブジェクトを生成するものです。

       List<Person> list = new ArrayList<>();
        while(true) {
            Person p = new Person("John");
            list.add(p);
        }

そこで、ループにウェイトを噛ませようとしました。定番のThread.sleepはウェイトが1ミリ秒以上となるため、1秒間に1000オブジェクトしか生成できず、今度はいつまでたってもOutOfMemoryErrorになりません。

Javaには、1ミリ秒未満の短い時間をウェイトする方法があるかを探ってみました。APIとしては、マイクロ秒やナノ秒を渡すsleepもあります。

  • Threadクラスのsleepメソッド
    • public static void sleep(long millis, int nanos) throws InterruptedException
  • TimeUnit.MICROSECONDS、TimeUnit.NANOSECONDSのsleepメソッド

これらのAPIに1マイクロ秒や100マイクロ秒を渡してみましたが、実際には1ミリ秒のウェイトになってしましました。 これは、通常のOSのスケジューラーが1msのtickで動作するので、それ以下の短い時間をsleep(ウェイト)させることができず、ビジーループで実現するしかないかと思われます。

以下は、1,000 ns のビジーループメソッドです。

    static void busyWait() {
        var start = System.nanoTime();
        while (System.nanoTime() - start < 1000);
    }
JavaVMオプションを環境変数で渡す

コマンドラインオプションで渡すJVM構成の指定を、環境変数から行うこともできるようです。

Oracle JDKドキュメントのツール仕様で、javaコマンドに次の記載があります。

JDK_JAVA_OPTIONSは、その内容をコマンド行から解析されるオプションの先頭に追加します。

https://docs.oracle.com/javase/jp/20/docs/specs/man/java.html#using-the-jdk_java_options-launcher-environment-variable

JAVA_TOOL_OPTIONS

Oracle JDKドキュメントのトラブルシューティングガイドに記載があります。

環境変数とシステム・プロパティ

JDK_JAVA_OPTIONSとの違いは、javaコマンド以外の時にも反映できる点、メインクラスなどのJavaVMオプション以外も渡せる点です。

Mission ControlツールでもVisaulVMと同じような情報が得られるのか?

T.B.D.

Java読書会「Java Memory Management」を読む会(第2回)

Java Memory Management」を読む会(第2回)の予習

世代別ヒープ管理

  • 若い世代(Young generation)は、さらにEdenと2つのSurvivor space(S0, S1)に分かれる
  • S1がターゲット空間とする
  • EdenのライブオブジェクトがS1にコピーされ、年齢が1にセット
  • S0のライブオブジェクトのうち年齢が閾値(MaxTenuringThreshold)を超えたものが旧い世代(Old generation)にコピーされる
  • S0の残るライブオブジェクトはS1にコピーされ、年齢が1つ加算
マイナー(若い世代の)GCの発動
  • Edenに新しいオブジェクトを割当てる連続した空き領域がない場合
関連するJVMフラグ

ヒープの大きさ、若い世代と古い世代の大きさの指定に関するJVMフラグがあります。

  • -Xms, -Xmx はヒープの最小、最大サイズを指定
  • -XX:NewSizeと-XX:MaxNewSizeは若い世代の最小サイズと最大サイズを指定
  • -XX:SurvivorRationは、edenの大きさに対する2つのsurvivorの相対的なサイズを指定
  • -XX:NewRationは、旧い世代に対する新しい世代の相対的なサイズを指定
  • -XX:PretenureSizeThresholdは、オブジェクトのサイズがこの閾値より大きい場合にオブジェクトを若い世代ではなく直接旧い世代に割当てる

一般には、ヒープ全体の25-33%を若い世代のサイズとするとのこと。

ガベージコレクション

オブジェクトが不要となる判断(マーク)
  • ストップ・ザ・ワールドは、マーキングフェーズ中に新しいオブジェクトが作成されないようにアプリケーションの実行を一時停止します。
  • ストップ・ザ・ワールド以外のアプローチとして参照カウントはオブジェクトの参照数をカウントし、参照数が0となったオブジェクトを削除可能とします。アプリケーションを一時停止する必要はないですが、相互参照する孤立したオブジェクトを削除できない欠点があります。
スイープ
  • 通常のスイープは、マークされていないオブジェクトをメモリから削除します。オブジェクトの大きさはまちまちなので、削除したメモリに新しいオブジェクトが割当てられるかはそのサイズによります。このようにメモリが断片化すると空きメモリは合ってもオブジェクトが割当てできないという問題が生じます。

  • 断片化したメモリを、割当済みのメモリを詰めて再配置するコンパクションを行うことで解消します。ただし、コンパクションには時間がかかります。

  • コピーによるスイープは、メモリを2つのブロックに分け、片方のブロックに割当てられたオブジェクトのうち到達可能なライブオブジェクトをもう一つのブロックにコピーすることで断片化を防ぎます。コンパクションよりも性能がよいのもメリットですが、メモリを多く使用するのがデメリットです。

メタスペース

クラスの情報(メタデータ)などを格納します。 メタデータ

  • クラスファイルのメモリイメージ
  • クラスのstructure、method
  • 定数プール
  • アノテーション
  • 最適化

JVMのメモリ管理の構成と監視

プロファイリングツール、jstat, jmap, VisualVM

Java読書会「Java Memory Management」第1回を実施して

Java読書会「Java Memory Management」を読む会(第1回)開催

5月20日(土)に、Java読書会BOF主催の「Java Memory Management」を読む会の第1回を実施しました。

洋書だけど

Java読書会BOFでは、これまでに幾度か洋書を課題図書とした読書会を実施しました。

初期の頃は、参加者が事前に担当ページを決めて日本語訳をした紙を配って朗読するやり方をしていました。準備がなかなか大変で、洋書の読書会は敷居が高いものがありました。

最近は、直接英語で朗読するやり方に変えて、事前準備は不要としましたが、英語での朗読なのでその場で意味を解釈しきれないといったことも出てきており、参加者の雰囲気としては日本語の本がいいねというものがあるようでした。

今回の「Java Memory Management」では、電子版(PDF、Microsoft Word)のデータをGoole翻訳あるいはMicrosoftの翻訳にかけて、読書会の場では日本語で朗読するという方法を取りました。(一部英語で朗読も実施) その結果、ページの進み具合は日本語の書籍と同じ程度となり、敷居もだいぶ下がっていました。

読書会当日の議論より

C言語でのint型のサイズ

p.7 の C言語での動的メモリ割り当てコード例で出てきた sizeof(int)について、今の大抵の環境では4(4バイト)となりますが、それ以外の値となる環境があるかどうか議論になりました。

64bitプログラムのデータモデルとして一般的なWindows OSのLLP64モデル、Linux OSのLP64モデルではintは4バイトです。ILP64モデルはintは8バイトとなり、大規模なデータを配列に収めたいといった用途で使われているようです(Intel MKLライブラリでILP64対応が提供)。

バイトコードを見る

スタック上に取られるメソッドのフレームにはローカル変数配列、オペランドスタック、フレームデータが置かれます。 IntelliJ IDEAでは、GUI上でバイトコードを見ることが標準でできました。ソースファイルを開いた状態で[View]メニュー > [Show Bytecode]です。 ただし、コンスタントプール、ラインナンバーテーブルは表示されず、そこまで見るとしたらjavapコマンドで解析する必要があるようです。

ガベージコレクションのルート

ガベージコレクションのルート(GCされないオブジェクトで、Liveの確認のため参照を辿る出発点)

  • スタック上のローカル変数
  • activeなJavaスレッド
  • スタティック変数
  • JNI参照
世代別ガベージコレクションでのオブジェクトの年齢

若い世代のヒープにはサバイバースペースがあり、マイナーGCの度に生存しているオブジェクトはその年齢を+1し、閾値に達すると旧い世代に移動されます。 この閾値Javaのオプションフラグ(-XX:MaxTenuringThreshold)で指定可能ですが、15より大きい値を指定するとオブジェクトが旧い世代には移動しなくなると記載があります。

the argument, as a value greater than 15 specifies that objects should never tenure

Java(Hotspot VM)の実装では、ヒープに生成するオブジェクトにはそれぞれオブジェクトヘッダーが付けられ、そのヘッダーにGCに関する情報も記載されます。サバイバースペースを生きのこった回数(年齢)はヘッダーの中に4bitの枠が確保されているので、0-15の値を取ることができます。よって、閾値を16以上にしてしまうと閾値判定ができなくなります。

オブジェクトヘッダーの構造は、OpenJDKのソースコード markWord.hpp を見るほか、OpenJDKのプロジェクト Lilliput に現状のヘッダーの資料があります。

ランチと2次会

ランチは、近くのインドレストランに行きました。土曜日もランチメニューがあり、インドカレー(ライスorナン、ドリンク付き)かビリヤニ(ドリンク付き)が1000円前後で食べられます。参加者の一人は、ビリヤニがおいしかったと言っていました。

2次会は、まず目的の会場撤収後17時過ぎに生ラム肉ジンギスカンのお店へ、しかしすでに満席でした。次の焼肉屋さんも予約で満席、台湾料理屋さんも予約で満席、となり、流れてメキシコ料理のレストランにて2次会を実施しました。

Java読書会「Java Memory Management」

今月からJava読書会「Java Memory Management」を読む会開始

Java読書会BOFは、5月の読書会から新しい本

Java Memory Management (Packt出版、2022年11月)

の読書会を開始します。洋書ですがページ数が140ページほどです。 (参加者募集中、申込は上述のJava読書会BOFのWebサイトから)

内容

プログラミングから見たJavaのメモリ管理の仕組みを平易に解説しています。 対象となるメモリは、

  • スタック
  • ヒープ
  • メソッド領域/メタスペース
  • ランタイム・コンスタントプール
  • プログラムカウンタレジスタ
  • ネイティブメソッドスタック

それぞれの内容、プリミティブ変数とリファレンス変数、スタックのフレームの構造、call-by-valueで引数・戻り値を受け渡すこととコピーの実態、世代別に管理されるヒープとGCルート、ガベージコレクタ、メタスペース、メモリの構成と監視について解説されていきます。

英語ですが、図が多く割と取りつきやすいのではないかと思います。 プログラミングにあたりメモリ管理について詳し過ぎることなく、難し過ぎることなくまとめられています。

買い方

紙で読みたいので、amazon.co.jp で注文しました。在庫があったので2日後には届きました。 Packt出版は、紙の本を購入した人に向けて、購入したことのエビデンス(領収証など)を提示するとPackt出版からPDF版を無料で受け取ることができます。

第1回の予習

英語本なので、事前に目を通しておいた方が良いと思い、ちらほら読みました。 スタックに取られるフレーの構造の説明が分かりやすいです。スレッド毎に作られ、ローカル変数配列、フレームデータ、オペランドスタックから成り立つ構成が図と共に説明されており、これまで漠然としか理解していなったフレームについて理解が深まりました。

Cesiumのためのnode.jsとJavaScript環境

はじめに

Webブラウザ上で3D地図表示を行うアプリケーションのためのJavaScriptフレームワーク Cesium JS があります。Cesium JSは、WebGLを用いてWebブラウザ上で描画するためのJavaScriptライブラリで、Cesium JSを利用して3D地図表示アプリケーションを開発するには、JavaScriptとnode.jsの知識が必要となります。

初めてJavaScript言語でアプリケーションを作成するので、その環境について調べたことを記録しておきます。

Cesium JSを用いて地球の3D表示をしたデモプログラムの画面が次です。

node.js

Cesium JSは、node.jsのパッケージとして配布されています。また、Cesium JSはCDN(Content Delivery Network)で提供されているので、node.js環境を用意しなくてもHTMLファイルからネットワーク経由でCesium JSをロードすることは可能です。ですが、Cesium JS以外のパッケージも使う場合などはnode.js環境で作るのが良いのかなと推測します。

node.jsのインストール

MacOSでは、Homebrewを利用している場合、次のコマンドでnode.jsをインストールします。

~ % brew install node
node.jsでパッケージのインストール

node.jsは、パッケージ(JavaScriptで記述されたライブラリやツール)をnpm(Node Package Manager)で管理するのが標準です。

npmは、デフォルトではローカルPCの作業ディレクトリにパッケージをインストールします。ディレクトリを変更すればパッケージを新たに入れる必要があるので、作業毎にクリーンな環境を作ることができます。また、オプション-gを指定すれば、ローカルPCに共通な場所にインストールすることもできます。

Cesium JSを使ったアプリケーションを開発するディレクトリを用意し、そこにnpmを使ってCesium JSをインストールします。

work % mkdir HelloGlobe
work % cd HelloGlobe
HelloGlobe % nom install cesium

インストール後、ディレクトリを見ると

HelloGlobe % ls -F -1
node_modules/
package-lock.json
package.json

node_modulesディレクトリの中に、Cesium JSライブラリがインストールされていました。

HTMLとJavaScriptファイルの作成

Cesium JSを用いて3D地図表示を行うには、HTMLファイル、CSSファイルおよびJavaScriptファイルを記述する必要があります。 手元のMacには、これらのコード補完が効く編集環境として、Visual Studio CodeIntelliJ IDEA Ultimateが入っているので、どちらかを使うことにします。

ローカルWebサーバーの使用

Webブラウザで実行するアプリケーションが、ローカルPC上のJavaScriptファイルをロードすることはセキュリティ的に制限されています。そのため、node.js環境でインストールしたパッケージを使うHTMLファイルをWebブラウザで直接開いて実行すると、エラーとなってしまいます。そこで、ローカルPCに簡易なHTTPサーバーを立てて、その上でアプリケーションをWebブラウザに実行させるようにします。

node.jsでweb サーバーを探すと、express等のhttpサーバー構築用フレームワークが出てきますが、今回はhttpサーバーを作りたいのではなく、HTML、JavaScriptファイルをWebサーバー経由でWebブラウザ上で動かしたいので、出来合いのhttpサーバーを使います。

http-serverパッケージのインストール

node.jsでインストールし実行可能な出来合いのHTTPサーバーとして http-serverを使用します。

~ % npm install -g http-server

-gオプションを指定し、共通のディレクトリにインストールします。

http-serverの実行
HelloGlobe % http-server
Starting up http-server, serving ./

http-server version: 14.1.1
  :
Available on:
  http://127.0.0.1:8080
  http://192.168.133.101:8080
Hit CTRL-C to stop the server

デフォルトでは、カレントディレクトリをルートとしてポート8080でhttpサーバーを実行します。