4

Play Framework 1 had a great feature where directly assigning a value to a model property was automatically translated into a function call at runtime. Here are the docs. For example

model.fullname = "John Smith";

would automatically be converted into this under the hood:

model.setFullname("John Smith");

Does the same feature exist in Play Framework 2?

Is it documented anywhere?

Here is a sample java project where I tried to get the feature working in Play 2.1.1. It shows that the getters and setters are being created but that the client byte code isn't being rewritten to call the generated getters and setters.

KevSheedy
  • 3,195
  • 4
  • 22
  • 26
  • BTW, in Play 1, if I remember right that was done by Project Lombok : http://projectlombok.org/ – i.am.michiel May 21 '13 at 07:12
  • Thanks Michiel. I searched through the Play Codebase and couldn't find any reference to Lombok, but the behaviour does sound similar. It looks like the [PropertiesEnhancer.java](https://github.com/playframework/Play20/blob/master/framework/src/sbt-link/src/main/java/play/core/enhancers/PropertiesEnhancer.java) is creating the getters and setters. I'm not sure if this class is any relation to Lombok? – KevSheedy May 21 '13 at 11:20

2 Answers2

4

Here's an excerpt from the book: Play For Java


Play uses a cool trick called ‘byte code enhancement’ to add getters and setters right after your original code is compiled, and then silently rewrites all your client byte code to use the generated getters and setters. However, if you change from field access to getter/setters, or the other way around, you'll find your code no longer compiles. This is because the bytecode enhancement takes place after your class is compiled, which means it has to actually compile first.


Did you change field access to getter/setter, or the other way around?

Mingyu
  • 31,751
  • 14
  • 55
  • 60
  • Thanks Mingyu. That's exactly the behaviour I'm trying to get but it doesn't work for me. I've included a link to a [Sample Project](https://github.com/KevinSheedy/PlayGetSet) that shows the getters and setters are being created but that they aren't being called. Would you mind having a look to see if it works for you? Thanks – KevSheedy May 21 '13 at 11:25
0

I am using Play 2.1.0 and getters/setters generation(at a runtime) works for me. In my "target" directory, in classes I can see getter/setter method for all my fields. It is not generating getters/setters only if you already have them in your class. Can you post what in the compiled MyModel.class for you example?

Jas
  • 5
  • 2
  • 1
    Hi Jas. I updated the question to include a link to my [sample project](https://github.com/KevinSheedy/PlayGetSet). It shows that the getters and setters are being created but that they aren't being called. Would you mind having a look and seeing if it works for you? Thanks – KevSheedy May 21 '13 at 11:23
  • I have just compiled your example. Go to PlayGetSet-master\target\scala-2.10\classes\models\MyModel.class I can see all getter/setters there. but my Play is one subversion behind you. I don't know if it's matters or not. – Jas May 21 '13 at 23:15
  • Thanks Jas. Yes, the getter/setters are being created. My problem is that they aren't being called. When you run the example, are the getters/setters being called for you? You will see some log statements in the console if they are being called eg `System.out.println("inside getFirstName()");`. Thanks, Kev – KevSheedy May 22 '13 at 09:01
  • You can't directly call gettters/setters. you need to call .firstName field instead and the Play will take care about the rest.[link]http://www.playframework.com/documentation/1.2.3/model[link].Here you can see the following warning : Warning! You can’t directly use getter and setter methods to access properties if you rely on automatic generation. These methods are generated at runtime. So if you reference them in code you write, the compiler won’t find the methods and will generate an error. – Jas May 22 '13 at 17:22
  • Thanks Jas. In my example, I'm doing direct assignment like you said eg `

    @myModel.lastName

    `, and Play is supposed to take care of the rest ie converting this into a getter call. My problem is that Play is not doing this conversion. I put a log statement into the getter to see if it was being called eg `System.out.println("inside getFirstName()");`. I don't see these log statements in my console. Do you? Thanks
    – KevSheedy May 23 '13 at 11:02