Error while extracting json into case class SCALA FLINK - json

The problem is in the map function while doing case class extraction. The case class is not serializable. I have defined formats DefaultFormats implicitly.
package org.apache.flink.quickstart
import java.util.Properties
import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper}
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import org.apache.flink.api.scala._
import org.apache.flink.runtime.state.filesystem.FsStateBackend
import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer09
import org.apache.flink.streaming.util.serialization.SimpleStringSchema
import org.json4s.DefaultFormats
import org.json4s._
import org.json4s.native.JsonMethods
import scala.util.Try
case class CC(key:String)
object WordCount{
def main(args: Array[String]) {
implicit val formats = org.json4s.DefaultFormats
// kafka properties
val properties = new Properties()
properties.setProperty("bootstrap.servers", "***.**.*.***:9093")
properties.setProperty("zookeeper.connect", "***.**.*.***:2181")
properties.setProperty("group.id", "afs")
properties.setProperty("auto.offset.reset", "earliest")
val env = StreamExecutionEnvironment.getExecutionEnvironment
val st = env
.addSource(new FlinkKafkaConsumer09("new", new SimpleStringSchema() , properties))
.flatMap(raw => JsonMethods.parse(raw).toOption)
// .map(_.extract[CC])
val l = st.map(_.extract[CC])
st.print()
env.execute()
}
}
The error :
INFO [main] (TypeExtractor.java:1804) - No fields detected for class
org.json4s.JsonAST$JValue. Cannot be used as a PojoType. Will be
handled as GenericType
Exception in thread "main" org.apache.flink.api.common.InvalidProgramException: Task not
serializable
at org.apache.flink.api.scala.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:172)
at org.apache.flink.api.scala.ClosureCleaner$.clean(ClosureCleaner.scala:164)
at org.apache.flink.streaming.api.scala.StreamExecutionEnvironment.scalaClean(StreamExecutionEnvironment.scala:666)
at org.apache.flink.streaming.api.scala.DataStream.clean(DataStream.scala:994)
at org.apache.flink.streaming.api.scala.DataStream.map(DataStream.scala:519)
at org.apache.flink.quickstart.WordCount$.main(WordCount.scala:38)
at org.apache.flink.quickstart.WordCount.main(WordCount.scala)
Caused by: java.io.NotSerializableException: org.json4s.DefaultFormats$$anon$4
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at org.apache.flink.util.InstantiationUtil.serializeObject(InstantiationUtil.java:317)
at org.apache.flink.api.scala.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:170)
... 6 more
Process finished with exit code 1

