JavaEEで作ったソフトのアップロードはどうするの?


はじめに

 これは、JavaEE Advent Calendar 2016 の第1日目の記事です。

 JavaEEについて学習し、仕組みがわかってくると、何か作れそうな気がしてきて「じゃぁ、アレを作ってみよう」などと考えます。そして、できれば仕事で使えるものにしたいと思うのが人情です。すると、必ず湧いてくる疑問が「サーバーはどうする? アップロードってどうやるんだろう?」ということです。「わかりやすいJavaEE」(秀和システム刊)の読者からも、何度か同じような質問を頂きました。

 そこで、いい機会ですから、サーバーの準備やデータベースのセットアップ、そしてデプロイまで、あれこれまとめてお話しようと思います。自分でサーバーを持つなんてゼイタクと思う必要はありません。今では、案外、手軽に使うことができます。初めてでも大丈夫ですよ!

1.サーバーをなんとかする -さくらのVPSを例にして-

 JavaEEのソフトウェアを動かすには、JavaやGlassfishが使えるサーバーが必要です。いわゆる”レンタルサーバー”は、ウェブサーバーは使えますが、JavaはもちろんGlassfishサーバーをインストールして動かすなんてことはできません。

 個人でも、VPS(virtual private server)をレンタルするのがいいでしょう。最近は業者さんも増えてきて、価格も安くなりました。GMOとさくらのVPSを使ったことがありますが、さくらはインストールのための解説記事をたくさん公開していて、初心者にもやさしいVPSです。本稿では、さくらのVPSを使うことを前提にお話しします。

 筆者が "さくらのVPS" で借りているのは、OS:CentOS、CPU:仮想3Core、メモリ:2GB、SSD:50GBで、月額1,706円です。
 このサーバー上にApacheでサポートウェブを開設し、解説ブログ JavaIndex「Q&AわかりやすいJavaEE」用にWordpressもインストールしています。また、JavaとGlassfishをインストールして、「わかりやすいJavaEE」に掲載したショッピングサイトの例題 雑貨屋さん.com を公開しています。さらに、ユーザー登録処理("読者になる"のボタンの処理)のサービスをはじめ、いくつかのJavaEEで作ったウェブアプリケーションも動かしています。

 これだけやってもSSDのディスクは、まだ30%程度しか使っていない状態なので、小規模な仕事ならこれで十分のようです。VPSのよいところは、監視や運用の手間が軽減できることと、ファイルのダウンロード速度が速いことです。以前は、ダイナミックDNSのサービスを使って自宅サーバーを構築・運営していましたが、VPSに替えてずいぶんよくなりました。

 VPSはOSによって値段が違います。WindowsOSのサーバーを選ぶと、Linux(CentOSが多い)を選択した場合に比べて、料金が1.5~2倍くらいになります。どちらにするか考えどころですが、Linuxに不慣れでもインストールの解説記事が公開されているので、それほど難しいわけではありません。それを見ながら、無料で使えるお試し期間(2週間)にトライしてみるといいでしょう。さくらのVPSでは、次のようなマニュアルを公開しています。

Sakura VPS マニュアル
初心者でもわかる!さくらVPS - Sakura VPS マニュアル

 この解説の通りに作業する(コピペ用のコマンドが書かれているので、それをそのまま入力する)だけで、Teratermを使ってサーバーにsshでログインししたり、ファイル転送をしたりできるようになります。また、ウェブサーバ、mySQL、PHPなどのインストールもできるはずです。

 なお、ファイル転送にwinSCPを使いたい場合はsynclogue naviさんの解説が役にたちます。

WinSCPの使い方から設定まで全てが分かる記事まとめ

2.必要なモノを準備をする 

 JavaEEのアプリケーションを動かすには、JavaとGlassfishをVPSにインストールします。
この手順は、no14141さん(タイガー!タイガー!じれったいぞー(SE編))の次の記事が役に立つでしょう。

CentOS7.0へGlasssfish4.1インストール

3.アプリケーションをアップロード

