2016年6月20日月曜日

【JavaでPlayFramwork2.4.6】ビルド時のネットワーク問題と起動

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

最近はPlayFrameworkについて勉強を進めています。

プロジェクト起動


前回の荒技で、とにかく2.4.6でのプロジェクトは完成しました。

では、プロジェクトの起動に行ってみましょう。

コマンドプロンプトを起動し、

cd "作成したプロジェクトのフルパス"
activator run

これでプロジェクトが起動します。
が、実際には私はここで躓いたので、その時の経験談も踏まえて今回は雑談ベースです。

Activatorにパスが通っていない


私のような慌て者のエンジニアは上記の通りActivatorコマンドを実行しても「操作可能なプログラムまたはバッチ ファイルとして認識されていません。」とか出てくるかもしれませんね。
これはActivatorにパスが通っていないのでしょう。

PlayFrameworkの管理コマンドであるActivatorはダブルクリックで自動インストールするものではなく、圧縮ファイルを展開して設置し、そこに手動でパスを通さなければいけないものです。
この状況に陥っている人は公式サイトをもう一度ご確認下さい。


ネットワーク問題


PlayFrameworkはActivatorコマンド実行時とrun実行時の二回に分けてインターネット上からファイルをダウンロードしてくる挙動となっています。
従ってネットワーク環境に繋がっていない環境では起動出来ません。

私はここで大変苦労しました。
私の現在の現場環境はセキュリティが大変厳しいので自由にインターネット接続出来ません。
よってsbtのビルドで自動であっちこっちからjarファイル等のライブラリをダウンロードしてくるのは望ましくなかった為、オフラインビルドを試みました。


公式サイトのダウンロードページに「Offline Distribution」というリンクがあり、これがsbt実行ダウンロードするファイルを最初から一塊で取得出来るものです。
これを取得し、USBメモリでオフラインPCに移動させて、いざオフラインPCから起動……とやってみたわけですが……。

結論を言うと、無理!!
初回のオフラインビルドは現実的ではありません。

と言いますのも、どうやら「Offline Distribution」と言えども全部入っているわけではないようです。
インターネット界は日々進化していますので、細かいバージョンの差分とかが発生してしまって「Offline Distribution」には既に古くなってしまったものが混ざっているのです。

また、「Offline Distribution」はあくまで初回セットであり、そこから追加で何かプラグインを入れたりするとなると、当然ながら「Offline Distribution」の中にはありません。

「Offline Distribution」に入っていないものは別途、手動でネットからダウンロードしてオフラインPCに移植し……と頑張ってみましたが、無理でした。
取得しなければならないファイルは一個や二個の話ではないので、手動ダウンロードを繰り返してビルドしようと思ったら一日では終わりません。

二日……三日……どれくらい頑張ったら出来るんだろう???

とにかく、インターネットビルドを使わず手動ビルドで初回起動するのは三途の川のほとりで石を積み上げるようなものです。

頑張ってもゴールに辿り着けませんので、これからビルドする人は絶対にインターネット環境でビルドすることをオススメします。

  • オフラインだけでのビルドは至難。オンライン環境は事実上の必須。
  • どうしてもオフラインでビルドしなければならない場合、最初だけオンラインでビルドし、ダウンロードしたファイルをオフラインPCに移植する。

ただし、あくまでも初回起動時にjarファイルを収集するステップが大変なだけですので、一度ビルド出来てしまえば、後はオフラインでもOKです。
複数人で作業する場合も、最初に一台だけインターネット環境でビルドし、集めたjarファイルをUSBメモリ等で他のオフラインPCに移植すれば、全部オフラインでも起動出来ます。

経験者ならではの体験談ですね。。。

プロキシ


当然ながら社内などプロキシがある環境で実行する場合、プロキシが通っていなければインターネットに接続出来ません。

これは知っている人は当然でしょうが、私は初体験でした。
インターネットオプションのプロキシと、コマンドプロンプトのプロキシは別です。

コマンドプロンプト実行時にプロキシ接続する場合は、例えば以下のようにコマンドラインからプロキシを設定するとか、
システム詳細の環境変数で事前にプロキシ設定を登録するといった対応の必要があります。

set HTTP_PROXY=http://プロキシサーバ:ポート番号/

この辺りはPlayの話というよりネットワークの問題ですので、各環境毎に奮闘願います。
簡単そうで意外に難しかったです。

起動成功

こうして環境の壁を越えて、何とかようやく初回起動出来ました。
「http://localhost:9000/」で以下のような画面が表示出来ます。


私の場合はネットワークの壁があったので大変苦労しましたが、それが無い環境でしたらスルッと簡単に起動まで辿り着けると思います。

やっぱり開発者には快適なインターネット環境は必要不可欠ですね。。。

終わりに


これにてようやく初回起動まで辿り着きました。
引き続き勉強を継続していきます。

2016年6月6日月曜日

【JavaでPlayFramwork2.4.6】プロジェクト作成 後編 ~古いバージョンで作成する~

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

業務都合によりPlayFramworkを始めました。
ここまでの下勉強により、PlayFramworkのバージョンは2.4.6にすることにしました。

しかし、PlayFramworkは最新バージョンで作成するのは簡単なのですが、古いバージョンで作成するのは面倒なのです。
今回は古いバージョンで作成する手順をご紹介します。

バージョン指定が出来ない


おさらいから行ってみましょう。
PlayFrameworkではプロジェクトを新規作成する場合、コマンドプロンプトでActivatorのnewコマンドを実行すれば一発で作成出来ます。

