poornerd

my thoughts on programming and other nerdy stuff

December 6, 2013
by poornerd
1 Comment

How to run a Play Framework Application in Tomcat or JBoss

So you have written an application using Play! Framework 2.x and your System Administrator tells you that he won’t install Play! and that your application needs to run in a supported Java Servlet Container like JBoss, Tomcat or Glassfish?

No worries, you can use the play2-war-plugin to create a WAR file which can be deployed in a Java Servlet 2.5 or 2.3 spec Servlet Container!

Here is the Quick Guide for 2.1.x (mainly from stackoverflow):

  1. Within plugins.sbt add:
    addSbtPlugin("com.github.play2war" % "play2-war-plugin" % "1.1.1")

    According to the project web page, you will need to pick the correct Version for you Play! Framework version:

        Play 2.0 -> 2.0.4 : 0.8.1
        Play 2.0.5+       : 0.8.2
        Play 2.1 -> 2.1.3 : 1.0.1
        Play 2.1.4+       : 1.1.1
        Play 2.2.x        : 1.2-beta1 (unstable)
    
  2. Then within the Build.scala file add:
    import com.github.play2war.plugin._
    ...
    .settings(Play2WarPlugin.play2WarSettings: _*)
    .settings(Play2WarKeys.servletVersion := "X.X")
    

    The X.X needs to be changed to the required Java Servlet version (usually 3.0 or 2.5 depending on your container)

If you are using Play! Framework 2.2 then you can also try this method without the Plugin, just using sbt http://play2war.blogspot.in.

If you have read this far, you may as well follow me on Twitter:

October 22, 2013
by poornerd
0 comments

Crowd Dialog: Crowdfunding Conference 2013

Screen Shot 2013-10-22 at 15.10.12
Some of you have noticed that I have not published much recently.  In addition to my day-job, I have been organizing a Crowd Funding conference for Startups and Companies that want to use Crowdfunding to finance new products.  The Crowd Dialog Conference is on Nov. 21 in Munich, Germany if you are interested in coming.

If you have read this far, you may as well follow me on Twitter:

July 25, 2013
by poornerd
3 Comments

How to set the Java Version for Compiling a Play Framework Module

@jaliss and I were recently wondering how to make sure that a module was compiled with JSDK 1.6 after we had upgraded the Java Version on our Macbooks.

Stackoverflow user mgregori just provided this solution (Thanks!):

In the file project/Build.scala, add the setting below if you want to compile with java 1.6 :

val main = play.Project(appName, appVersion, appDependencies).settings(
  // Force compilation in java 1.6
  javacOptions in Compile ++= Seq("-source", "1.6", "-target", "1.6")
)
If you have read this far, you may as well follow me on Twitter:

July 5, 2013
by poornerd
4 Comments

How to integrate Concordion in Play Framework and write acceptance tests in natural language

