No such method error akka.util.Helpers$.toRootLowerCase(Ljava/lang/String;)Ljava/lang/String; - scala

I am trying to run the following program
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.marshalling.ToResponseMarshallable
import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.directives.BasicDirectives
import akka.io.IO
import akka.stream.ActorMaterializer
import com.typesafe.config.ConfigFactory
import spray.json.DefaultJsonProtocol
import scala.concurrent.duration._
import scala.concurrent.Await
trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
implicit val itemFormat = jsonFormat2(Item)
}
final case class Item(name: String, id: Long)
object Main extends App with RestInterface {
val config = ConfigFactory.load()
val host = config.getString("http.host")
val port = config.getInt("http.port")
implicit val system = ActorSystem("My-ActorSystem")
implicit val executionContext = system.dispatcher
implicit val materializer = ActorMaterializer()
//implicit val timeout = Timeout(10 seconds)
val api = routes
Http().bindAndHandle(api, host, port) map {
binding => println(s"The binding local address is ${binding.localAddress}")
}
// recover
// { case ex => println(s"some shit occurred and it is"+ex.getMessage) }
// sys.addShutdownHook {
// system.log.info("Shutting down Spray HTTP in 10 seconds...")
// // NOTE(soakley): We are waiting to unbind to allow the VIP time to query healthcheck status.
// Thread.sleep(10000)
// system.log.info("Shutting down Spray HTTP and allowing 10 seconds for connections to drain...")
// val unbindFuture = Http.unbind(10.seconds)
//
// Await.ready(unbindFuture, 10.seconds)
// }
}
case class Stringer(str1 : String, str2 : String, str3 : String)
trait RestInterface extends Resource {
val routes = questionroutes ~ mydirectiveroute01 ~ mydirectiveroute02
}
trait Resource extends QuestionResource with mydirective01 with mydirective02
trait QuestionResource {
val questionroutes = {
path("hi") {
get {
val stringer_instance = Stringer("questionairre created","whatever","whatever-whatever")
complete(ToResponseMarshallable(stringer_instance.toString()))
}
}
}
}
trait mydirective01 extends BasicDirectives {
val getandputdirective = get | put
val mydirectiveroute01 = {
path("customhi" / IntNumber) {
passednumber1 => {
path(IntNumber) {
passednumber2 => {
getandputdirective {
ctx =>
ctx.complete("Testing get and put directive" + s"The passed string is " + passednumber2 + passednumber1)
}
}
}
}
}
}
}
trait mydirective02 extends BasicDirectives with JsonSupport {
val mydirectiveroute02 =
path("hello") {
get {
complete(HttpEntity(
ContentTypes.`text/html(UTF-8)`,
"<h1>Say hello to akka-http</h1>"))
}
} ~
path("randomitem") {
get {
// will marshal Item to JSON
complete(Item("thing", 42))
}
} ~
path("saveitem") {
post {
// will unmarshal JSON to Item
entity(as[Item]) { item =>
println(s"Server saw Item : $item")
complete(item)
}
}
}
}
But I get the following error
Exception in thread "main" java.lang.NoSuchMethodError: akka.util.Helpers$.toRootLowerCase(Ljava/lang/String;)Ljava/lang/String;
The error seems to be because of this line
implicit val materializer = ActorMaterializer()
May I know where I am going wrong. I have identical pom.xml file and the program in another module and it seems to run fine. I dont understand where I am going wrong. Thanks

I get errors like that when something that should have been re-compiled has not been re-compiled. clean" followed by "compile" in sbt resolves it.

The issue is due to the conflict in dependencies make sure you are using same version for all the related packages you are importing.
example:
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http-core_2.11</artifactId>
<version>10.0.0</version>
</dependency>
2.11 make sure you have other dependencies with same version
then make a clean build.

Your project dependencies have conflicting versions. The version that has that function gets discarded, and the other version included in the jar (or classpath - depending on how you execute).
Please provide your dependencies file (i.e. sbt.build or gradle.build etc.)

Related

scala akka http type mismatch