activator new my-first-app play-java

この時、Activatorはインターネットに接続し、Play本家のサイトから最新バージョンをサーチして取得するという挙動をします。
勝手に最新バージョンを取得してしまい、古いバージョンは取得出来ません。

「-version=2.4.6」のようにオプションを指定することで古いバージョンを取得する機能はありません。

これくらい出来そうな気がするんですけどね。何で無いんだろ……。

しかし、自動で作成出来ないなら手動で作成しましょう。

テンプレートをダウンロード


PlayFrameworkのnewコマンドが最新バージョンになってしまうのは、最新のテンプレートをダウンロードしてくるからです。
そして過去のテンプレートはGitHubに置いてありますので、これを手動でダウンロードすればテンプレートは入手可能です。

以下サイトからお好みのバージョンをダウンロードしてきてください。
私は2.4.6をダウンロードします。


解凍すると、中に「templates」というフォルダが入っています。


その中には2.4.6テンプレート4種が入っています。


これこれ、これが欲しかったんですよ。
私はJavaを使用しますので「play-java」をゲッツします。


その中身は、このように「Activator new」した時とほぼ同じ構成になっています。
PlayFramework初心者はこの状態からスタートするのが最もスムーズに入っていく近道でしょう。

しかし、この状態でアプリを起動しようとするとまだエラーが発生してしまいます。



  • :: org.scala-sbt#sbt;%SBT_VERSION%: java.lang.IllegalArgumentException at sun.net.www.ParseUtil.decode(ParseUtil.java:202)

%SBT_VERSION%!!

バージョン指定。
つまり、本来はnewコマンドが自動で行ってくれる設定ファイルへの最新バージョンセット機能が作動していない。
よってここから先は手動でバージョンを記述することになります。

「手動でセットって、どんな値をセットすればいいの?」という問題につきましては、フォルダを一個遡ってtemplatesフォルダ直下のbuild.sbtに書いてあります。

import play.sbt.activator.Templates._

templateSettings

scalaVersion := {
  // If we're a snapshot build, then default to 2.10.5, since this is what gets built by default for Play
  // If we're a production build, then we want 2.11.6
  sys.props.getOrElse("scala.version", if (isSnapshot.value) {
    "2.10.5"
  } else {
    "2.11.6"
  })
}

crossScalaVersions := Seq("2.10.5", "2.11.6")

templates := {
  val dir = baseDirectory.value
  Seq(
    "play-scala",
    "play-java",
    "play-scala-intro",
    "play-java-intro"
  ).map(template => dir / template)
}

version := sys.props.getOrElse("play.version", version.value)

def playDocsUrl(version: String) = {
  // Use a version like 2.4.x for the documentation
  val docVersion = version.replaceAll("""(\d+)\.(\d+)\D(.*)""", "$1.$2.x")
  s"http://www.playframework.com/documentation/${docVersion}"
}

// Use different names for release and milestone templates
def templateNameAndTitle(version: String) = {
  val officialRelease = version.matches("[0-9.]+") // Match final versions but not *-SNAPSHOT or *-RC1
  if (officialRelease) ("", "") else ("-preview", " (Preview)")
}

templateParameters := Map(
  "PLAY_VERSION" -> version.value,
  "SCALA_VERSION" -> scalaVersion.value,
  "PLAY_DOCS_URL" -> playDocsUrl(version.value),
  "SBT_VERSION" -> "0.13.8",
  "COFFEESCRIPT_VERSION" -> "1.0.0",
  "LESS_VERSION" -> "1.0.6",
  "JSHINT_VERSION" -> "1.0.3",
  "DIGEST_VERSION" -> "1.1.0",
  "RJS_VERSION" -> "1.0.7",
  "MOCHA_VERSION" -> "1.1.0",
  "ENHANCER_VERSION" -> "1.1.0",
  "EBEAN_VERSION" -> "1.0.0",
  "PLAY_SLICK_VERSION" -> "1.1.0",
  "TEMPLATE_NAME_SUFFIX" -> templateNameAndTitle(version.value)._1,
  "TEMPLATE_TITLE_SUFFIX" -> templateNameAndTitle(version.value)._2
)


パッと見て概ね意味は分かるのではないでしょうか?

例えば、「SBT_VERSION" -> "0.13.8"」と書かれていますので、
先ほどのエラーの「%SBT_VERSION%」の所には「0.13.8」を書けば良いという意味になります。

「"PLAY_VERSION" -> version.value」のように直球で書かれていない部分は、
「自分は2.4.6を使いたいんだから2.4.6だな」と判断していくことになります。

これらを元にplay-javaの以下ファイルにガンガン手動記述していってください。

  • play-java/build.sbt
  • play-java/project/build.properties
  • play-java/project/plugins.sbt

ちょっと数が多いので面倒ですが、正常に設定出来ていないと上記画像のようにコマンドプロンプト上にエラーが出来ますから、
地道にやっていけば10分くらいで起動まで到達出来ると思います。

これでPlayFramwork2.4.6の起動に成功しました。
おめでとうございます!!

終わりに


我ながら荒技ですね、このやり方は……。
元々がActivator newコマンド一発で可能な作業なわけですから、
build.sbtによるビルドを熟知している人なら、こんな手動置換作業を行わなくても自動でビルド出来るはずなのですが……。

しかし調べても分からなかったので今回はこのような手動ゴリ押し戦術で対処しました。

何か分かったら追加記事を書きたいと思います。

引き続きPlayFramworkの記事を継続します。