Executing Play! from outside of Play! code

As I’ve said earlier, I think that the Play! framework is lovely. It makes it easy to develop and write code quickly. One of the ways that it enables this is through performing runtime byte code enhancement of the code. This makes execution of your code somewhat non-trivial when coming from a non-Play! context. Play! aims to meet all your needs, but use cases exist where it is important non-Play! code with Play! code, and have your non-Play! code call into Play!

Having said that this is non-trivial, it is reassuring to know that the process to do this is very straight forward.

  1. Create a subclass of play.Invoker.Invocation.
  2. Override the public void execute() method.
  3. Call the run() method of the invocation.
1
2
3
4
5
6
    Invoker.Invocation invocation = new Invoker.Invocation() {
        public void execute() {
            //do stuff with play here
        }
    };
    invocation.run();

With this simple snippet of code, it is possible to have non-Play! code easily and cleanly call your Play! application code.

Related posts:

  1. Eleven reasons to use the Play! Framework for Java Web Development
  2. The first test method
  3. Technique for getting JUnit tests to compile
  4. Fixing Intermittent Table Not Found Errors with JUnit when Using Hibernate SchemaExport and H2
  5. code snippit to Find the active Window in Swing
Tags: ,

4 Responses

  1. Sam Owen says:

    Which version on play have you tried this on? On play 1.0.2, when I try to use the byte-code enhanced JPA static helper methods on Model subclasses (count, all, find … etc) I get the following …

    Caused by: java.lang.UnsupportedOperationException: Please annotate your JPA model with @javax.persistence.Entity annotation.
    at play.db.jpa.JPASupport.find(JPASupport.java:395)
    at model.crud.IndexCRUD.testDeletingAnIndexRemovesAllIds(IndexCRUD.java:22)
    at model.crud.IndexCRUD.execute(IndexCRUD.java:15)
    at play.Invoker$Invocation.run(Invoker.java:176)
    … 16 more

    To make these work I had to get to jump through the following hoops (and run in prod mode):

    Play.classes.add(new ApplicationClasses.ApplicationClass(name));
    Class aClass = Play.classloader.loadClass(name);

    Method declaredMethod = Play.classloader.loadClass(Invoker.class.getName()).getDeclaredMethod(“invoke”, Invoker.Invocation.class);

    Future f = (Future) Java.invokeStatic(declaredMethod, new Object[]{(Invoker.Invocation) aClass.newInstance()});
    f.get();

    where name in the fully qualified name of the play invocation I want to run. Urg

  2. Rob says:

    ouch — I was going through an extra level of indirection — I had some code that called the enhanced code on the Play side — so was calling a method on an object that then called a method on the Model subclasses.

    so in my execute I was calling something like:

    persister.load(), and then within the load method code was calling play models.

  3. Lex says:

    Useful trick! As you feel that Play framework is lovely, I invite you to join at http://www.myplayforum.com, a new Play framework community See you soon! :)

  4. Joseph says:

    Hi guys!

    I’m working on a play project, and running into a couple of obstacles. To give a quick overview of the project, I have to deal real-time processes with user Interface handled by play. The work horse behind is Drools. I’m running into problems coupling the two elements. And I’m trying to run some play code of the box, mainly accessing models. Could be kind enough to give an example of to run these calls exactly.

    I seem to be missing a certain number of elements while launching the app. So a little insight on the usage of the code snippet would be much appreciated :)

    Cheers,
    Joseph

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© Rob@Rojotek