question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot access implicits with Play 2.7

See original GitHub issue

Hi,

I’m currently using version 0.17.0 with Play 2.6.20, and today I wanting to upgrade Play to version 2.7.3, but I did not manager to make the library work with this version of Play…

I tried a few things, with both versions 2.1.0 (first version to handle Play 2.7) et 3.1.0(latest). After sbt reloading, request.jwtSession was not available anymore in the implicits I imported…

package fr.staycation.commons.auth

import javax.inject.{Inject, Singleton}
import pdi.jwt._
import pdi.jwt.JwtSession._
import play.api.mvc.{AnyContent, _}

import fr.staycation.foundation.models.User

import scala.concurrent.{ExecutionContext, Future}


trait BaseAction extends ActionBuilder[BaseRequest, AnyContent] with ActionRefiner[Request, BaseRequest]

@Singleton
class BaseActionImpl @Inject()(val parser: BodyParsers.Default)
  (implicit val executionContext: ExecutionContext)
  extends BaseAction {

  def refine[T](request: Request[T]): Future[Either[Result, BaseRequest[T]]] = {

    // We expect a header of type : 'Authorization: Bearer token'
    // Always successful - Return user if it exists
    Future.successful(Right(
      BaseRequest(request.jwtSession.getAs[User]("user"), request)
    ))
  }
}

And if I keep version 0.17.0 with Play 2.7, I have the following stack trace:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[RuntimeException: java.lang.ExceptionInInitializerError]]
	at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:351)
	at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:267)
	at play.filters.cors.AbstractCORSPolicy$$anonfun$1.applyOrElse(AbstractCORSPolicy.scala:128)
	at play.filters.cors.AbstractCORSPolicy$$anonfun$1.applyOrElse(AbstractCORSPolicy.scala:126)
	at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:414)
	at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
	at scala.concurrent.impl.CallbackRunnable.run$$$capture(Promise.scala:60)
	at scala.concurrent.impl.CallbackRunnable.run(Promise.scala)
	at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:72)
	at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
	at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete(Promise.scala:368)
	at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete$(Promise.scala:367)
	at scala.concurrent.impl.Promise$KeptPromise$Failed.onComplete(Promise.scala:383)
	at scala.concurrent.impl.Promise.transformWith(Promise.scala:36)
	at scala.concurrent.impl.Promise.transformWith$(Promise.scala:34)
	at scala.concurrent.impl.Promise$KeptPromise$Failed.transformWith(Promise.scala:383)
	at scala.concurrent.Future.recoverWith(Future.scala:413)
	at scala.concurrent.Future.recoverWith$(Future.scala:412)
	at scala.concurrent.impl.Promise$KeptPromise$Failed.recoverWith(Promise.scala:383)
	at play.api.libs.streams.StrictAccumulator.$anonfun$recoverWith$3(Accumulator.scala:206)
	at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
	at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
	at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
	at play.api.libs.streams.StrictAccumulator.run(Accumulator.scala:219)
	at play.core.server.AkkaHttpServer.$anonfun$runAction$4(AkkaHttpServer.scala:441)
	at akka.http.scaladsl.util.FastFuture$.strictTransform$1(FastFuture.scala:41)
	at akka.http.scaladsl.util.FastFuture$.$anonfun$transformWith$3(FastFuture.scala:51)
	at scala.concurrent.impl.CallbackRunnable.run$$$capture(Promise.scala:60)
	at scala.concurrent.impl.CallbackRunnable.run(Promise.scala)
	at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
	at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:92)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
	at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:92)
	at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41)
	at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:49)
	at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
	at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
	at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
	at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.RuntimeException: java.lang.ExceptionInInitializerError
	at play.api.mvc.ActionBuilder$$anon$10.apply(Action.scala:431)
	at play.api.mvc.Action.$anonfun$apply$2(Action.scala:98)
	at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$4(Accumulator.scala:184)
	at scala.util.Try$.apply(Try.scala:209)
	at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$3(Accumulator.scala:184)
	at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
	at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
	... 20 common frames omitted