I created a project with open api then added a endpoint GET /product which is supposed to return a product( i am testing it so I just want it to return any product).
When I run the project I get the following error.
[error] found : org.openapitools.server.model.Product.type
[error] required: (?, ?, ?) => ?
[error] def toEntityMarshallerProduct: ToEntityMarshaller[Product] = jsonFormat3(Product)
the logs point at Product inside jsonFormat3
I noticed it's caused by the number of properties of the Product Model, if I reduce them to 3, it works ! this is weird! does anyone know how to resolve this?
this is the product model file
package org.openapitools.server.model
final case class Product (
id: Int,
name: String,
isAvailable: Boolean,
description: String,
category: String
)
this is the productAPI file
package org.openapitools.server.api
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.marshalling.ToEntityMarshaller
import akka.http.scaladsl.unmarshalling.FromEntityUnmarshaller
import akka.http.scaladsl.unmarshalling.FromStringUnmarshaller
import org.openapitools.server.AkkaHttpHelper._
import org.openapitools.server.model.Product
class ProductApi(
productService: ProductApiService,
productMarshaller: ProductApiMarshaller
) {
import productMarshaller._
lazy val route: Route =
path("product" / "all") {
get {
productService.productAllGet()
}
}
}
trait ProductApiService {
def productAllGet200(responseProduct: Product)(implicit toEntityMarshallerProduct: ToEntityMarshaller[Product]): Route =
complete((200, responseProduct))
def productAllGet()(implicit toEntityMarshallerProduct: ToEntityMarshaller[Product]): Route
}
trait ProductApiMarshaller {
implicit def toEntityMarshallerProduct: ToEntityMarshaller[Product]
}
and this is the main file
import akka.actor.typed.{ActorSystem, ActorRef}
import akka.actor.typed.scaladsl.Behaviors
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.StatusCodes
// for JSON serialization/deserialization following dependency is required:
// "com.typesafe.akka" %% "akka-http-spray-json" % AkkaHttpVersion
import akka.http.scaladsl.marshalling.ToEntityMarshaller
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._
import scala.io.StdIn
import akka.util.Timeout
import scala.concurrent.duration._
import scala.concurrent.{ ExecutionContext, Future }
import org.openapitools.server.api._
import org.openapitools.server.model._
object Main extends App {
// needed to run the route
implicit val system = ActorSystem(Behaviors.empty, "product")
// implicit val materializer = ActorMaterializer()
// needed for the future map/flatmap in the end and future in fetchItem and saveOrder
implicit val executionContext = system.executionContext
object DefaultMarshaller extends ProductApiMarshaller {
def toEntityMarshallerProduct: ToEntityMarshaller[Product] = jsonFormat3(Product)
}
object DefaultService extends ProductApiService {
def productAllGet() (implicit toEntityMarshallerProduct: ToEntityMarshaller[Product]) : Route = {
val reponse = Future {
Product(1,"product",false,"desc","pizza")
}
requestcontext => {
(reponse).flatMap {
(product: Product) =>
productAllGet200(product)(toEntityMarshallerProduct)(requestcontext)
}
}
}
}
val api = new ProductApi(DefaultService, DefaultMarshaller)
val host = "localhost"
val port = 3005
val bindingFuture = Http().newServerAt(host, port).bind(pathPrefix("api"){api.route})
println(s"Server online at http://${host}:${port}/\nPress RETURN to stop...")
bindingFuture.failed.foreach { ex =>
println(s"${ex} Failed to bind to ${host}:${port}!")
}
StdIn.readLine() // let it run until user presses return
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
}
I noticed it's caused by the number of properties of the Product Model, if I reduce them to 3, it works ! this is weird! does anyone know how to resolve this?
try it with using a Data Transfer Object (DTO) which will provide by your api and a domain model object which is handled internally.
so you will use jsonFormat3 for your DTO and have no need to jsonFormat5.
a simple mapper or helper method inner of case classes provide a smooth integration of that.
for example:
final case class Product (
id: Int,
name: String,
isAvailable: Boolean,
description: String,
category: String
) {
def toDto: ProductDTO = ProductDTO(prop0, prop1, prop2)
}
final case class ProductDTO (
prop0: X,
prop1: Y,
prop2: Z
) {
def toDomain(propA: X, propB: Y): Product = Product(id, name, isAvailable, description, category)
}
object ProductSupport extends SprayJsonSupport with DefaultJsonProtocol {
implicit val productFormat = json3Format(ProductDTO)
}

Scala compiler can't find the unmarshalling implicits in route declaration

