2013-06-25 9 views
6

मैं अक्का रिमोट एक्टर्स का उपयोग करके एक संदेश भेजने की कोशिश कर रहा हूं, जहां केस क्लास अपने कन्स्ट्रक्टर में सुपरक्लस लेने का तर्क है।अक्का रिमोट एक्टर्स, डिफॉल्ट कन्स्ट्रक्टर के बिना सुपरक्लास

यहाँ समस्या पुन: पेश करने के लिए एक न्यूनतम उदाहरण है:

package com.tuvistavie.testremote 

import akka.actor.{ Actor, ActorSystem, Props, ActorLogging } 
import com.typesafe.config.ConfigFactory 

abstract class Foo(val a: Int) 
case class MessageFoo(override val a: Int) extends Foo(a) 

object Sender { 
    def main(args: Array[String]) { 
    val system = ActorSystem("Sender", ConfigFactory.load.getConfig("sender")) 
    val actor = system.actorFor("akka://[email protected]:2552/user/receiver") 
    actor ! MessageFoo(1) 
    } 
} 

object Receiver { 
    class ReceiverActor extends Actor with ActorLogging { 
    def receive = { 
     case m: MessageFoo => log.debug(m.toString) 
    } 
    } 

    def main(args: Array[String]) { 
    val system = ActorSystem("Receiver", ConfigFactory.load.getConfig("receiver")) 
    val actor = system.actorOf(Props[ReceiverActor], "receiver") 
    } 
} 

इस कोड चल रहा है, मैं निम्नलिखित त्रुटि मिलती है:

[ERROR] [06/26/2013 02:53:16.132] [Receiver-9] 
[NettyRemoteTransport(akka://[email protected]:2552)] 
[email protected]://[email protected]:2552] Error[java.io.InvalidClassException: com.tuvistavie.testremote.MessageFoo; no valid constructor] 

मुझे लगता है कि ऐसा इसलिए है क्योंकि संदेश deserialized नहीं किया जा सकता (माता-पिता के कन्स्ट्रक्टर की वजह से akka.serialization.JavaSerializer का उपयोग करना)। यदि यह केवल एक या दो संदेश थे, तो मुझे पता है कि मैं अपना खुद का धारावाहिक लिख सकता हूं, लेकिन मेरे पास मेरे आवेदन में इस तरह के केस क्लास हैं।

रिमोट एक्टर्स का उपयोग करके इस तरह के ऑब्जेक्ट को पास करने का कोई आसान तरीका होगा?

trait Foo{ 
    val a:Int 
} 
case class MessageFoo(a:Int) extends Foo 

मैं आम तौर पर कोशिश करते हैं और मामले वर्गों के साथ वर्ग विरासत से दूर रहना:

उत्तर

8

चीजें यदि आप ऐसा तरह पुनर्गठन काम करेंगे। यदि मुझे केस क्लास के एक सेट को एक सार प्रकार के रूप में संदर्भित करने में सक्षम होना आवश्यक है, तो मैं इसके बजाय लक्षणों का उपयोग करता हूं।

+1

क्या आप कृपया यहां बताएंगे कि क्या हो रहा है? न तो प्रश्न का 'संदेशफू' और न ही आपके पास कोई तर्क-पुष्टिकरण नहीं है। जावा धारावाहिकता के साथ कोई काम क्यों करता है जब दूसरा नहीं करता है? –

+0

@DanielDarabos, स्कैला केस क्लासेस serializable हैं। यदि आप केस क्लास के लिए जेनरेट किए गए जावा कोड को देखते हैं तो आप देखेंगे कि यह धारावाहिक होने के लिए अनुबंध को पूरा करता है। – cmbaxter

+0

लेकिन प्रश्न में केस क्लास को deserialized नहीं किया जा सका, है ना? –

9
class A(a: Int) 
case class C() extends A(1) 

तरह cmbaxter के जवाब बताते हैं, इस पद्धति है, जहां मामले वर्ग के सुपर क्लास नो आर्ग निर्माता नहीं है, अक्रमांकन पर InvalidClassException की ओर जाता है। प्रति cmbaxter के जवाब, इस पैटर्न से परहेज एक समाधान है।

लेकिन इस पैटर्न में क्या गलत है? कारण Serializable के लिए एपीआई डॉक्स में दर्ज है:

To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.

तो समस्या यह है कि class A नो आर्ग निर्माता नहीं है, के साथ साथ यह Serializable नहीं है। तो Serializable बनाने के लिए एक आसान समाधान है!

class A(a: Int) extends Serializable 
case class C() extends A(1) 
+0

लक्षणों के पुनर्गठन के लिए अपील के रूप में एक 'विस्तार'/'के साथ जोड़ने के लिए एक त्वरित, त्वरित जीत की तरह काम करता है। – Brett

संबंधित मुद्दे