Space Specification for custom Space

11 views
Skip to first unread message

Stefano Tedeschi

unread,
Oct 23, 2021, 1:20:47 PM10/23/21
to sarl
Good evening!

Sorry for bothering you.

I'm trying to define a SpaceSpecification to create an instance of a custom space which extends the AbstractEventSpace. However I'm having some troubles in determining how to instantiate the space (which requires a SpaceParticipantListener).

Following the example of the specifications implemented in Janus, I've tried to define my space specification as follows:

class MySpaceSpecification implements SpaceSpecification<ExceptionSpace> {

val injector : Injector
val loggingService : LoggingService
val spaceParticipantListenerFactory : SpaceParticipantListenerFactory
val defaultSpace : OpenEventSpace

new (injector : Injector, defaultSpace : OpenEventSpace,
       spaceParticipantListenerFactory : SpaceParticipantListenerFactory, 
                       logger : LoggingService) {
this.injector = injector;
this.defaultSpace = defaultSpace
this.spaceParticipantListenerFactory = spaceParticipantListenerFactory
this.loggingService = logger
}
def create(id : SpaceID, params : Object*) : MySpace {
val logger = this.loggingService.getKernelLogger
val listener = this.spaceParticipantListenerFactory.create(this.defaultSpace, logger)
val ^space = new MySpaceImpl(id, listener, this.loggingService)
if (this.defaultSpace === null) { // Only useful for the default space of the default context
listener.defaultSpace = ^space;
}
this.injector.injectMembers(^space)
return ^space
}
}

However, if I try to use it inside an agent to instantiate the space I get a NoSuchMethodException concerning the MySpaceSpecification constructor.

Am I missing something?
I'm not sure I have fully understood the interaction between SARL and Janus.

Thank you very much in advance!
Best,

Stefano

Stéphane Galland

unread,
Oct 24, 2021, 4:25:44 AM10/24/21
to sarl
Dear Stefano.

You're code is very close to the good solution. It is not so easy to create space specifications because this feature is not completely documented in the SARL documentation. Congrats to reach this level of quality!

There is one major difference between the space specifications in the Janus framework (that are your source of inspiration), and those that could be defined by you: the Janus's space specifications are written for enabling a faster running. This implementation choices result to the creation of specific constructors. But, these specific constructors are used only if the space specification is defined in Janus, e.g., OpenEventSpaceSpecification. For the other space specifications, e.g., defined by you, only the default constructor is invoked. It is the key problem in your code.

Consequently, you have to refactor your code in the following way:

class MySpaceSpecification implements SpaceSpecification<ExceptionSpace> {
@Inject
var injector : Injector

@Inject
var loggingService : LoggingService

@Inject
@KernelScope
var spaceParticipantListenerFactory : SpaceParticipantListenerFactory

@Inject
@Named("defaultSpace")
var defaultSpace : OpenEventSpace

def create(id : SpaceID, params : Object*) : ExceptionSpace {
val logger = this.loggingService.getKernelLogger
val listener = this.spaceParticipantListenerFactory.create(this.defaultSpace, logger)
val ^space = new MySpaceImpl(id, listener, this.loggingService)
listener.defaultSpace = ^space
this.injector.injectMembers(^space)
return ^space
}
}

The code above have the following key points to be noted:
  1. There is no specific constructor. Only the default constructor (not written) is assumed.
  2. Because of the default constructor usage, the attributes that must have reference to Janus framework components must be injected by Janus (with Google Guice). Here, we use the standard annotated @Inject (from javax.annotation) to force the injector to set the values of the attributes.
  3. Annotation @KernelScope is mandatory for enabling the attribute injector to retrieve the right value for the factory of the space participant listener.
  4. Annotation @Named("defaultSpace") is mandatory for enabling the injector to write the reference to the default space of the context in which the new space is created.
  5. The create() function was well written. Here I have assumed that MySpaceImpl is a subclass of ExceptionSpace.
All the best.
Stéphane.

Stefano Tedeschi

unread,
Oct 24, 2021, 11:50:16 AM10/24/21
to sarl
Dear  Stéphane,

thank you very much for your fast response and for your help!
I've tried to adjust the code according to your suggestion and now it works perfectly.

Thanks again.
Best,

Stefano

Reply all
Reply to author
Forward
0 new messages