The solution to to put
implicit val formats = org.json4s.DefaultFormats
outside the main function like
object WordCount{
implicit val formats = org.json4s.DefaultFormats
def main(args: Array[String])
OR lazily initialize formats like
implicit lazy val formats = org.json4s.DefaultFormats
inside the main function like
def main(args: Array[String]) {
implicit lazy val formats = org.json4s.DefaultFormats

Related

How to update select table using JPA custom single query

I want update work_withdraw table , set pending column of deposit
table value quantity column of work_withdraw table.First of all I
want to pick deposit table id that id contain all the details, I find
pending value from that id and that value set in work_withdraw table's
quantity column. I write Below type of Custom Query and code by in my
service class code it shows me type mismatch error, Required Long
found Unit,If I change the Return type of query to Long It throw
another "Update cannot return any thing"
WorkWithdrawRepository.kt
package com.nilmani.workload.repository
import com.nilmani.workload.entity.Deposit
import com.nilmani.workload.entity.WorkWithdraw
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.RequestParam
interface DepositRepository:JpaRepository<Deposit,Long> {
#Modifying
#Query("update WorkWithdraw Ww SET Ww.quantity=(SELECT d.pending FROM Deposit d WHERE d.id=Ww.id)")
fun getPendingStatus(#RequestParam("id")id:Long)
}
WorkWithdrawService.kt
package com.nilmani.workload.service
import com.nilmani.workload.entity.WorkWithdraw
import com.nilmani.workload.model.request.ReqUpdateWork
import com.nilmani.workload.model.request.ReqWorkWithdraw
import com.nilmani.workload.repository.DepositRepository
import com.nilmani.workload.repository.WorkerWithdrawRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
#Service
class WorkWithdrawService {
#Autowired
private lateinit var workerWithdrawRepository: WorkerWithdrawRepository
#Autowired
private lateinit var workerRepository: WorkerWithdrawRepository
#Autowired
private lateinit var depositRepository: DepositRepository
/**Update the work service*/
fun updateWorkWithdraw(reqUpdateWork: ReqUpdateWork): WorkWithdraw {
val updateWork = WorkWithdraw (
id = reqUpdateWork.id,
quantity = depositRepository.getPendingStatus(reqUpdateWork.id)
)
return workerWithdrawRepository.save(updateWork)
}
}
AdminWorkController.kt
package com.nilmani.workload.controller
import com.nilmani.workload.entity.AdvanceCash
import com.nilmani.workload.entity.Deposit
import com.nilmani.workload.entity.WorkWithdraw
import com.nilmani.workload.model.request.ReqUpdateWork
import com.nilmani.workload.model.request.ReqWorkWithdraw
import com.nilmani.workload.service.AdminService
import com.nilmani.workload.service.DepositService
import com.nilmani.workload.service.WorkWithdrawService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
#RestController
#RequestMapping("/admin")
class AdminWorkController {
#Autowired
private lateinit var workWithdrawService: WorkWithdrawService
#Autowired
private lateinit var depositService: DepositService
#Autowired
private lateinit var adminService: AdminService
/**Update the workWithdraw table when receive amterial*/
#PutMapping("/updateWithdraw-work")
fun updateWorkWithdraw(#ModelAttribute reqUpdateWork: ReqUpdateWork):ResponseEntity<*>{
val deza= workWithdrawService.updateWorkWithdraw(reqUpdateWork)
val respDeza = ReqUpdateWork(
deza.id,
deza.quantity
)
return ResponseEntity(respDeza,HttpStatus.OK)
}
}
RequestUpdatWork.kt
package com.nilmani.workload.model.request
data class ReqUpdateWork(
var id:Long=-1,
var quantity:Long=-1,
)
Deposit.kt
package com.nilmani.workload.entity
import java.time.LocalDateTime
import javax.persistence.*
#Entity
data class Deposit(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id:Long=-1,
val totalPiece:Long=-1,
val totalDeposit:Long=-1,
#OneToOne(targetEntity = WorkWithdraw::class,cascade = [CascadeType.ALL])
val workWithdraw: WorkWithdraw,
var pending: Long =-1,
val depositTime:LocalDateTime= LocalDateTime.now()
)
WorkWithdraw.kt
package com.nilmani.workload.entity
import java.time.LocalDateTime
import javax.persistence.*
#Entity
data class WorkWithdraw(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id:Long=-1,
val materialName:String="",
val quantity: Long =-1,
val withTime:LocalDateTime= LocalDateTime.now(),
#OneToOne(targetEntity = Worker::class,cascade = [CascadeType.ALL])
val worker: Worker?=null
)
I get error in my service class at this below point point
quantity = depositRepository.getPendingStatus(reqUpdateWork.id)
And the error is below
Type mismatch.
Required:
Long
Found:
Unit
I do not understand how to handle this type of situation,I tried to
solve this issue last 3 day's but not able to solve according
requirement
Do not know which type of parameter value passed inside #RequestParam
in my repository class

How to display OpenCV webcam capture frame in JavaFX app

I'm working on creating desktop app using JavaFX, which allows you to scan qr codes from a webcam.
I decided to choose JavaCV to handle webcam capturning. However, the problem is that the CanvasFrame class creates a Swing JFrame. My main goal is to find the best way to integrate this with JavaFX components.
My question is whether it is possible to create CanvasFrame in JPanel(or other Swing/JavaFx component), not in JFrame. In this option I would wrap JPanel into SwingNode - it's solve my integration problem.
I'm also asking for other suggestions that solves JavaFX with JavaCV integration problem in my case.
Maybe there is a direct way to embed a camera screen into a JavaFx component.
I'm pasting the test code below. My code is written in kotlin, but it doesn't affect the problem:
import com.google.zxing.*
import com.google.zxing.client.j2se.BufferedImageLuminanceSource
import com.google.zxing.common.HybridBinarizer
import org.bytedeco.javacv.*
import java.awt.image.BufferedImage
import java.util.*
import java.util.concurrent.Executors
class Test {
companion object {
#JvmStatic
fun main(args: Array<String>) {
Executors.newSingleThreadExecutor().execute { testWebcam() }
}
private fun testWebcam() {
val grabber: OpenCVFrameGrabber = OpenCVFrameGrabber(0);
val canvasFrame: CanvasFrame = CanvasFrame("Cam")
grabber.start()
while (canvasFrame.isVisible) {
val frame: Frame = grabber.grabFrame() ?: break
canvasFrame.showImage(frame)
decodeQrCode(grabber)
}
}
private fun decodeQrCode(grabber: OpenCVFrameGrabber) {
val java2DFrameConverter: Java2DFrameConverter = Java2DFrameConverter()
val frame: Frame = grabber.grabFrame()
val image = java2DFrameConverter.getBufferedImage(frame)
val decodedQr = parseQr(image)
println(decodedQr)
}
private fun parseQr(image: BufferedImage): String? {
val reader: MultiFormatReader = MultiFormatReader()
val binaryBitmap: BinaryBitmap =
BinaryBitmap(HybridBinarizer(BufferedImageLuminanceSource(image)))
val hints: Hashtable<DecodeHintType, Any> = Hashtable()
hints[DecodeHintType.CHARACTER_SET] = "UTF-8"
hints[DecodeHintType.POSSIBLE_FORMATS] = listOf(BarcodeFormat.QR_CODE)
return try {
reader.decode(binaryBitmap, hints).text
} catch (e: NotFoundException) {
null;
}
}
}
}
There's a project at https://github.com/rladstaetter/javacv-webcam that has examples of using javacv with Swing, JavaFX, and a newer method of using a shared memory buffer between OpenCV and JavaFX's PixelBuffer.
Instead of using a CanvasFrame, you can use JavaFX's ImageView backed by a shared ByteBuffer. The pseudo-code is:
import java.nio.ByteBuffer
import javafx.scene.image._
import org.bytedeco.javacv.Frame
import org.bytedeco.opencv.global.opencv_imgproc._
import org.bytedeco.opencv.opencv_core.Mat
val videoView: ImageView = ImageView()
val grabber: OpenCVFrameGrabber = OpenCVFrameGrabber(0)
grabber.start()
// Fire off a thread to grab frames while the camera is active
// Each frame will ber passed to the updateView method below
// ... timer/thread omitted for brevity
val javaCVMat = Mat()
/** create buffer only once saves much time! */
val buffer: ByteBuffer = javaCVMat.createBuffer()
val formatByte: WritablePixelFormat<ByteBuffer> = PixelFormat.getByteBgraPreInstance()
fun updateView(frame: Frame): Unit = {
val w = frame.imageWidth()
val h = frame.imageHeight()
val mat = javaCVConv.convert(frame)
cvtColor(mat, javaCVMat, COLOR_BGR2BGRA)
val pb = PixelBuffer(w, h, buffer, formatByte)
val wi = WritableImage(pb)
videoView.setImage(wi)
}
I solved my problem. In my case, the best solution was to use Java2DFrameConverter:
import javafx.application.Application
import javafx.embed.swing.SwingFXUtils
import javafx.scene.Scene
import javafx.scene.image.ImageView
import javafx.scene.image.WritableImage
import javafx.scene.layout.VBox
import javafx.stage.Stage
import org.bytedeco.javacv.Frame
import org.bytedeco.javacv.Java2DFrameConverter
import org.bytedeco.javacv.OpenCVFrameGrabber
import java.awt.image.BufferedImage
import java.util.concurrent.Executors
class StackOverflow : Application() {
private val java2DFrameConverter: Java2DFrameConverter = Java2DFrameConverter()
companion object {
#JvmStatic
fun main(args: Array<String>) {
launch(StackOverflow::class.java)
}
}
override fun start(primaryStage: Stage) {
val grabber: OpenCVFrameGrabber = OpenCVFrameGrabber(0)
grabber.start()
val imageView: ImageView = ImageView()
Executors.newSingleThreadExecutor().execute {
while (true) {
val frame = grabber.grabFrame()
imageView.image = frameToImage(frame)
}
}
val scene: Scene = Scene(VBox(imageView), 800.0, 800.0)
primaryStage.scene = scene
primaryStage.show()
}
private fun frameToImage(frame: Frame): WritableImage {
val bufferedImage: BufferedImage = java2DFrameConverter.getBufferedImage(frame)
return SwingFXUtils.toFXImage(bufferedImage, null)
}
}

Retrofit 2 - Getting response 200, but list is empty

I've tried to get some json from this api: https://api.cointelegraph.com/api/v1/mobile/feed
I want to get the "title" field of each news. I created the class that supposed to get this fields and wrapper for this class, but I'm getting an empty list instead of this, i guess it's because I have to get field, which called "data" firstly and then parse it. So I changed my class for getting "title" fields to class for getting "data" field, but I'm still getting empty list.
I guess it's kinda stupid mistake, because it works with github api. I will put some kind of response below and my code. Thanks for trying to help.
Json response:
{"data":{"news":[{"type":"header","data":{"id":22358,"title":"MIT, Stanford Researchers to Fund New \u2018Globally Scalable\u2019 Cryptocurrency, \u2018Unit-e\u2019","lead":"Major U.S. universities including MIT, Stanford and UC Berkeley have teamed up to fund a new digital currency.","thumb":"https://s3.cointelegraph.com/storage/uploads/view/f7a7d42a1cba645f861ba810d2524f77.jpg","published_at":{"date":"2019-01-17 18:52:00.000000","timezone_type":3,"timezone":"Europe/London"},"share_url":"https://cointelegraph.com/news/mit-stanford-researchers-to-fund-new-globally-scalable-cryptocurrency-unit-e","views":2375,"type":"news","author":"Helen Partz","author_id":545,"tag":"Blockchain","badge":{"title":"News","label":"default"},"isSponsored":false,"audio":"https://s3.cointelegraph.com/audio/22358.71732d08-dc28-4787-98b1-46c4e0317916.mp3"}},{"type":"currencies","data":[{"price":3677.37,"name":"BTC","currency":"USD","isIncreased":1,"difference":"0.89"},{"price":123.57,"name":"ETH","currency":"USD","isIncreased":1,"difference":"0.17"},{"price":31.56,"name":"LTC","currency":"USD","isIncreased":1,"difference":"0.19"},{"price":0.33,"name":"XRP","currency":"USD","isIncreased":1,"difference":"1.22"}]}
Interface:
package com.hfad.cointask.service
import com.hfad.cointask.model.DataLIst
import com.hfad.cointask.model.NewsList
import retrofit2.Call
import retrofit2.http.*
interface CoinClient {
#GET("api/v1/mobile/feed")
fun getFeed(): Call<NewsList>
}
News class:
package com.hfad.cointask.model
class News (private var data: String) {
fun getData(): String{
return data
}
}
I've tried to get title in first time like that
package com.hfad.cointask.model
class News (private var title: String) {
fun getTitle(): String{
return title
}
}
My wrapper for News class:
package com.hfad.cointask.model
class NewsList {
var list = mutableListOf<News>()
}
My adapter:
package com.hfad.cointask.adapter
import android.support.v7.view.menu.MenuView
import android.support.v7.view.menu.MenuView.ItemView
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.RecyclerView.ViewHolder
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.hfad.cointask.R
import com.hfad.cointask.model.News
class CoinAdapter(var values: List<News>): RecyclerView.Adapter<CoinAdapter.CoinViewHolder>() {
override fun onBindViewHolder(p0: CoinViewHolder, p1: Int) {
val itemTitle: News = values[p1]
p0.newsTitle.text = itemTitle.getData()
}
override fun getItemCount(): Int {
return values.size
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): CoinViewHolder {
val view: View = LayoutInflater.from(p0.context).inflate(R.layout.news_item_view, p0, false)
return CoinViewHolder(view)
}
class CoinViewHolder(itemView: View): ViewHolder(itemView) {
var newsTitle: TextView = itemView.findViewById(R.id.item_title)
}
}
And my main activity:
package com.hfad.cointask
import android.os.Bundle
import android.support.design.widget.BottomNavigationView
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.widget.Toast
import com.hfad.cointask.adapter.CoinAdapter
import com.hfad.cointask.model.DataLIst
import com.hfad.cointask.model.News
import com.hfad.cointask.model.NewsList
import com.hfad.cointask.service.CoinClient
import kotlinx.android.synthetic.main.activity_feed.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class FeedActivity : AppCompatActivity() {
var news = mutableListOf<News>()
private lateinit var newsRecyclerView: RecyclerView
private lateinit var newsAdapter: CoinAdapter
private lateinit var layoutManager: LinearLayoutManager
private val client = mCoinClient().build()
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> {
message.setText(R.string.title_home)
return#OnNavigationItemSelectedListener true
}
R.id.navigation_dashboard -> {
message.setText(R.string.title_dashboard)
return#OnNavigationItemSelectedListener true
}
R.id.navigation_notifications -> {
message.setText(R.string.title_notifications)
return#OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_feed)
newsRecyclerView = findViewById(R.id.news_recycler_view)
layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
newsRecyclerView.layoutManager = layoutManager
newsAdapter = CoinAdapter(news)
newsRecyclerView.adapter = newsAdapter
getNews().enqueue(object: Callback<NewsList>{
override fun onResponse(call: Call<NewsList>, response: Response<NewsList>) {
var jsonNews = response.body().list
news.clear()
news.addAll(response.body().list)
newsAdapter.notifyDataSetChanged()
}
override fun onFailure(call: Call<NewsList>?, t: Throwable?) {
val toast = Toast.makeText(this#FeedActivity, t.toString(), Toast.LENGTH_SHORT)
toast.show()
}
})
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}
private fun getNews() = client.getFeed()
class mCoinClient {
private val builder = Retrofit
.Builder()
.baseUrl("https://api.cointelegraph.com/")
.addConverterFactory(GsonConverterFactory.create())
private val retrofit: Retrofit by lazy {
builder.build()
}
private val client: CoinClient by lazy {
retrofit.create(CoinClient::class.java)
}
fun build() = client
}
}
Thanks for any help
I think it you should change your Interface to
interface CoinClient {
#GET("api/v1/mobile/feed")
fun getFeed(): Call<Your Object that you want to receive it with>
}

NullPointerException when accessing val field in Scala class constructor

I want to translate something like the following Java code into Scala:
private HashMap<KeyStroke,Action>actionMap=new HashMap<KeyStroke,Action>();
KeyStroke left = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
//....
actionMap.put(left, new AbstractAction("move left") {
#Override
public void actionPerformed(ActionEvent e) {
doSomething();
}
}
My initial attempt was this:
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import java.awt.event.KeyEvent
import java.awt._
import javax.swing.JFrame
import javax.swing.JPanel
import javax.swing.Action
import javax.swing.AbstractAction
import javax.swing.KeyStroke
import collection.mutable.HashMap
object Main{
def main(args:Array[String]){
val gui:GUI = new GUI()
}
}
class GUI extends JFrame{
initKeyboard
pack
this.setVisible(true)
private val actionMap = new HashMap[KeyStroke,Action]
def initKeyboard{
val left = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0)
actionMap.put(left, new AbstractAction("Move Left"){
override def actionPerformed(e:ActionEvent){
println("Do something")
}
})//actionMap.put
}
}
Note that I have not yet written code to do anything with the actionMap.
However I get the following error at runtime:
Java.lang.NullPointerException
at GUI.initKeyboard(Game.scala:24)
at GUI.<init>(Game.scala:18)
at Main$.main(Game.scala:13)
at Main.main(Game.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
(note that line 24 is the line that starts "actionMap.put")
How should this be implemented?
The problem is in the initialization order.
The following is executed on new GUI instance creation, in the order listed:
initKeyboard
pack
this.setVisible(true)
private val actionMap = new HashMap[KeyStroke,Action]
You can see that you call initKeyboard before you initialize actionMap. Therefore accessing it inside initKeyboard throws an exception.
You can verify the initialization order with this simple example:
class GUI extends {
initKeyboard
private val actionMap = println("actionMap")
def initKeyboard: Unit = {
println("initKeyboard")
}
}
new GUI // prints: initKeyboard actionMap

Akka-Spray object marshall

I am experimenting with aka and spray, what I want to achieve is a simple object marshalling service.
When I try to compile the code I get the following error :
Error:(33, 18) could not find implicit value for parameter marshaller:
spray.httpx.marshalling.Marshaller[ExampleApplication.Password]
marshal(Password(randomString(8),i,0))
^
Here is the code:
import akka.actor.ActorSystem
import spray.http.HttpEntity
import spray.json.DefaultJsonProtocol
import spray.routing.SimpleRoutingApp
import spray.httpx.marshalling._
import spray.json._
object ExampleApplication extends App with SimpleRoutingApp {
implicit val actorSystem = ActorSystem()
implicit var i = 0;
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val PasswordFormat = jsonFormat3(Password)
}
case class Password(pass: String, count: Int, complexity: Int)
def newPass(cplx: Int):Password = {return Password(randomString(cplx),i,0)}
startServer(interface = "localhost", port = 8080) {
get {
path("passgen") {
i+=1
complete {
marshal(newPass(8))
}
}
}
}
def randomString(n: Int): String = {
n match {
case 1 => util.Random.nextPrintableChar().toString
case _ => util.Random.nextPrintableChar.toString ++ randomString(n - 1).toString
}
}
}
I'm still failing to understand what's going wrong.
Two changes to fix it:
import spray.httpx.SprayJsonSupport._
Then even though you define the JsonProtocol object right in your app you must still import it's members explicitly:
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val PasswordFormat = jsonFormat3(Password)
}
import MyJsonProtocol._
That looks a little repetitive in this case, but in most use cases you'll have it defined somewhere else.
Optional
You can complete the call without explicitly calling marshal:
complete {
newPass(8)
}