|
|||||||||
play24 の変更点
#author("2017-11-16T01:48:50+00:00","default:pentacle","pentacle")
play2.4 になってだいぶかわったので書き直し
JAVA 用です!~
----
* はじめに [#q9a7f043]
- activator
''play コマンドがなくなって activator コマンドになった''
COLOR(RED):''activator コマンドがなくなって sbt コマンドになった(May/2017)(んもう!''
インストールも実行も全部 activator
mkdir /usr/local/play24
https://www.playframework.com/download
* install [#i2cb0429]
activator をダウンロードしてどこかに置く~
cygwin では実行するとエコーを奪われてしまうので戻す必要がある~
.bashrc
function activator(){
/usr/local/play24/activator $@
stty sane
}
function playkill(){
ps aux -W |grep java |uniq | head -1 |awk '{print $1;}' |xargs kill
}
alias activatordebug='activator -jvm-debug 9999 run'
* eclipse [#ee682e90]
[[eclipse]]
* hello world [#w30bce6c]
activator
UI で、java のシンプルなテンプレートを選ぶ
cd helloworld
** 2.4 でいろいろ変わった設定 [#n5574081]
- play eclipse がプリインストールではなくなりました。
- ebean がプリインストールではなくなりました。
- evolution がデフォではなくなりました
- PlayEbean がデフォではなくなりました
''project/plugins.sbt''
addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "1.0.0")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0-RC2")
activator
eclipse with-source=true
exit
''build.sbt''
下記行を変更
lazy val root = (project in file(".")).enablePlugins(PlayJava,PlayEbean)
fork in run := false
sources in (Compile,doc) := Seq.empty
publishArtifact in (Compile, packageDoc) := false
import com.typesafe.sbt.packager.Keys.scriptClasspath
scriptClasspath := {
val originalClasspath = scriptClasspath.value
val manifest = new java.util.jar.Manifest()
manifest.getMainAttributes().putValue("Class-Path", originalClasspath.mkString(" "))
val classpathJar = (target in Universal).value / "lib" / "classpath.jar"
IO.jar(Seq.empty, classpathJar, manifest)
Seq(classpathJar.getName)
}
mappings in Universal += (((target in Universal).value / "lib" / "classpath.jar") -> "lib/classpath.jar")
libraryDependencies ++= に追加
evolutions,
filters,
''conf/application.conf''
include "server.conf"
下記コマンドでシークレットを作成
activator playGenerateSecret
''conf/server.conf''
新規作成して、下記行に、上記コマンドで作られたキーを入力
play.crypto.secret = "xxxxxxxxxxxxxxxxxxxxx"
''conf/routes''
Play では基本的に html 等は jar にまとめられてしまうため、生のファイルをリンクしたい場合は下記行を追加
GET /files/*file controllers.Assets.versioned(path="/files", file: Asset)
* eclipse でインポート [#v142ea51]
//- ビルド・パスに クラス・フォルダーの追加(scala template用)
// target/scala-2.11/classes
// target/scala-2.11/routes
// target/scala-2.11/twirl
* 実行 [#rd3a4cad]
外部ツールの構成 -> プログラム
|ロケーション|c:\cygwin\usr\local\play24\activator.bat|
|作業ディレクトリー| ${project_loc} |
|引数| -Djava.net.preferIPv4Stack=true -jvm-debug 9999 run|
* DBをpostgres [#ncf74064]
- DBを作成しておく
psql -U postgres
create database play24base;
''build.sbt''
libraryDependencies += "org.postgresql" % "postgresql" % "9.4-1201-jdbc41"
activator compile
activator eclipse
''conf/server.conf''
db.default.driver=org.postgresql.Driver
db.default.url="jdbc:postgresql://localhost:5432/play24base"
db.default.username="postgres"
db.default.password="postgres"
ebean.default=["models.*"]
* debug [#qe7b5584]
** break point [#k049ab9c]
activator -jvm-debug 9999 run
eclipse で 9999をデバッグポートに指定
* log [#jb1bd29e]
** ログに日付を [#b302d76e]
''conf/logback.xml''
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level] - %logger - %message%n%xException</pattern>
** RAW SQL をログ出力 [#m516f750]
''conf/logback.xml''
<logger name="org.avaje.ebean.SQL" level="TRACE"/>
* dist [#qe22dd24]
デプロイ用パッケージの作成
activator dist
下記に生成されている
target\universal\xxxxx.zip
このファイルをサーバに持っていって展開~
bin 以下にある実行ファイルを実行~
~
ちなみに、conf 以下のフォルダはそのままパックされるのでもって行きたい外部ファイル等はconf 以下に置くと楽~
設定でかけるとは思うけれど・・~
public/ 以下の画像ファイル等は jar に固められている~
*** 起動スクリプト [#df60dbd7]
#pre{{
#!/usr/bin/bash
BIN=appname
APP=${BIN}-1.0-SNAPSHOT
ps -auxww |grep java |grep ${APP} |awk '{print $2;}' |xargs kill -9 2>/dev/null
rm -rf ${APP}/RUNNING_PID
rm -rf ${APP}
cp ~/${APP}.zip ./
unzip ${APP}.zip
cp service.conf ${APP}/conf/
rm -rf ${APP}/share
cd ${APP}
bin/${BIN} -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 >> /var/log/application/${BIN}.log &
}}
本当の初回に evolution を一回だけやりたい場合は
bin/${BIN} -Dplay.evolutions.db.default.autoApply=true -Dplay.evolutions.db.default.autoApplyDowns=true
* SessionCache を永続化 [#g10c42fc]
''conf/ehcache.xml''
#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd" updateCheck="false">
<!-- ehcache 永続化ファイルのパスを指定 -->
<diskStore path="user.dir/.ehcache" />
<!-- diskPersistent="true" で永続化を有効にする (デフォルトは false) -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
}}
* sample [#nbe20a7b]
** model [#ue9b4b05]
#pre{{
package models;
import java.util.Date;
import javax.persistence.*;
import com.avaje.ebean.*;
import com.avaje.ebean.annotation.*;
import play.data.validation.Constraints.*;
@Entity
public class Country extends Model {
@Id
public Long id;
@Required
public String name;
// @OneToMany(cascade = CascadeType.ALL)
// public List<Holiday> holidays;
@CreatedTimestamp
public Date created_date;
@UpdatedTimestamp
public Date updated_date;
public static final Find<Long, Country> finder = new Find<Long, Country>() {
};
}
}}
* テンプレートを velocity にしたい時 [#vbaa2b20]
''build.sbt''
libraryDependencies += "org.apache.velocity" % "velocity" % "1.7"
libraryDependencies += "velocity-tools" % "velocity-tools" % "1.4"
activator eclipse
''Global.java''
#pre{{
import org.apache.velocity.app.Velocity;
import play.Application;
import play.GlobalSettings;
public class Global extends GlobalSettings {
@Override
public void onStart(final Application app) {
Velocity.setProperty("file.resource.loader.path", "conf/templates/");
Velocity.init();
}
}
}}
* CSRF [#ie7717b5]
- build.sbt に filters を追加
- application.conf の play.crypto.secret を適切に設定
''Controller''
#pre{{
@AddCSRFToken
public Result form() {
return ok(session().get("csrfToken"));
}
@RequireCSRFCheck
public Result post() {
Form<PostParam> form = Form.form(PostParam.class).bindFromRequest();
PostParam query = form.get();
return ok(query.name);
}
public static class PostParam {
public String name;
}
}}
* 外部プロジェクト [#xcb5db4a]
eclipse でプロジェクト参照しても activator 側で認識できない。
''build.sbt''
lazy val PlayUtil = RootProject(file("../PlayUtil"))
lazy val root = (project in file(".")).enablePlugins(PlayJava,PlayEbean).dependsOn(PlayUtil)
activator eclipse
※ 注意: 参照される側のプロジェクトが単なるライブラリ的な存在の場合は application.conf が上書きで読み込まれるため消しておいたほうが良い
----
* cron [#n8cdf7e0]
''build.sbt''
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
libraryDependencies += "com.typesafe.akka" % "akka-remote_2.11" % "2.3.13"
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.11" % "2.3.13"
libraryDependencies += "com.typesafe.akka" % "akka-kernel_2.11" % "2.3.13"
libraryDependencies += "com.enragedginger" % "akka-quartz-scheduler_2.11" % "1.4.0-akka-2.3.x"
これだけだと scala-library の部分が eclipse に認識されない。~
今のところ手動で activator eclipse した後に、追加しているけれど・・
<classpathentry kind="lib" path="scala-library-2.11.5.jar"/>
''application.conf''
#pre{{
akka {
quartz {
schedules {
EveryMM {
description = "毎分"
expression = "0 * * ? * *"
timezone = "Asia/Tokyo"
}
}
}
}
}}
''actors/MinutelyActor.java''
#pre{{
public class MinutelyActor extends UntypedActor implements VelocityController {
@Override
public void onReceive(Object arg0) throws Exception {
Logger.debug("CRON MINUTERY: " + new Unixtime().format("yyyy-MM-dd HH:mm"));
//do something
}
}
}}
''Global.java''
#pre{{
try{
ActorSystem system = ActorSystem.create("system");
try{
ActorRef ref = system.actorOf(Props.create(MinutelyActor.class), "MinutelyActor");
QuartzSchedulerExtension scheduler = (QuartzSchedulerExtension) QuartzSchedulerExtension.get(system);
scheduler.schedule("EveryMM", ref, "minutely");
}catch(Exception e){
}
}catch(Exception e){
}
}}
----
* web socket [#ke80f94d]
actor を使うので、build.sbt 等は上記の cron と同じ設定を行う。~
''conf/routes''
GET /connect controllers.SocketController.socket
GET /send controllers.SocketController.send(message)
''controllers/SocketController.java''
#pre{{
public class SocketController extends Controller {
public WebSocket<String> socket() {
return WebSocket.withActor(WebSocketActor::props);
}
public Result send(String message) {
WebSocketActor.members.forEach(a -> a.send(message));
return ok("OK");
}
}
}}
''actors/WebSocketActor.java''
#pre{{
public class WebSocketActor extends UntypedActor {
private final ActorRef out;
public static List<WebSocketActor> members = new ArrayList<WebSocketActor>();
public static Props props(ActorRef out) {
return Props.create(WebSocketActor.class, out);
}
public WebSocketActor(ActorRef out) {
this.out = out;
members.add(this);
}
@Override
public void onReceive(Object arg0) throws Exception {
System.out.println(arg0);
}
@Override
public void postStop() throws Exception {
members.remove(this);
System.out.println("bye");
}
public void send(String message) {
out.tell(message, self());
}
}
}}
*** test [#m81f6524]
http://websocket.org/echo.html
ws://localhost:9000/connect
----
* ebean [#e96f1559]
*** relation系 [#c074afc8]
|OneToOne |public String |cascade 使用すると子オブジェクトは親に従属|
|OneToMany |public String[] |cascade 使用すると子配列は親に従属 |
|ManyToOne |public String |cascade は使用しない。子を保存する場合は子側で保存|
|ManyToMany|public String[] |cascade は使用しない。子配列を保存する場合は子側で保存|
*** date [#lc1a9121]
form からテキストで入ってきた date string を Date 型にする場合
''import play.data.format.Formats;''
@DateTime(pattern = "yyyy/MM/dd")
public Date date;
*** validate系 [#eddec6b0]
''import play.data.validation.Constaints;''
|@Required |必須 |
|@Email |email 型 |
|@MaxLength |最大長 |
|@MinLength |最小長 |
|@NotNull |必須 |
*** DB系 [#i8b58755]
|@Table |実際のDB上のテーブル名を指定できる |
|@SerializedName |実際の DB上の field 名を指定できる |
|@Entity |Model として認識するために必要 |
|@MappedSuperclass|モデルの super class に作る。このモデルはテーブルを作らない|
|@Transient |DB にフィールドを作らない(一時計算用のフィールド等) |
|@Column |DBに実際作られるフィールド (columnDefinition = "text") で256文字より長い文字 |
*** 前処理系 [#l9b373e6]
|@PostLoad |select の後に呼ばれる callback|
|@PrePersist|insert の前に呼ばれる callback|
|@PreUpdate |update の前に呼ばれる callback|
|@PreRemove |delete の前に呼ばれる callback|
*** 基本フィールド [#n81e7ea5]
|@Id |ユニークな値の方針を決めたりできる|
|@CreatedTimestamp|作成日が自動挿入される |
|@UpdatedTimestamp|更新日が自動挿入される |
* トラブルシュート [#c279c626]
*** https/http [#o29ae0a9]
play.core.server.netty.PlayDefaultUpstreamHandler - Exception caught in Netty
-【原因】httpsの設定をしていないのに htpps でアクセスした
-【対応】http でアクセスする
*** memory [#c9217499]
java.lang.OutOfMemoryError: Java heap space
-【原因】java に割り当てているメモリが足りない
-【対応】起動スクリプトに下記パラメータを追加する(dist環境)
bin/【appname】 -J-Xmx4096M -J-Xms2048
----
* deploy [#q51bfec2]
useradd sample
mkdir /var/log/sample
chown sample.sample /var/log/sample
''/etc/logrotate.d/sample''
#pre{{
/var/log/sample/sample.log {
weekly
dateext
missingok
rotate 52
compress
delaycompress
copytruncate
notifempty
sharedscripts
}
}}
su sample
cd
ln -s /var/log/sample logs
cat > ~/.emacs
(setq make-backup-files nil)
(setq auto-save-default nil)
cp sample-1.0-SNAPSHOT.zip ~/
''~/server.conf''
#pre{{
play.crypto.secret="sample"
# postgres
db.default.driver=org.postgresql.Driver
db.default.url="jdbc:postgresql://localhost:5432/sample"
db.default.username="sample"
db.default.password="sample"
ebean.default=["models.*"]
play.http.session.secure=false
}}
''~/deploy.sh''
#pre{{
#!/usr/bin/bash
BIN=sample
APP=${BIN}-1.0-SNAPSHOT
DB=sample
STAMP=`date '+%y%m%d%H%M'`
USER=sample
ps -auxww |grep java |grep ${APP} |awk '{print $2;}' |xargs kill -9 2>/dev/null
rm -rf ${APP}/RUNNING_PID
cp -rf ${APP}/conf backup/conf.bak.${STAMP}
rm -rf ${APP}
cp ${APP}.zip ./backup/${APP}.zip.${STAMP}
cp /home/${USER}/${APP}.zip ./
unzip ${APP}.zip
rm -rf ${APP}/share
rm -rf ${APP}/conf/files
cp -rfp conf/files ${APP}/conf
cp server.conf ${APP}/conf/
cd ${APP}
bin/${BIN} \
-J-Xmx2048M -J-Xms2048M \
-Djava.net.preferIPv4Stack=true \
-Dhttp.port=9000 \
-Dplay.evolutions.db.default.autoApply=true \
-Dfile.encoding=UTF-8 >> /var/log/${DB}/${DB}.log 2>&1 &
tail -f /var/log/${DB}/${DB}.log
}}
chmod +x deploy.sh
*** database [#c587a06a]
createuser -U postgres sample
psql -U postgres -c "alter role sample with password 'sample';"
psql -U postgres -c "create database sample;"
psql -U postgres sample -c "create extension postgis;"
psql -U postgres -c "alter database sample owner to sample;"
|
|||||||||