I'm trying to build a REST server using this tutorial:
https://spindance.com/reactive-rest-services-akka-http/
However, having reached the "Responding with JSON" section, I've noticed that my code doesn't compile, and I can't make POST requests. This is the error that I'm getting:
Error:(59, 18) could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[Health]
entity(as[Health]) { statusReport =>
^
Having looked at other tutorials, I've found out that you need to include an object containing an implicit variable for the class that I'm trying to unmarshall. I did that, and I even imported the httpx library, but I'm still getting this error. My code is given below.
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.stream.ActorMaterializer
import akka.pattern.ask
import akka.util.Timeout
import spray.json._
import DefaultJsonProtocol._
import spray.httpx.SprayJsonSupport.sprayJsonUnmarshaller
import scala.concurrent.duration._
import scala.io.StdIn
object JsonImplicits extends DefaultJsonProtocol {
implicit val healthFormat = jsonFormat2(Health)
}
object MyApplication {
val host = "localhost"
val port = 8080
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem("simple-rest-system")
// Something to do with flows
implicit val materializer = ActorMaterializer()
// A reference to a specific thread pool
// You can configure thread pool options through it
// It is the engine that executes the actors
implicit val executionContext = system.dispatcher
val requestHandler = system.actorOf(RequestHandler.props(), "requestHandler")
//Define the route
val route : Route = {
implicit val timeout = Timeout(20 seconds)
import JsonImplicits._
import spray.httpx.SprayJsonSupport._
path("health") {
get {
onSuccess(requestHandler ? GetHealthRequest) {
case response: HealthResponse =>
complete(StatusCodes.OK, s"Everything is ${response.health.status}!")
case _ =>
complete(StatusCodes.InternalServerError)
}
}
} ~ post {
// Entity extracts the body of the POST request and then converts it into a
// Health object
entity(as[Health]) { statusReport =>
onSuccess(requestHandler ? SetStatusRequest(statusReport)) {
case response: HealthResponse =>
complete(StatusCodes.OK,s"Posted health as ${response.health.status}!")
case _ =>
complete(StatusCodes.InternalServerError)
}
}
}
}
//Start up and listen for requests
val bindingFuture = Http().bindAndHandle(route, host, port)
println(s"Waiting for requests at http://$host:$port/...\nHit RETURN to terminate")
StdIn.readLine()
//Shutdown
bindingFuture.flatMap(_.unbind())
system.terminate()
}
}

Stubbing SOAP requests in Scala

I use scalaxb to generate models and client part of the SOAP interface. For testing I use Betamax, which can also be used in Scala. However, scalaxb uses Netty as a transport, which ignores proxy settings set up by Betamax. How would you cope with this situation?
scalaxb uses cake pattern, so the service is built from 3 parts like in the following example:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.concurrent.duration._
val service = (new stockquote.StockQuoteSoap12Bindings with
scalaxb.SoapClientsAsync with
scalaxb.DispatchHttpClientsAsync {}).service
val fresponse = service.getQuote(Some("GOOG"))
val response = Await.result(fresponse, 5 seconds)
println(response)
And tests:
import co.freeside.betamax.{TapeMode, Recorder}
import co.freeside.betamax.proxy.jetty.ProxyServer
import dispatch._
import org.scalatest.{Tag, FunSuite}
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
class StockquoteSpec extends FunSuite with Betamax {
testWithBetamax("stockquote", Some(TapeMode.READ_WRITE))("stockquote") {
val fresponse = service.getQuote(Some("GOOG"))
val response = Await.result(fresponse, 5 seconds)
println(response)
}
}
trait Betamax {
protected def test(testName: String, testTags: Tag*)(testFun: => Unit)
def testWithBetamax(tape: String, mode: Option[TapeMode] = None)(testName: String, testTags: Tag*)(testFun: => Unit) = {
test(testName, testTags: _*) {
val recorder = new Recorder
val proxyServer = new ProxyServer(recorder)
recorder.insertTape(tape)
recorder.getTape.setMode(mode.getOrElse(recorder.getDefaultMode()))
proxyServer.start()
try {
testFun
} finally {
recorder.ejectTape()
proxyServer.stop()
}
}
}
}
Versions:
net.databinder.dispatch 0.11.2
co.freeside.betamax 1.1.2
com.ning.async-http-client 1.8.10
io.netty.netty 3.9.2.Final
It is indeed possible to use proxy with Netty. Although Netty does not read system properties for proxy settings, the settings can be injected using ProxyServerSelector. It is created in build method of AsyncHttpClientConfig:
if (proxyServerSelector == null && useProxySelector) {
proxyServerSelector = ProxyUtils.getJdkDefaultProxyServerSelector();
}
if (proxyServerSelector == null && useProxyProperties) {
proxyServerSelector = ProxyUtils.createProxyServerSelector(System.getProperties());
}
if (proxyServerSelector == null) {
proxyServerSelector = ProxyServerSelector.NO_PROXY_SELECTOR;
}
The only obstacle is that scalaxb uses default config with useProxyProperties=false. You can override it with custom MyDispatchHttpClientsAsync that you can use when creating the service:
val service = (new stockquote.StockQuoteSoap12Bindings with
scalaxb.SoapClientsAsync with
MyDispatchHttpClientsAsync {}).service
And the source code of MyDispatchHttpClientsAsync (the key point is calling setUseProxyProperties(true)):
import com.ning.http.client.providers.netty.NettyAsyncHttpProvider
import com.ning.http.client.{AsyncHttpClientConfig, AsyncHttpClient}
import scalaxb.HttpClientsAsync
/**
* #author miso
*/
trait MyDispatchHttpClientsAsync extends HttpClientsAsync {
lazy val httpClient = new DispatchHttpClient {}
trait DispatchHttpClient extends HttpClient {
import dispatch._, Defaults._
// Keep it lazy. See https://github.com/eed3si9n/scalaxb/pull/279
lazy val http = new Http(new AsyncHttpClient(new NettyAsyncHttpProvider(new AsyncHttpClientConfig.Builder().setUseProxyProperties(true).build())))
// lazy val http = Http.configure(_.setUseProxyProperties(true)) // Maybe later. See https://github.com/eed3si9n/scalaxb/issues/312
def request(in: String, address: java.net.URI, headers: Map[String, String]): concurrent.Future[String] = {
val req = url(address.toString).setBodyEncoding("UTF-8") <:< headers << in
http(req > as.String)
}
}
}