では、準備がおわったら、作ったアプリケーションをGlassfishにアップロード(本当は、配備とかデプロイなどという)しましょう。


 

 NetBeansは、デプロイするwarファイルを自動的に作成しています。
 まず、NetBeansの3つのタブ(プロジェクト、ファイル、サービス)のうち、ファイルタブを開きます。例えば、デプロイしたいのがdb_Custormerプロジェクトなら、それに対応するdb_Customerフォルダが見えるはずです。
 フォルダを展開するとその中にdistというフォルダがあります。distフォルダにdb_Customer.warファイルが入っています。ただ、これはNetBeansの中での表示ですから、warファイルが実際にはどこにあるか、右ボタンでファイルをクリックし、プロパティを見て調べる必要があります。

  

 なお、distフォルダがない時は、プロジェクトタブをクリックして戻り、プロジェクトを右クリックして、[消去してビルド]を実行します。たまに、消去できずに失敗することがありますが、その場合は、[ビルド]を実行すればいいでしょう。この操作により、distフォルダが作成され、その中にwarファイルが生成されます。
 

 warファイルをGlassfishサーバーにデプロイするには、サーバー管理コンソールから行うと簡単です。[Application]→[deploy]→[ファイルを選択]とボタンを選択して、最後に[OK]を押すだけです。

① Applicationをクリックする

②[Deploy]ボタンを押す

③[ファイルを選択]ボタンを押す

④ファイルを選択して[開く]ボタンを押す

⑤[OK]ボタンを押す

⑦リストにデプロイしたファイルが表示される

4.コネクションプールとデータソースがないとデータベースは使えない

注記
Glassfishのサーバーコンソールでは、GUIでコネクションプールとデータソースを作成できるようになっていますが、4.1以降のバージョンでは、正常に動作しないようです。4.1では一見作成できたかに見えるのですが、pingでエラーになり、接続できません。また、4.1.1では内部エラーを起こしてしまいます。コマンドを使って作成すると、確実に動作するので、ここではコマンドを使う方法を紹介しています。

 Glassfishには、JavaDBというデータベースシステムが付属しています。ここでは、ダウンロードしたglassfishを/usr/localに解凍した場合の例で示します。/usr/local/glassfish4フォルダの中にあるjavadbフォルダが、付属するjavadbです。

(1)データベースを作成する

 まず、Teratermでサーバーにログインします。
 そして、次の手順で、データベースmydbを作成します。

1   #> su glassfish
2   $> cd /usr/local/glassfish4/bin
3   $> asadmin start-database
4   ・・・省略・・・
5   Command start-database executed successfully
6   $> cd /usr/local/glassfish4/javadb/bin
7   $> ./ij
8   ijバージョン10.10
9   ij>connect 'jdbc:derby://localhost/mydb;create=true;user=APP;password=APP';
10  ij>exit;

※プロンプトは簡略に表記しています(以下も同様)。
 
<説明>
1: ユーザー glassfishに切り替える (glassfishインストール時に作成したユーザー)
2: glassfishのコマンドがあるディレクトリに切り替える
3: データベースサーバーを起動する
6: JavaDBのコマンドがあるディレクトリに切り替える
7: ijコマンドモードに入る(データベースを操作できるようになる)
9: ユーザー名APP、パスワードAPPで、mydbというデータベースを作成する
10: ijコマンドモードを終了する

(2)コネクションプールとデータソースを作成する

 「わかりやすいJavaEE」の393ページで解説していますが、JavaEEではデータベースをリソースとして扱います。そのため、コネクションプールとデータソースを定義しておく必要があるのです。
 

  

 
次は、作成したデータベースにアクセスするためのコネクションプールとデータソースを作る手順です。

<コネクションプールの作成:JavaDB用>

$> cd /usr/local/glassfish4/bin
$> <コネクションプール作成コマンド(下記)>

 コネクションプール作成コマンドを、意味が分かるように分かち書きしたものが次です。□は、半角の空白を意味します。入力する時は、半角の空白を含めて、改行せずにすべてを連続して入力し、最後にEnterキーをタイプしてください。

asadmin□create-jdbc-connection-pool
□--datasourceclassname□org.apache.derby.jdbc.ClientDataSource 
□--restype=javax.sql.DataSource 
□--property 
□user=APP:
□password=APP:
□DatabaseName=mydb:
□ServerName=localhost:
□port=1527:
□URL="jdbc\:derby\://localhost\:1527/mydb"□mydb-Pool

