Migration to 2.6 from 2.5

793 views
Skip to first unread message

Gavin Baumanis

unread,
Mar 31, 2017, 6:48:19 PM3/31/17
to Play Framework
Hi Everyone,

I have a working application in play 2.5.x

And I have just tried to upgrade to the latest version 2.6-M3 and am having an issue, that for whatever reason I don't seem to be able to work out for myself.
(i am not the smartest guy in the Scala ecosystem... but I am certainly not the most useless either  - so I am a little frustrated and "not getting it".

[error] /Users/gavinbaumanis/workspace/emr/trunk/app/au/com/ecpr/emr/controllers/config/AppConfig.scala:142: could not find implicit value for parameter messages: play.api.i18n.Messages
[error]     Ok(au.com.ecpr.emr.views.html.config.appconfig(appConfigData, theDateTime.toString))

I have read through the migration guide and there is indeed a section about new treatment for internationalisation /  messages - but I can't seem to make it (the documentation) make enough sense to me to allow me to get my code to work.

Perhaps it is just a case of :
"inherent knowledge to the developers of Play allows the current state of the documentation to make perfect sense : no changes are necessary"
But without that inherent knowledge .... or perhaps I am, just, too stupid!....


Can someone in the know, please update the documentation, perhaps with something like this;
"
If you used the play-scala seed in 2.5 you need to change your code...

Remove this library it is no longer required
import XXXX


Add / replace with it this new one(s)
import YYY

because we altered the mechanics of AAAA and BBBB
Controller code in the 2.5 seed that looks like this;
xxxxxxx

You now need to change it to 
yyyyyyy


Lastly, if I may;
If such a thing doesn't already exist...
How about if I volunteer to loiter on the developer mailing list and as new things are discussed,
act like a documentation reviewer / editor 
and make sure the docs are appropriate for people "outside" of the inherent knowledge that committers, just, have.



Stephen Walsh

unread,
Apr 12, 2017, 5:40:56 AM4/12/17
to Play Framework
also facing this same issue :(

all worked from me on Play 2.5.10, but got this on 2.6.0-M1

Christian Schmitt

unread,
Apr 12, 2017, 6:05:27 AM4/12/17
to Play Framework
Should be fixed in 2.6.0-M4

Gavin Baumanis

unread,
Apr 30, 2017, 7:59:46 AM4/30/17
to Play Framework
Hi Christian,

I am getting the exact same error in 2.6.0-M5
Is there something else I should be doing?

Thanks

-Gavin.

Gavin Baumanis

unread,
May 6, 2017, 10:37:28 PM5/6/17
to Play Framework
Hi everyone,

I am still having issues with the same error, for over a month now.
And I am none the wiser as to whether or not I need to change something in my code 
(well I am sure that I need to change something because it works is Play 2.5 - but not in 2.6.

Or am I doing something weird enough that has something running awry in the framework?

From everything I have read i THINK I am doing things correctly.
Eg. Using MessagesAPI, not Messages
using the appropriate traits etc.

I have checked through the mailing list here and also through 
I have also looked through the templates, trying to find one that uses internationalisation and forms, to use as a guide: but I can't seem to find one.


Here is the error message that I am receiving;
controllers/config/AppConfig.scala:142: could not find implicit value for parameter messages: play.api.i18n.Messages
[error]     Ok(au.com.ecpr.emr.views.html.config.appconfig(appConfigData, theDateTime.toString))



Below is the start of the controller;
package au.com.ecpr.emr.controllers.config

import java.util.Date._
import javax.inject._

import scala.concurrent.{ ExecutionContext, Future }
import play.api._
import play.api.mvc._
import play.api.i18n._
import play.api.data.Form
import play.api.data.Forms._
import play.api.data.validation.Constraints._
import play.api.libs.json.Json
import au.com.ecpr.Utilities
import au.com.ecpr.emr.models.config.SystemUser

class AppConfig @Inject() (val messagesApi: MessagesApi)(implicit ec: ExecutionContext)
   
extends Controller
   
with I18nSupport {
...



And here is the method that is throwing the error (I had originally, made it as simple as possible - to still throw the error);

def appConfig = Action {
    val appConfigData
= appConfigForm.fill(CreateAppConfigForm("URL",
     
"subDomain",
     
"region",
     
AppModifiedByForm("GavinB",
       
"Gavin",
       
"Baumanis")))

    val utilities
= new au.com.ecpr.Utilities()
    val theDateTime
= utilities.dateTimeFormat_AU_now

   
// The line below is #142 - where the error is reported.
   
Ok(au.com.ecpr.emr.views.html.config.appconfig(appConfigData, theDateTime.toString))
 
} // End appconfig




Thanks in advance;
Gavin.

Greg Methvin

unread,
May 6, 2017, 11:16:25 PM5/6/17
to play-framework
Hi Gavin,

I'm not sure if this has to do with a change since 2.5.x, but the request2Messages implicit requires an implicit RequestHeader: https://github.com/playframework/playframework/blob/2.6.0-M5/framework/src/play/src/main/scala/play/api/i18n/I18nSupport.scala#L32.

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/b0c1747d-646c-415e-9cc6-9a51a68c16b0%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Greg Methvin
Tech Lead - Play Framework

Gavin Baumanis

unread,
May 7, 2017, 6:45:59 AM5/7/17
to Play Framework
Hi greg,

Firstly, 
Thanks for the reply.

I can see via your link that a request header is required to meet the requirements.
What I am unclear about - and what I can't seem to get any sense out of the docs about is
What do I need to do my code - to add this requirement?


Eg. I have had a look through the documentation at;

And I can't see that I am doing anything wrong .

I have also looked through;

Which gives the following code example and follow-up text;
import javax.inject.Inject
import play.api.i18n.I18nSupport


class MyController @Inject()(val messagesApi: MessagesApi)
extends Controller with I18nSupport {
// ...



The I18nSupport trait gives you an implicit Messages value as long as there is a Lang or a RequestHeader in the implicit scope.
Note: If you have a RequestHeader in the implicit scope, it will use the preferred language extracted from the Accept-Language header and matching one of the MessagesApi supported languages. You should add a Messages implicit parameter to your template like this: @()(implicit messages: Messages).
Note: Also, Play knows out of the box how to inject a MessagesApi value (that uses the DefaultMessagesApi implementation), so you can just annotate your controller with the @javax.inject.Inject annotation and let Play automatically wire the components for you.



SO...
my view code is supposed to have this?
@()(implicit messages: Messages).

and it does;
@(appConfigData : Form[au.com.ecpr.emr.controllers.config.CreateAppConfigForm],
     theDateTime
: String)(implicit messages : Messages)


and then;
Note: Also, Play knows out of the box how to inject a MessagesApi value (that uses the DefaultMessagesApi implementation), so you can just annotate your controller with the @javax.inject.Inject annotation and let Play automatically wire the components for you.


Awesome... but for the fact that when I add the annotation to the controller, I get a compilation error;
expected start of definition


Is there somewhere specific the annotation is supposed to go / or not go in the controller?
because I tried adding it before the class declaration and within the class declaration, too : and still get the same error.

So...
While the documentation tells you, you need a RequestHeader in scope : that's (sincerely) good to know - but where is the explanation of how to ensure that you have requirement covered off in your code?
Again - what he documentation lacks is a "complete" example of;
A form that uses messages / il8n for field labels, headings (perhaps), ...
A controller to handle the internationalised form.

(Or at least something like;
"See it in action here in this g8 template...
That you can get via xxxxxxx

I really don't want to sound like all I am doing is complaining.... because that's not correct.
I am more than happy to contribute to the documentation - but if I can't get the code to work - and since I don't (obviously) understand the requirements to get it to work.... then assisting is (currently) out of the question.

Gavin.

To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Will Sargent

unread,
May 7, 2017, 2:13:28 PM5/7/17
to play-fr...@googlegroups.com
You're looking at the 2.5.x documentation though, and you're doing the migration to 2.6.x.  

You want


Note the 2.6.x in the URL.


--
Will Sargent
Engineer, Lightbend, Inc.


To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/2b80f68b-3732-4a41-9009-f4da53af1a1e%40googlegroups.com.

Asa Zernik

unread,
May 7, 2017, 6:18:22 PM5/7/17
to Play Framework
Hi Gavin,

You can add the implicit RequestHeader (a superclass of Request) by creating a block with an implicit parameter; this propagates the implicit val available to the internal Action code down to your handler. Like so:
Action { implicit request =>

The perplexing question is why this ever worked; I think this behavior is the same as in 2.5. Unless there's an alternative deprecated I18nMessages API that doesn't use the implicits that you had to move away from?

Hope that helps,
Asa

Greg Methvin

unread,
May 7, 2017, 9:39:23 PM5/7/17
to play-framework
The annotation goes on the constructor, exactly as shown in the code example at the beginning of your email. The annotation is just needed to tell your runtime DI framework that an instance can be created by calling that constructor. There's nothing special here; this should be the same as in all the examples in the documentation, just with different constructor parameters.

If you're wiring your app using the cake pattern, you don't need the annotation since you're just calling the constructor (or Macwire figures it out), but even in that case it doesn't hurt to add the annotation.
 

So...
While the documentation tells you, you need a RequestHeader in scope : that's (sincerely) good to know - but where is the explanation of how to ensure that you have requirement covered off in your code?
Again - what he documentation lacks is a "complete" example of;
A form that uses messages / il8n for field labels, headings (perhaps), ...
A controller to handle the internationalised form.

Right. I believe every example where it's needed uses the Action { implicit request => ... } syntax which puts the request into implicit scope. This part could be better explained in the docs though.
 

(Or at least something like;
"See it in action here in this g8 template...
That you can get via xxxxxxx

You're right, more of the examples should probably include i18n, since that's a relatively common need.
 

I really don't want to sound like all I am doing is complaining.... because that's not correct.
I am more than happy to contribute to the documentation - but if I can't get the code to work - and since I don't (obviously) understand the requirements to get it to work.... then assisting is (currently) out of the question.

Perhaps we should modify the existing starter templates, e.g. https://github.com/playframework/play-scala-seed.g8, to include an example of i18n.
 
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/2b80f68b-3732-4a41-9009-f4da53af1a1e%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Greg Methvin

unread,
May 7, 2017, 9:47:20 PM5/7/17
to play-framework
I would like to know what code you had that worked in 2.5.x that doesn't work in 2.6.0-M5, though, since ideally the old code should be source-compatible, but with some parts deprecated. If something does completely break, the change should at least be mentioned prominently in the migration guide.

Will Sargent

unread,
May 8, 2017, 2:41:42 PM5/8/17
to play-fr...@googlegroups.com
The play-scala-seed.g8 template does have an example of using forms, but it's in the `g8Scaffold form` which provides scaffolding for forms.  

Probably the thing to do is to merge https://github.com/wsargent/play-forms-tutorial/ into play-scala-starter-template, or have an explicit forms example, such as https://github.com/ics-software-engineering/play-example-form.

I've filed a PR for making the i18nsupport implicit changes more explicit:






--
Will Sargent
Engineer, Lightbend, Inc.


On Sun, May 7, 2017 at 6:38 PM, Greg Methvin <gr...@lightbend.com> wrote:

Will Sargent

unread,
May 8, 2017, 7:20:17 PM5/8/17
to play-fr...@googlegroups.com
The problem with implicits in 2.5.x was that lang2Messages would resolve an implicit Lang from the Lang singleton object if there was no Lang in local scope, so you could have code like the following:

  def listWidgets = Action {
    // implicit lang from singleton object
    // implicit val implicitLang: Lang = play.api.i18n.Lang.defaultLang
    val lang = implicitly[Lang]
    
    // implicit messages in scope from implicit lang
    // val implicitMessages: Messages = lang2Messages(implicitLang)
    val messages = implicitly[Messages]
        
    // implicit parameter messages: Messages in listWidgets template, but no request!
    val content = views.html.listWidgets(widgets.toSeq, Application.createWidgetForm)
    Ok(content)
  }

So you could think you were getting the request's messages object... but you were really getting the application's messages object.  That loophole's gone in 2.6.x.


--
Will Sargent
Engineer, Lightbend, Inc.


Gavin Baumanis

unread,
May 8, 2017, 7:42:42 PM5/8/17
to play-framework
Hi Everyone,

Thanks to you all for your help.
Once Asa explicitly mentioned, you need THIS code, like this... the examples code made more sense.

For a reason that I can't explain... (especially since I have been learning Scala / Play /... by example : was to explicitly copy the line of code in the documentation.
I think, I just wasn't seeing it as "real" code, to use verbatim.


Documentation is ridiculously hard to make awesome. I sincerely appreciate the task that it is. The issue I find with documentation is that it is practically always written by the developer who wrote the code and the problem with that is;
* The developer has a deep understanding of the theory and what they're trying to achieve in the coded solution
* The developer inherently understands the code, already.
* Because of this innate understanding the developer sees the task / principal as easily understood.

The trick I find, IMHO is;
Write documentation so that it explains in the minimum word count, the theory to someone who is completely brand new to "this" today.
They have no previous experience with your product, your coding style. They have never seen a XXX widget in action before.
What do I need to explain to them so that they can create working code for themselves?
Back that up with example code (or 3) - and you've made documentation that is usable by everyone, forever.

These same rules should be applied to a migration guide, too.
Don't assume that the reader has a complete understanding of your work - just because they happen to have used the previous version.
Perhaps like me, they're learning by example...

E.g.
Copy / paste this work example code - changing / adding / removing field names from models / views / controllers - until you seemingly have a working application.
Absolutely no idea about any of the theory / the science / the engineering that sits behind the example...
just simply take a working example and hack on it until it does what you need.


Scala can be pretty obscure in places, making it, not so straight forward to successfully grok. and (once again, just my opinion) but the committers and the Lightbend staff have been using Scala and the frameworks for so long now - that the parts that "are" peculiar - just aren't peculiar to you anymore, so the potential for under explaining / under documenting is reasonably high.


Lastly, I am genuinely happy to help out where I can.
previously I was the patch manager for Subversion for quite a few years.
(I made sure that community-based patches remained "in-sight" and got logged to the issue register.)
it was a non-technical role because I don't know C / C++ well enough at the low level that SVN is programmed at.

If the project feels that it will be useful;
I'll happily be the "newbie" editor for documentation - but of course am going to have lots of questions along the way.

-Gavin.


As always thanks!

Gavin Baumanis

I, for one, like Roman numerals.


--
You received this message because you are subscribed to a topic in the Google Groups "Play Framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/j1YdT_jIdmY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/CAJmgB6312YGwFkC-%2BV3pptDQ5KpFChY62J0zY%3DK5k5VoN3EAiQ%40mail.gmail.com.

Gavin Baumanis

unread,
May 8, 2017, 7:52:22 PM5/8/17
to play-framework
Hi Greg,

Here is a complete (small) controller that suffered from the issue was I having.
The project is a technology pilot - so it doesn't do a lot and is deliberately verbose.
Nonetheless, I hope it explains why it suddenly isn't working in 2.6.x

Please let me know if you need a corresponding model and / or view.

package au.com.ecpr.emr.controllers.config

import java.util.Date._
import javax.inject.Inject


import scala.concurrent.{ ExecutionContext, Future }

import play.api._
import play.api.mvc._
import play.api.i18n._
import play.api.data.Form
import play.api.data.Forms._
import play.api.data.validation.Constraints._
import play.api.libs.json.Json

import au.com.ecpr.Utilities
import au.com.ecpr.emr.models.config.SystemUser

/** "Interface" between the model and the view.
  * it contains the actions required for an event and ALSO contains any related business logic for
  * those actions.
  *
  */


class AppConfig @Inject() (val messagesApi: MessagesApi)(implicit ec: ExecutionContext)
    extends Controller
    with I18nSupport {

  /** Class pseudo-constructor
    *
    * The Forms object defines the mapping method. This method takes the names and constraints of
    * the form, and also takes two functions: an apply function AND an unapply function.
    *
    * Normally we would also create a "full name" from the first and last name. But we have left
    * them separated here - to show how to used Nested values in Play forms.
    *
    */

  /** HTTP form data is never directly bound to your model classes. Instead, you use an instance
    * of play.api.data.Form.
    *
    */
  val appConfigForm: Form[CreateAppConfigForm] = Form {
    mapping(
      "URL" -> nonEmptyText,
      "subDomain" -> nonEmptyText,
      "region" -> nonEmptyText,
      "appModifiedBy" -> mapping(
        "userName" -> text,
        "firstName" -> text,
        "lastName" -> text)(AppModifiedByForm.apply)(AppModifiedByForm.unapply))(CreateAppConfigForm.apply)(CreateAppConfigForm.unapply)
  } // End appConfigForm

  /** Default / Home Page
    *
    * @return the Index (home) page for the application.
    * @since 0.1.0
    * @version 0.1.0
    * @author gavinbaumanis
    */
  def index = Action {
    Ok(au.com.ecpr.emr.views.html.index())
  } // End index

  /** System Administration menu
    *
    * @return the System Administration page for the application.
    * @since 0.1.0
    * @version 0.1.0
    * @author gavinbaumanis
    */
  def sysConfig = Action {

    Ok(au.com.ecpr.emr.views.html.config.sysconfig())
  } // End sysconfig

  /** Application Configuration Actions
    *
    * @return the Application Configuration page for THIS install
    * @since 0.1.0
    * @version 0.1.0
    * @author gavinbaumanis
    */
  def appConfig = Action { implicit request =>

    /** Get the current values stored in the database to display in the view via the above
      * mapping.
      *
      */

    /** TODO: get data from data source Then replace handwritten values with those retrieved
      *
      */


    val appConfigData = appConfigForm.fill(CreateAppConfigForm("URL",
      "subDomain",
      "region",
      AppModifiedByForm("GavinB",
        "Gavin",
        "Baumanis")))

    // Display the HTML form for THIS Application's System Configuration

    /** REMOVEME :
      * This is temporary for us to create a NOW timestamp to show in the prototype. When
      * we start retrieving real data this will go away.
      *
      */

    val utilities = new au.com.ecpr.Utilities()
    val theDateTime = utilities.dateTimeFormat_AU_now

    // Display the HTML form for THIS Application's System Configuration

    Ok(au.com.ecpr.emr.views.html.config.appconfig(appConfigData, theDateTime.toString))
  } // End appconfig

  /** SAVE the contents of the AppConfig Form.
    *
    */
  def appConfigSubmit = Action {

    // TODO: verify the contents of the form are valid
    // TODO: save the form

    // Saved. Now return to the SYS config Menu

    Redirect(au.com.ecpr.emr.controllers.config.routes.AppConfig.sysConfig)
  } // End appconfigsubmit
} // End Application controller class

/** Case classes
  *
  * The following case classes are used "here" within the controller only.
  * It is quite often the case that the model representation and that which is needed within a view
  * are different.
  *
  * So we can use the controller as an appropriate place to hold this interfacing code.
  */

/** Interfacing class between the model and the view for AppModifiedByForm
  * @param userName The user name of the logged-in user completing this change
  * @param firstName The first name of the logged-in user completing this change
  * @param lastName The last name of the logged-in user completing this change
  * @since 0.1.0
  * @version 0.1.0
  * @author gavinbaumanis
  */
case class AppModifiedByForm(userName: String, firstName: String, lastName: String)

/** Interfacing class between the model and the view for CreateAppConfigForm
  * @param subDomain the subDomain to prepend to ecpr.com.au for distinguishing between sites
  * @param region the region used for setting date / time locales.
  * @param modifiedBy form that contains modifiedBy data
  * @since 0.1.0
  * @version 0.1.0
  * @author gavinbaumanis
  */
case class CreateAppConfigForm(URL: String,
  subDomain: String,
  region: String,
  modifiedBy: AppModifiedByForm)


​-Gavin.​

As always thanks!

Gavin Baumanis

I, for one, like Roman numerals.


--
You received this message because you are subscribed to a topic in the Google Groups "Play Framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/j1YdT_jIdmY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/CAA%3D11Hxgy98wGzzzoXPtvV5ZrbjTHJhvSvjNKgM7qNRxLQcG5w%40mail.gmail.com.

Will Sargent

unread,
May 8, 2017, 7:57:46 PM5/8/17
to play-fr...@googlegroups.com
Hi Gavin, 

Please see https://github.com/playframework/playframework/pull/7313/files and provide feedback to see if that's any clearer.

Thanks,
Will.

--
Will Sargent
Engineer, Lightbend, Inc.


Gavin Baumanis

unread,
May 8, 2017, 8:05:38 PM5/8/17
to play-framework
Hi again, 

Just to follow up on this;

On 8 May 2017 at 11:38, Greg Methvin <gr...@lightbend.com> wrote:
The annotation goes on the constructor, exactly as shown in the code example at the beginning of your email. The annotation is just needed to tell your runtime DI framework that an instance can be created by calling that constructor. There's nothing special here; this should be the same as in all the examples in the documentation, just with different constructor parameters.


​The example code looks like this;
public MyClass {
    @javax.inject.Inject 
    public MyClass(play.i18n.MessagesApi messagesApi) { ... } 
}

The very first line; ​public MyClass {
Is missing from all my controller classes.
They all begin at your line 3;public MyClass(play.i18n.MessagesApi messagesApi) { ... } 

so when I add the annotation to the non-existent
​line ​
4
​,
 I get the following compilation error;

expected start of definition

at the next line of my code.
​(your line 5)​



So I assume I just need to add a wrapper class declaration to all my controllers and add the annotation?
​But w
What's the 1st line for?
It seems redundant?
​ (and outside of the fact that I am having issues with 2.6.x.... my code works without it.​


Thanks.


Gavin Baumanis

unread,
May 8, 2017, 8:09:20 PM5/8/17
to play-framework
Hi Will,

That's a great change;
Exactly what I was asking for.

Thanks very much.



As always thanks!

Gavin Baumanis

I, for one, like Roman numerals.


Greg Methvin

unread,
May 8, 2017, 9:01:01 PM5/8/17
to play-framework
Are you using Java or Scala? The previous code was Scala code and now this looks like Java code.

I was referring to the class declaration in this section of the Scala documentation: https://www.playframework.com/documentation/2.6.x/ScalaI18N#Externalizing-messages. The Java i18n API is different and is documented here: https://www.playframework.com/documentation/2.6.x/JavaI18N

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Gavin Baumanis

unread,
May 8, 2017, 10:35:43 PM5/8/17
to play-framework
Oh thanks gooness for that....
You're right - I was reading from the Java docs.... but am using Scala!

So I don't end up mispeaking again;
I'll re-review the scala docs again - now that I know to explicitly use the code examples in the docs (not sure how I ever overlooked it.... but noentheless)

And if I have anything further, I'll come back again.

(Please just let me know if you need anything more with respect to my old code that was working with 2.5.x)


Thanks to everyone!

As always thanks!

Gavin Baumanis

I, for one, like Roman numerals.


--
You received this message because you are subscribed to a topic in the Google Groups "Play Framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/j1YdT_jIdmY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/CAA%3D11Hyw7YFc8MgsANq_w45ca8up%2B_Qghtc0768btd2w0T6Kqg%40mail.gmail.com.

Gavin Baumanis

unread,
May 18, 2017, 9:35:21 AM5/18/17
to Play Framework
Ok : I am back!

I have been following along with the new 2.6 docs;


My controllers now start with;

class InsuranceDetails @Inject() (val messagesApi: MessagesApi)(implicit ec: ExecutionContext)

   
extends Controller
   
with I18nSupport {
...


The actions are now;

def insuranceDetails = Action { implicit request =>
...


The views start with;

@(insuranceDetailsData : Form[au.com.ecpr.emr.controllers.pas.CreateInsuranceDetailsForm],

    theDateTime : String)(implicit messages : Messages)
...



Now I am getting the following exception - but since it doesn't "seem" to point to my code
(Oh I am sure I am not doing something right! - I just don't know where to look - based on the exception)
So I need to bother you for some more help, please!


NoClassDefFoundError: play/api/i18n/I18nSupport$ResultWithLang
No source available, here is the exception stack trace:
->java.lang.NoClassDefFoundError: play/api/i18n/I18nSupport$ResultWithLang
 java
.lang.Class.getDeclaredMethods0(Native Method)
 java
.lang.Class.privateGetDeclaredMethods(Class.java:2701)
 java
.lang.Class.getDeclaredMethods(Class.java:1975)
 com
.google.inject.spi.InjectionPoint.getInjectionPoints(InjectionPoint.java:688)
 com
.google.inject.spi.InjectionPoint.forInstanceMethodsAndFields(InjectionPoint.java:380)
 com
.google.inject.internal.ConstructorBindingImpl.getInternalDependencies(ConstructorBindingImpl.java:165)
 com
.google.inject.internal.InjectorImpl.getInternalDependencies(InjectorImpl.java:616)
 com
.google.inject.internal.InjectorImpl.cleanup(InjectorImpl.java:572)
 com
.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:558)
 com
.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:887)
 com
.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:808)
 com
.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:285)
 com
.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:217)
 com
.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:893)
 com
.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:46)
 com
.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:50)
 com
.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:134)
 com
.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
 com
.google.inject.Guice.createInjector(Guice.java:99)
 com
.google.inject.Guice.createInjector(Guice.java:84)
 play
.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181)
 play
.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
 play
.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
 play
.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:163)
 play
.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:160)
 play
.utils.Threads$.withContextClassLoader(Threads.scala:21)
 play
.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:160)
 play
