Wednesday, October 30, 2013

Running Play 2.1.x App as Windows Service (Fat Free Version)

In this post, I'll show you how to run your Play 2.1.x app silently as a background service and give you a couple tools you can use to ease the administration process for your app. All of this without the use of third party tools.

For this tutorial we will use the Zentasks sample application that came bundled with the framework. This tutorial assumes that:

  • The zentasks project folder is located in C:\apps\zentasks
  • The Java executable is located at C:\Program Files\Java\jdk1.7.0_25\bin\

Adjust these directories to suit your needs. Let's get started.

The Problem

You have several apps that you need to deploy in a production Windows environment, but you hate having the pesky command prompt window visible in the background when you run play start for each application. You want your apps to run silently as Windows services on startup.

The Solution

Create a standalone distribution of your app by opening a command window and running

cd c:\apps\zentasks
play clean dist

In the dist folder of the application directory, you should see an archive named Extract the contents of that archive to the current folder.

In my case the location of my app is C:\apps\zentasks and the location of the folder I just extracted from the archive is C:\apps\zentasks\dis\zentasks-1.0-SNAPSHOT.

To run my app invisibly, I take advantage of the javaw.exe application bundled with my Java installation. This file does exactly what java.exe does but it does it in the background without showing a console window.

Note before continuing: Either turn off evolutions or set them to automatic in the application.conf file. You can do that by following the example here. Once that's done, run play dist again.

In a command prompt window I then run the following commands:
cd c:\apps\zentasks\dist\zentasks-1.0-SNAPSHOT
javaw -cp lib\* play.core.server.NettyServer

You'll notice that the command runs and returns you to the command prompt. Give it a couple seconds and go to http://locahost:9000 (or whatever port you set the app to run on) and see if your app is running. It should be.

Once you have that sorted out, let's move on. We're going to create two batch files for starting and stopping the application. Once these files are created we can also place them in the Startup folder on our Start menu to have them execute when Windows starts up.

Batch File #1: Start.bat

Open a Notepad document and paste in the following:
cd .
start "" "C:\Program Files\Java\jdk1.7.0_25\bin\javaw.exe" -cp lib\* play.core.server.NettyServer

Substitute the correct paths where necessary and save the file as start.bat in your application's dist\zentasks-1.0-SNAPSHOT directory.

To test the file, open task manager and kill the javaw.exe process,

then go to your application's dist\zentasks-1.0-SNAPSHOT directory and delete the RUNNING_PID file. Now double-click start.bat, wait a couple seconds then go to http://localhost:9000 to check if your app is up. It should be.

Batch File #2: Stop.bat

If starting your app in production mode is now that easy, then stopping it should be too.

Again, open a new Notepad document and paste in the following:
set /p pid=<RUNNING_PID
taskkill /PID %pid% /F

That information goes on three separate lines. Save the file as stop.bat, place it in your app's dist\zentasks-1.0-SNAPSHOT directory and when you run it, it should kill the javaw process that your app is running on and delete the RUNNING_PID file as well. To ensure that your app has been shut down, go to http://localhost:9000 and observe that your app is down. At the end of it all your directory structure is supposed to look as follows:

* zentasks  
 *-- dist      
 *-- zentasks-1.0-SNAPSHOT          
 *-- lib          
 *-- RUNNING_PID          
 *-- start.bat          
 *-- stop.bat 

You can now take this folder and plop it down on your production server worry-free. Yay!


But what about my configuration options? What if I want to change the port that the application is running on?
 Simple. In start.bat include -Dhttp.port=xxxx or any other configuration options before the -cp argument. E.g:

start "" "C:\Program Files\Java\jdk1.7.0_25\bin\javaw.exe" -Dhttp.port=9001 -Dconfig.resource=prod.conf -cp ...

Is starting the application this way safe?
As far as I can tell, yes. The long and short of the story is that the command you place in the start.bat file is what is essentially run when you execute play start plus or minus a few directory and Java option changes. +James Ward and the +Play Framework team are free to correct me on this if I'm wrong.

Where will the logs and other necessary files be created? A directory for logs will be created in the dist\zentasks-1.0-SNAPSHOT folder and an application.log file will be placed there. File system h2 databases will be placed in the dist\zentasks-1.0-SNAPSHOT folder.

Where does the application read configuration items from in this mode?
In the lib directory of dist\zentasks-1.0-SNAPSHOT  there is a file named zentasks_2.10-1.0-SNAPSHOT.jar If you were to extract the contents of this file, you'd see all the evolutions and *.conf files your created up to the point in time you ran the play dist command.

I hope this was helpful to you. Thanks to +James Ward and the amazing +Play Framework team for all their hard work, and as always thank you for reading.
Post a Comment