<データソースの作成: javadb用>
 コネクションプールができたら、次のコマンドをタイプし、データソースを作成します。

asadmin□create-jdbc-resource□--connectionpoolid□mydb-Pool□jdbc/mydb

とても手書きする気にはならないと思いますが、glassfish-resources.xmlは、次のような内容です。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
    <jdbc-connection-pool
    allow-non-component-callers="false"
    associate-with-thread="false" 
    connection-creation-retry-attempts="0"
    connection-creation-retry-interval-in-seconds="10" 
    connection-leak-reclaim="false" 
    connection-leak-timeout-in-seconds="0" 
    connection-validation-method="auto-commit"
    datasource-classname="org.apache.derby.jdbc.ClientDataSource"
    fail-all-connections="false" 
    idle-timeout-in-seconds="300" 
    is-connection-validation-required="false" 
    is-isolation-level-guaranteed="true" 
    lazy-connection-association="false" 
    lazy-connection-enlistment="false" 
    match-connections="false" 
    max-connection-usage-count="0" 
    max-pool-size="32" 
    max-wait-time-in-millis="60000" 
    name="derby_net_mydb_APPPool" 
    non-transactional-connections="false" 
    pool-resize-quantity="2" 
    res-type="javax.sql.DataSource" 
    statement-timeout-in-seconds="-1" 
    steady-pool-size="8" 
    validate-atmost-once-period-in-seconds="0" 
    wrap-jdbc-objects="false">
        <property name="serverName" value="localhost"/>
        <property name="portNumber" value="1527"/>
        <property name="databaseName" value="mydb"/>
        <property name="User" value="APP"/>
        <property name="Password" value="APP"/>
        <property name="URL" value="jdbc:derby://localhost:1527/mydb"/>
        <property name="driverClass" value="org.apache.derby.jdbc.ClientDriver"/>
    </jdbc-connection-pool>
    <jdbc-resource
        enabled="true"
        jndi-name="jdbc/mydb" 
        object-type="user" 
        pool-name="derby_net_mydb_APPPool"/>
</resources>

 安心してください。これは、「わかりやすいJavaEE」の例題で、持続性ユニットを作る時に、自動的に生成されたものです。持続性ユニットを作る時、[新しいデータソース]を選択して、JNDI名やデータベース名を入力すると、プロジェクトに[サーバー・リソースフォルダ]ができ、その中に自動生成されます。

 このファイルをwinSCPで /usr/local/glassfish4/javadb/bin/ に送信して、次のようにタイプするだけで、コネクションプールとデータソースが生成されます。

$> cd /usr/local/glassfish4/bin
$> asadmin add-resources glassfish-resources.xml

 なお、winSCPでは、次の図のように、local側(左)からremote側(右)へ、ファイルをドラッグしてドロップします。すると、ダイアログが出るので、[Copy]ボタンを押すと転送されます。

 

5.おわりに

 「わかりやすいJavaEE」のサポートウェブにも書いていますが、NetBeansの8.1と8.2は、glassfish-resources.xmlを作ってくれるところまではいいのですが、Glassfishサーバーにそれをうまく渡すことができないようです。そのため、コネクションプールやデータソースの自動生成がうまく働きません。また、注記に書いたように、Glssfish側にも問題があって、4.1以降は、サーバーコンソールでの作成もうまく機能しません。

 そこで、安全で確実な組み合わせとして、NetBeans8.02とGlassfish4.1を使うように、サポートウェブでお知らせしています。しかし、ここでお話した方法で、つまり、コマンドでコネクションプールとデータソースを作っておけば、NetBeansやGlassfishの最新版を使えると思います。コマンドプロンプトで、<Glassfishのインストールディレクトリ>/bin に切り替えて、asadmin add-resources glassfish-resources.xml を実行するだけです。glassfish-resources.xml は、binフォルダにコピーしておくか、パスを指定すればそれでもいいはずです。
 
追記:
 Java(SE)のAdvent Calendar13日目に、JavaSEでJPAを使う方法と、そのためのユーティリティクラスについて書きます。JavaSEでもEEのようにスマートにJPAを使えるようにしてみました。ぜひ、そちらの方もご覧ください。