How do you set the viewport, width, with phantomjs with play 2 framework

I have been struggling with this for a while, I can't find a way to instruct phantomjs about the viewport. I am using play 2.2 (code is based on: Set Accept-Language on PhantomJSDriver in a Play Framework Specification )
package selenium
import org.specs2.mutable.Around
import org.specs2.specification.Scope
import play.api.test.{TestServer, TestBrowser, FakeApplication}
import org.openqa.selenium.remote.DesiredCapabilities
import org.specs2.execute.{Result, AsResult}
import play.api.test.Helpers._
import scala.Some
import org.openqa.selenium.phantomjs.PhantomJSDriver
import org.openqa.selenium.NoSuchElementException
import java.io.File
import java.io.PrintWriter
import java.util.concurrent.TimeUnit
import collection.JavaConversions._
abstract class WithPhantomJS(val additionalOptions: Map[String, String] = Map()) extends Around with Scope {
implicit def app = FakeApplication()
implicit def port = play.api.test.Helpers.testServerPort
// for phantomjs
lazy val browser: TestBrowser = {
val defaultCapabilities = DesiredCapabilities.phantomjs
print(defaultCapabilities.toString)
val additionalCapabilities = new DesiredCapabilities(mapAsJavaMap(additionalOptions))
val capabilities = new DesiredCapabilities(defaultCapabilities, additionalCapabilities)
val driver = new PhantomJSDriver(capabilities)
val br = TestBrowser(driver, Some("http://localhost:" + port))
br.webDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS)
br
}
override def around[T: AsResult](body: => T):Result = {
try {
running(TestServer(port, FakeApplication()))(AsResult.effectively(body))
} catch {
case e: Exception => {
val fn: String = "/tmp/test_" + e.getClass.getCanonicalName;
browser.takeScreenShot(fn + ".png")
val out = new PrintWriter(new File(fn + ".html"), "UTF-8");
try {
out.print(browser.pageSource())
} finally {
out.close
}
throw e;
}
} finally {
browser.quit()
}
}
}
and the actual test looks like this:
class ChangeName extends Specification {
"User" should {
"be able to change his name in account settings" in new WithPhantomJS() {
// ... this throws
I'd like the exception handler to render the site, which works, however, i can see the with matching a mobile device (narrow).
How can I change the width?
This seems to work:
import org.openqa.selenium.Dimension
...
browser.webDriver.manage().window().setSize(new Dimension(1280, 800))

NullPointerException when unit testing Spray route

I am a Scala newbie, and I am moving my first steps with Spray.io. I have defined a bunch of routes that seem to work just fine when I manually run them through Curl. However, I do get a nasty NullPointerException when I try to unit test the 'GET /documents?q=' route using spray.testkit.Specs2RouteTest.
Here is the route definition:
trait MyService extends HttpService {
import DocumentJsonProtocol._
val searchService: SearchService
val myRoute =
path("documents") {
post {
entity(as[Document]) { doc =>
detach() {
val docId = searchService.indexDocument(doc)
complete(201, s"document created: $docId")
}
}
} ~
get {
parameter('q) { q =>
detach() {
val docs = searchService.matchingQuery(q)
complete(docs)
}
}
}
} ~
path("documents" / Segment ) { docId =>
get {
detach() {
searchService.getDocument(docId) match {
case Some(doc) => {
complete(doc)
}
case None => {
complete(404, s"Cannot find a document with id: $docId")
}
}
}
}
}
}
And here is the failing test:
package example.com
import org.specs2.mutable.Specification
import org.specs2.specification.Scope
import org.specs2.mock._
import spray.testkit.Specs2RouteTest
import spray.http._
import spray.httpx.marshalling._
import StatusCodes._
import com.example.services.SearchService
import com.example.data._
import DocumentJsonProtocol._
class MyServiceSpec extends Specification
with Specs2RouteTest
with Mockito
with MyService {
val searchService = mock[SearchService]
def actorRefFactory = system
trait testDoc extends Scope {
val docId = "test-id"
val testDoc =
Document(Some(docId), "test-title", "test-author", "body", None)
searchService.indexDocument(testDoc).returns(docId)
searchService.matchingQuery("test-title").returns(List(testDoc))
}
"MyService" should {
"allows to search documents by keyword" in new testDoc {
Get("/documents?q=hello-test") ~> myRoute ~> check {
Right(entity) === marshal(List(testDoc))
}
}
This fails with the following error:
[ERROR] [04/07/2014 23:56:50.689] [io-composable-MyServiceSpec-akka.actor.default-dispatcher-3] [ActorSystem(io-composable-MyServiceSpec)] Error during processing of request HttpRequest(GET,http://ex
ample.com/documents?q=hello-test,List(),Empty,HTTP/1.1)
java.lang.NullPointerException
at spray.json.CollectionFormats$$anon$1.write(CollectionFormats.scala:26)
at spray.json.CollectionFormats$$anon$1.write(CollectionFormats.scala:25)
at spray.httpx.SprayJsonSupport$$anonfun$sprayJsonMarshaller$1.apply(SprayJsonSupport.scala:43)
at spray.httpx.SprayJsonSupport$$anonfun$sprayJsonMarshaller$1.apply(SprayJsonSupport.scala:42)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$1.apply(Marshaller.scala:58)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$1.apply(Marshaller.scala:58)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$2.apply(Marshaller.scala:61)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$2.apply(Marshaller.scala:60)
at spray.httpx.marshalling.Marshaller$$anon$2.apply(Marshaller.scala:47)
at spray.httpx.marshalling.BasicToResponseMarshallers$$anon$1.apply(BasicToResponseMarshallers.scala:35)
at spray.httpx.marshalling.BasicToResponseMarshallers$$anon$1.apply(BasicToResponseMarshallers.scala:22)
at spray.httpx.marshalling.ToResponseMarshaller$$anonfun$compose$1.apply(Marshaller.scala:69)
at spray.httpx.marshalling.ToResponseMarshaller$$anonfun$compose$1.apply(Marshaller.scala:69)
at spray.httpx.marshalling.ToResponseMarshaller$$anon$3.apply(Marshaller.scala:81)
at spray.httpx.marshalling.ToResponseMarshallable$$anon$6.marshal(Marshaller.scala:141)
at spray.httpx.marshalling.ToResponseMarshallable$$anon$7.apply(Marshaller.scala:145)
at spray.httpx.marshalling.ToResponseMarshallable$$anon$7.apply(Marshaller.scala:144)
at spray.routing.RequestContext.complete(RequestContext.scala:235)
The problem I could see after reading your code is that you mock matchingQuery function with "test-title" argument and make request with "hello-test" query parameter which leads mock to return null.