Caused by: java.lang.ExceptionInInitializerError: null
	at fr.staycation.commons.auth.UserActionImpl.refine(UserAction.scala:21)
	at fr.staycation.commons.auth.UserActionImpl.refine(UserAction.scala:15)
	at play.api.mvc.ActionRefiner.invokeBlock(Action.scala:533)
	at play.api.mvc.ActionRefiner.invokeBlock$(Action.scala:532)
	at fr.staycation.commons.auth.UserActionImpl.invokeBlock(UserAction.scala:15)
	at play.api.mvc.ActionBuilder$$anon$11.invokeBlock(Action.scala:455)
	at play.api.mvc.ActionBuilder$$anon$11.invokeBlock(Action.scala:451)
	at play.api.mvc.ActionBuilder$$anon$10.apply(Action.scala:426)
	... 26 common frames omitted
Caused by: java.lang.RuntimeException: 
The global application reference is disabled. Play's global state is deprecated and will
be removed in a future release. You should use dependency injection instead. To enable
the global application anyway, set play.allowGlobalApplication = true.
       
	at scala.sys.package$.error(package.scala:27)
	at play.api.Play$.privateMaybeApplication(Play.scala:90)
	at play.api.Play$.maybeApplication(Play.scala:79)
	at pdi.jwt.JwtSession$.$anonfun$getConfigString$1(JwtSession.scala:98)
	at pdi.jwt.JwtSession$.$anonfun$wrap$1(JwtSession.scala:86)
	at pdi.jwt.JwtSession$.<init>(JwtSession.scala:111)
	at pdi.jwt.JwtSession$.<clinit>(JwtSession.scala)
	... 34 common frames omitted

Any idea why the implicit is not available anymore ? Thx!

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6

github_iconTop GitHub Comments

2reactions
pybuchecommented, Aug 30, 2019

Hi,

It worked ! The problem was indeed that jwtSession implicit needed both play.api.Configuration, and java.time.Clock instances as implicits.

I’m quite surprised IntelliJ didn’t warn me about a missing implicit… And actually I’m not really sure this is a good practice to have an implicit class with implicit parameters. If I have time, I will look into it to avoid this kind of complexity and propose you an alternative.

Thanks for your time!

PS: The working code is

package fr.staycation.commons.auth

import java.time.Clock

import javax.inject.{Inject, Singleton}
import pdi.jwt.JwtSession._
import play.api.Configuration
import play.api.mvc._

import fr.staycation.foundation.models.User

import scala.concurrent.{ExecutionContext, Future}


trait BaseAction extends ActionBuilder[BaseRequest, AnyContent] with ActionRefiner[Request, BaseRequest]

@Singleton
class BaseActionImpl @Inject()(val parser: BodyParsers.Default)
  (implicit val executionContext: ExecutionContext, conf: Configuration)
  extends BaseAction {

  implicit val clock: Clock = Clock.systemUTC

  def refine[T](request: Request[T]): Future[Either[Result, BaseRequest[T]]] = {

    // We expect a header of type : 'Authorization: Bearer token'
    // Always successful - Return user if it exists
    Future.successful(
      Right(
        BaseRequest(request.jwtSession.getAs[User]("user"), request)
      )
    )
  }
}
1reaction
pauldijoucommented, Aug 26, 2019

Could you try to import import java.time.Clock in the file and then add implicit val clock: Clock = Clock.systemUTC inside BaseActionImpl?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Play 2.7 Migration Guide - Documentation
This is a guide for migrating from Play 2.6 to Play 2.7. ... Add the implicit in scope: ... However, up until Play...
Read more >
[2.7.x]: @lang, @flash and @session are now ambiguous ...
Play Version 2.7.0-RC8 API Java Expected Behavior Using @lang, ... Http.Request implicit parameter found when accessing session.
Read more >
[Play 2.7 Java] Issues with deprecated Http.Context
I'm trying to migrate an old Play application to Play 2.7 starting by zero and I ... You must be authenticated to access...
Read more >
scala - Play Framework 2.1 - Cannot find an implicit ...
According to this issue, it is fixed in the documentation. I needed to add the following import: import play.api.libs.concurrent.Execution.Implicits._.
Read more >
Changelog | The Scala Programming Language
Changes in Version 2.10.0 · Value Classes · Implicit Classes · String Interpolation · Futures and Promises · Dynamic and applyDynamic · Dependent...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found