.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:125)
 scala
.Option.map(Option.scala:146)
 play
.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:125)
 play
.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:123)
 scala
.util.Success.flatMap(Try.scala:231)
 play
.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:123)
 play
.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:115)
 scala
.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
 scala
.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
 scala
.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
 scala
.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
 scala
.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
 scala
.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
 scala
.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)


As always - Thanks!
-Gavin.

Will Sargent

unread,
May 18, 2017, 10:14:23 AM5/18/17
to play-fr...@googlegroups.com
There isn't a ResultWithLang in https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/i18n/I18nSupport.scala -- how are you getting access to that class?

Can you clean and ensure you don't have old code or old dependencies lying around?

--
Will Sargent
Engineer, Lightbend, Inc.


Gavin Baumanis

unread,
May 18, 2017, 7:16:56 PM5/18/17
to Play Framework
Hi again,

The slightly "smartarse" answer would be;
"How the hecj should I know - that's why I am asking for help!)

As for cleaning: Sure thing.
I ran;
sbt clean update compile run

The app actually compiles without error - the exception is thrown after attempting to render the very first request.

(I also did "sbt cleanFiles" : as an additional step - without change to the end result.)


I haven't yet managed to do any more on it... but once I am home I will review all the code, again and see if I can find anything weird.
the issue of coursebeing thatI don't know what is weird and what is not.

the application started out as a Play 2.1 application and I have only made changes along the way - that stopped the application from compiling / running : which iswhy I have ended up having issues with internationilastion, recenty.

it wouldn't surprise me at all - to find that I am using an include that is needed : and not just isn;t needed - but is completely wrong!

Gavin.
-Gavin.


To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.



--
Greg Methvin
Tech Lead - Play Framework

--
You received this message because you are subscribed to a topic in the Google Groups "Play Framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/j1YdT_jIdmY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to play-framewor...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Gavin Baumanis

unread,
May 18, 2017, 10:18:01 PM5/18/17
to play-framework
That was some of the greatest English, of all time : sorry.
I had issues trying to read it back myself!


The application started as a Play 2.1 application.
I made the minimum change required to keep the application testing / running successfully as the versions of Play increased.

It wouldn't surprise me at all to find that I have imported old / now redundant / plain wrong framework libraries.
I'll do my best to review my code, comparing against a current template project and see if I can realise the problematic library.

Thanks once again....
I'll be sure to post again if I get stuck!

-Gavin.


As always thanks!

Gavin Baumanis

I, for one, like Roman numerals.


To unsubscribe from this group and all its topics, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/7ccc2e5d-7cda-4da0-8e99-3d20023e7405%40googlegroups.com.

Gavin Baumanis

unread,
May 21, 2017, 5:04:41 AM5/21/17
to Play Framework
Hi Greg / Will and everyone else....

I am not sure what the "deep" issue is - but I have solved my Language problem.
(AFTER making the required changes to now have an implicit request in the controller actions)


if I use Scala 2.11.11 with Play 2.6.x  I get the error;
NoClassDefFoundError: play/api/i18n/I18nSupport$ResultWithLang

And I assume this is a bug - since the 2.6.x documentation at;

Doesn;t mention anything about needing Scala 2.12.x 

and at;
the file-tree view shows Scala 2.11.11, in the "target" directory.

As soon as I swapped to Scala 2.12.2, (no other code changes - just the upgrade of Scala) : my app was back to working.

At first I thought it might been because of the Akka version I was using.. as I have also been trying to upgrade to Akka 2.5.x
But the bug is unrelated to Akka version.

If I use Akka 2.4.x AND scala 2.11.11 with Play 2.6.x : I get the exact same missing class error, even when using Akka 2.5.1

I am not sure if this is known or not ; by virtue of the 2.6.x documentation - it doesn't seem like it is.
And if it isn't... I am happy to provide you whatever extra information you think you might need.


Thanks to everyone for their assistance and helping me get to Play 2.6.with i18n.

-Gavin.
Reply all
Reply to author
Forward
0 new messages