Wednesday, March 08, 2017

View.html.index cannot be resolved to a type

If your play project in eclipse says that it can't resolve a type (see message below), but you are certain that everything should be fine
$ View.html.index cannot be resolved to a type
try to make a clean compile
$ activator clean compile eclipse
It helped me to resolve my issue.

Thursday, January 12, 2017

Kill Play Framework process

When we run application in DEV mode (using command activator run) the process normally will be killed when terminal is closed. It's pretty easy since PID is started/closed automatically and therefore we do not care about it at all.
Once we start application in PROD mode there is a file RUNNING_PID is created (./target/universal/stage/RUNNING_PID). There is a command (since version 2.4) in activator (stopProd) which will close PID
$ activator stopProd
Alternatively you can just kill process 'manually'
$ kill $(cat target/universal/stage/RUNNING_PID)

Play Framework project in production - Building process

We want to deploy our Play project to production environment.

Create a binary version of application

There are two commands that can help you to make a build. Simply run dist (it invokes universal:packageBin) or universal:packageZipTarball in Play console and wait
$ dist
$ universal:packageZipTarball
Result will be a ZIP or TGZ file located in target/universal folder with everything needed for you project (it means you do not need to install SBT or Activator on your server, just pure Java). Once you extract ZIP you will find 2 runner files in bin folder (one for unix and one for windows). Just run it and your server will up
$ path/to/hellow-world/bin/hello-world-app 
[info] play.api.Play - Application started (Prod)
[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
Make sure you have rights to run server, sometimes you need to give rights (see example below)
$ chmod +x /path/to/bin/project-name
To run process in background
$ sudo nohup target/universal/stage/bin/eqa-app -Dhttp.port=80 -Dplay.crypto.secret="secret_token_123" /dev/null 2>&1 &

Play Framework project in production - Application Secret

I am going to make series of articles about how to deploy Play Framework (version 2.5) application on centOS together with build system Jenkins. I'm doing this first time and want to document everything for myself and at the same time I hope it can be useful for somebody else as well.

Before I wrote few articles how to setup hello-world project on centOS or macOS however now I'm going to work on production setup. I assume you already have you hello-world project and clean centOS environment.

Let's have a look on important moment.

Application secret


Each play application has secret key which is used for signing session and some other important stuff. It is not possible to run play project in production mode in case if secret is not set or if it is set to default value 'changeme'. Secret key is stored in application.conf file /path/to/hello-word/conf/application.conf in variable play.crypto.secret (see below).
## Secret key
# http://www.playframework.com/documentation/latest/ApplicationSecret
# ~~~~~
# The secret key is used to sign Play's session cookie.
# This must be changed for production, but we don't recommend you change it in this file.
play.crypto.secret = "changeme"
Of course we should not share our secret key and therefore it has to be used/stored on production side only.

There are at least 3 ways how we can use secret key on production side.

1. Secret key as a parameter

It is fine if you have simple application on 1 server, but I would not really recommend that for bigger project.
/path/to/hello-world -Dplay.crypto.secret="secret_token_123"

2. Environment variables

That would read variable from OS environment, otherwise default value will be used (actually the last defined one, in example below it is "chagneme").
play.crypto.secret="changeme"
play.crypto.secret=${?APPLICATION_SECRET}

3. Use separate configuration file

Separate configuration is probably the best way to go.
include "application"
play.crypto.secret="QCY?tAnfk?aZ?iwrNwnxIlR6CTf:G3gf:90Latabg@5241AB`R5W:1uDFN];Ik@n"
They include config while running application.
/path/to/hello-word/bin/yourapp -Dconfig.file=/path/to/production.conf

Secret tools

There are few already builtin function that can help you deal with secrets: playGenerateSecret (generate secret) and playUpdateSecret (generate and update into config).
$ playGenerateSecret
[info] Generated new secret: G28Dze]Z4lr@Or_9DCoz;tT_yCj6opKkkIh27K>[0l_NT9lZaFfs?=zx[Wulz>cX
[success] Total time: 0 s, completed Jan 11, 2017 6:24:12 PM
$ playUpdateSecret
[info] Generated new secret: QmJ?udauJgDj34AYifbprJvbT5I8^Vw1MY0WmbYRscZmAOotkalbhXbIs^48_Uc9
[info] Updating application secret in /Users/dpa/git/eqa-app/conf/application.conf
[info] Replacing old application secret: changeme
[success] Total time: 0 s, completed Jan 11, 2017 9:22:06 PM

Sunday, December 25, 2016

HTTP Routing in Play Framework

We are going to check how Play connect http requests with our code. F.x. when user hits http://localhost:9000/ what happens?

HTTP Routing

There is already built in http router in Play Framework. It allows to connect incoming requests with Play Action and therefore with public method in a controller class.

Configuring HTTP Routing

Normally the configuration for HTTP routing is located in conf/routes. See example:

# Static path
GET   /clients/all                  controllers.Clients.list()
# Dynamic path
GET   /clients/:id                  controllers.Clients.show(id: Long)
GET   /files/*name               controllers.Application.download(name)
# Dynamic parts with regexp
GET   /items/$id<[0-9]+>    controllers.Items.show(id: Long)

If there are few routes are matched for the same request then the first one in a configuration file will be used.