Screen Shot 2013-07-05 at 10.24.25After starting to read “Specification by Example”, I wanted to have a go a writing acceptance tests for my Play Framework projects.  I stumbled onto Concordion (http://www.concordion.org/), because it is similar to Cucumber but written in and for Java.

Concordion is similar to Cucumber but focuses on readability.

Concordion integrates as Unit tests (which is the primary focus of this post), and lets you write the Tests in Natural Language in HTML Files so that it also becomes self documenting.

I got most of how to integrate Concordion from Craig Aspinall in Australia (@aspinall) who had written a Blog post about it, but which was no long “online”.   (he sent me a link to the markdown so I could try it out – thank Craig!)

Integrating Concordion

You first need to add the dependency to your Build.scala, and then add a line so that the SBT copies the Concordion HTML files:

import sbt._
import Keys._
import play.Project._

object ApplicationBuild extends Build {

    val appName         = "computer-database"
    val appVersion      = "1.0"

    val appDependencies = Seq(
       "org.concordion" % "concordion" % "1.4.2" % "test"  ,
      javaCore,
      javaJdbc,
      javaEbean
    )

    val main = play.Project(appName, appVersion, appDependencies).settings(
      // Next, you need to instruct SBT to copy the Concordion HTML files to the target folder
        unmanagedClasspath in Test <+= (baseDirectory) map { bd => Attributed.blank(bd / "test") }
    )
}

Telling Play where to output the Test results to

This turned out to be a challenge. If you do not set the concordion.output.dir system property, then they are outputed to your Java temp directory. Craig suggested setting it in the Build.scala, but as it turns out the most recent Version of Play forks the Tests into a separate process and loses the setting. So I ended up adding this to my Global Settings class:

import play.Application;
import play.GlobalSettings;
public class Global extends GlobalSettings {

    public void onStart(play.Application arg0) {
        if (arg0.isTest())
            System.setProperty("concordion.output.dir", "target/test-reports/concordion");
    }

}

Note: I think I discovered another Bug in Play, because although this works, if I run “test-only” it doesn’t!!!

The Test

The key to getting Play to recognize and run Unit Tests is the @Test annotation, so it seems that the easiest way to get Play to run the Concordion tests is to add a method like this to your Concordion fixture class:

    @Test
    public void runThisTest() {
    }

I ended up implementing one of the tutorial examples from here: http://www.concordion.org/Tutorial.html

You write the test case in HTML, and use <span> tags with Concordion elements to specify the paramters and assertions:

<html xmlns:concordion="http://www.concordion.org/2007/concordion">

    <head>
        <link href="../concordion.css" rel="stylesheet" type="text/css" />
    </head>

    <body>

        <h1>Splitting Names</h1>

        <p>
            To help personalise our mailshots we want to have the first name
            and last name of the customer. Unfortunately the customer data
            that we are supplied only contains full names.
        </p>

        <p>
            The system therefore attempts to break a supplied full name into
            its constituents by splitting around whitespace.
        </p>

        <div class="example">

            <h3>Example</h3>

            <p>
                The full name
                <span concordion:execute="#result = split(#TEXT)">John Smith</span>
                will be broken into first name
                <span concordion:assertEquals="#result.firstName">John</span>
                and last name
                <span concordion:assertEquals="#result.lastName">Smith</span>.
            </p>

        </div>
    </body>
</html>

Then you write a fixture class with the Tests (and the @Test “hack” I mentioned).

import org.junit.Test;
import play.mvc.Result;

import java.util.HashMap;
import java.util.Map;

import static org.fest.assertions.Assertions.assertThat;
import static play.test.Helpers.*;

import org.concordion.integration.junit4.ConcordionRunner;
import org.junit.runner.RunWith;
import org.junit.Test;

@RunWith(ConcordionRunner.class)
public class ConcordianTestFixture {

    public Result split(String fullName) {
        Result result = new Result();
        String[] words = fullName.split(" ");
        result.firstName = words[0];
        result.lastName = words[1];
        return result;
    }

    class Result {
        public String firstName;
        public String lastName;
    }

    @Test
    public void runThisTest() {
    }
}

When you run the tests, then the resulting HTML page it outputed (as previously defined) to your target/test-reports directory. Here is an example of a failed test (for a successful one, see the image at the start of the post):

Screen Shot 2013-07-05 at 10.30.39

I hope you try this out!  Let me know if you have more ideas or tips…

If you have read this far, you may as well follow me on Twitter:

June 27, 2013
by poornerd
0 comments

How to use Reflection to Document your Data Model based on JPA Annotations

annotation_reflectionSo using JPA, Hibernate or EBeans is cool when you can just annotate your Java classes, but haven’t you always wished you could “generate” documentation of your data model from the code? Pulling information of the the JPA / Hibernate  and other validation annotations?

Assuming you have all those nice Annotations in your beans:

@Entity
@Table(name = "project_bills")
public class Bill extends Model {
	
	private static final long serialVersionUID = 1L;

	@Id
	@Column(name="PBI_ID")
	public Long id;
	
	@DoubleFormat
	@Column(name="PBI_BILL_AMOUNT",length=22)
	public Double billAmount;
	
	@Column(name="PBI_BILL_DATE")
	@DateTime(pattern="dd.MM.yyyy")
	public Date billDate;
	
	@Column(name="PBI_BILL_NUMBER",length=10)
	public String billNumber;
	
	@Column(name="PBI_CAN_BILL")
	public Boolean canBill;
	
	@Column(name="PBI_COMMENT",length=65535)
	public String comment;
	
	@Column(name="PBI_PAID_DATE")
	@DateTime(pattern="dd.MM.yyyy")
	public Date paidDate;

 

Here is an example of how to go about accomplishing that task:

    public static String listEntities(String _package) {
        StringBuffer retval = new StringBuffer();
        Reflections reflections = new Reflections(_package, Play.application().classloader());
        Set<Class<?>> classes = reflections.getTypesAnnotatedWith(javax.persistence.Entity.class);
        for (Class c : classes) {
            retval.append(c.getName() + "\n");
            retval.append(listAnnotations(c.getName()) + "\n\n");
            retval.append(listAttributes(c.getName()) + "\n\n");
        }
        return retval.toString();
    }

    public static String listAnnotations(String _class) {
        StringBuffer retval = new StringBuffer();
        try {
            Annotation[] annotations = Class.forName(_class).getAnnotations();
            if (annotations.length != 0) {
                for (int j = 0; j < annotations.length; j++) {
                    retval.append(annotations[j].toString() + ": " + annotations[j].annotationType() + "\n");
                }
                retval.append("\n");
            }
        } catch (ClassNotFoundException e) {
            System.out.println(e.toString());
            return retval.toString();
        }
        return retval.toString();
    }

    public static String listAttributes(String _class) {
        StringBuffer retval2 = new StringBuffer();
        boolean perstistent = false;
        try {
            for (Field field : Class.forName(_class).getDeclaredFields()) {
                Class type = field.getType();
                String name = field.getName();
                perstistent = false;
                StringBuffer retval = new StringBuffer();
                retval.append("\t" + name + " (" + type + ")\n");
                Annotation[] annotations = field.getDeclaredAnnotations();

                if (annotations.length != 0) {
                    for (int j = 0; j < annotations.length; j++) {
                        retval.append(annotations[j].toString() + ": " + annotations[j].annotationType() + "\n");
                        if (annotations[j].toString().startsWith("@javax.persistence")) {
                            perstistent = true;
                        }
                    }
                    retval.append("\n");
                }
                if (perstistent) {
                    retval2.append(retval);
                }
            }
        } catch (ClassNotFoundException e) {
            System.out.println(e.toString());
            return retval2.toString();
        }
        return retval2.toString();
    }

Which will generate something like this:

models.controlling.Bill
@javax.persistence.Table(schema=, uniqueConstraints=[], catalog=, name=project_bills): interface javax.persistence.Table
@javax.persistence.Entity(name=): interface javax.persistence.Entity

	id (class java.lang.Long)
@javax.persistence.Id(): interface javax.persistence.Id
@javax.persistence.Column(insertable=true, scale=0, unique=false, precision=0, columnDefinition=, name=PBI_ID, updatable=true, length=255, nullable=true, table=): interface javax.persistence.Column

	billAmount (class java.lang.Double)
@utils.data.formatters.Formats$DoubleFormat(): interface utils.data.formatters.Formats$DoubleFormat
@javax.persistence.Column(insertable=true, scale=0, unique=false, precision=0, columnDefinition=, name=PBI_BILL_AMOUNT, updatable=true, length=22, nullable=true, table=): interface javax.persistence.Column

	billDate (class java.util.Date)
@javax.persistence.Column(insertable=true, scale=0, unique=false, precision=0, columnDefinition=, name=PBI_BILL_DATE, updatable=true, length=255, nullable=true, table=): interface javax.persistence.Column
@play.data.format.Formats$DateTime(pattern=dd.MM.yyyy): interface play.data.format.Formats$DateTime

	billNumber (class java.lang.String)
@javax.persistence.Column(insertable=true, scale=0, unique=false, precision=0, columnDefinition=, name=PBI_BILL_NUMBER, updatable=true, length=10, nullable=true, table=): interface javax.persistence.Column

Of course this is only the tip of the iceberg, but you get the idea.

Let me know if you have some good ideas of what other types of documentation can be generated from the source code.

If you have read this far, you may as well follow me on Twitter:

June 19, 2013
by poornerd
1 Comment

How to compile and use a Play Framework 2 module with the source from github

Screen Shot 2013-06-19 at 16.30.25Have you ever wanted to download the source of a Play Framework 2.0 module off of github and modify the source and test it?  Or have you expected it to be in some repository but for one reason or another it wasn’t there?

I have found myself in this situation a few time recently and had to piece this together…

  1. Download the code from github (or where ever) – of course you can fork it, or check it out with git, but you can also just download the ZIP file
  2. Switch to the module directory and run play clean , then play publish-local

Once you have done this, it is in you local repository, so you can remove the repository from your Build.scala if you added one.

Just remember that it is in your local repository so you will need to remove it if you want to revert back to a Version from the repository in the internet!

If you have read this far, you may as well follow me on Twitter:

May 29, 2013
by poornerd
0 comments

Play Framework Tip for developing offline

Screen Shot 2013-05-29 at 08.58.00This ended up being a useful tip from James Roper (@jroper) that I used recently when I was on vacation:

from a Twitter Post:

“Developing a Play app on a plane pro-tip: add offline := true to plugins.sbt”

Just make sure you have all your dependencies updated before you set this option!

If you have read this far, you may as well follow me on Twitter:

May 15, 2013
by poornerd
0 comments

Proof that Java, Scala and Play! Framework Developers do NOT use Internet Explorer!

browser_statsI was (almost) shocked when I looked at the statistics of which Browsers are being used to access my blog. In absolute numbers Internet Explorer ends up being about 1%. Webkit is almost 75% if you add Chrome + Safari + Mobile Safari. Even Mobile Safari is used more than Internet Exploder (sic)!

I am basing this on Google Analytics, and the fact that 90% of what I blog about is Play! Framework, or Java related.

If you have read this far, you may as well follow me on Twitter:

May 13, 2013
by poornerd
1 Comment

How to spend less time waiting for Play! Framework to compile while coding

A colleague just pointed this cool tip out to me:

play ~run

If you enter “play help“, it says: “~ Executes the specified command whenever source files change.

So what this does – and how it saves you time – is: it compiles when you save, so that by the time you hit reload in the browser, if you are lucky, it will have already compiled.

This saves me a few seconds each time I switch to the browser to check out my most recent changes.

If you have read this far, you may as well follow me on Twitter:

May 8, 2013
by poornerd
2 Comments

How to Edit Messages in the Browser While Developing Play! Framework Templates

As a followup to my recent experiments to inline editing of content blocks while developing Play! Framework templates, I decided to focus on Messages this week.  Messages are basically Resource Bundles with Texts to be used in the Application.

This is what I wanted to accomplish:

  1. No changes required to the Play! Framework Scala Templates
  2. Use an inline HTML5 editor to edit the messages directly in the rendered template in the browser
  3. Save (update) the message file directly in the conf directory of the application

I modified my play-aloha project on github (https://github.com/poornerd/play-aloha ) for the first requirement, by adding a Messages template, so that the typical @Messages("label.title") tags used in the templates would be rendered by my tag instead.  If the play-aloha.admin=true is set in the application.conf, then the Messages.scala.html template renders a <span> around the message with an id that contains "message." + the key of the message.

@(key:String)
@if(Application.isAlohaOn()) {
  <span id="message.@key" class="editable">
}
  @play.api.i18n.Messages(key)
@if(Application.isAlohaOn()) {
  </span>
}

I also added the class="editable" so that the Aloha Editor which I already integrated into the project would automatically make the <span> editable.

So for example this code in the template would make the messages with the given keys editable:

<h2 class="featurette-heading">
  @Messages("label.featurette1") 
  <span class="muted">@Messages("label.featurette1Mute")</span>
</h2>

message-editing

 

In the controller method which handles saving the edited content from the Aloha Editor via an AJAX Request, I check the id to see if it starts with "message.".

        if (contentId.startsWith("message.")) {
            // save as message
            saveMessages(contentId.substring(8), content);
        } else {
            // save in Template
            if (templateFilename != null) {
                saveToTemplate(fullTemplateFilename, pageId, contentId, content);
            }
        }

If it does, then I use the rest of the id (which is the message) key, to lookup and save the new message in the messages file.

#test
label.featurette1Mute=Google is cool!
label.featurette1=Chrome
If you have read this far, you may as well follow me on Twitter: