Hey,
I’m currently trying to create a command message from Service A that should be handled in Service B. The documentation mentions that alternatively, Kafka, Spring Cloud, etc. can be used, but it also states that Axon Server supports this natively, so I would prefer to use Axon alone.
Both services are running in separate Docker containers and are connected to the Axon Server (which is also running in its own container). I can view them both in the Axon Dashboard, and everything else works fine (like creating aggregates, members etc.).
However, whenever I send a command to the CommandGateway, I always receive a NoHandlerForCommandException (so it is not recognizing the handler defined in Service B). And when I try to directly send an event via the EventBus as an alternative, it is listed in the Axon Server, but ignored in Service B, too.
In both services, I have created the commands/events in the same path, as I read that Axon uses the path for identification, but that did not change anything.
data class CreateSomethingCommand(
val message: String
)
data class SomethingCreatedEvent(
val message: String
)
Service A
@Service
class ServiceA(
@Autowired private val commandGateway: CommandGateway,
@Autowired private val eventGateway: EventGateway
) {
private val logger = KotlinLogging.logger {}
fun testCommandRouting(message: String): ResponseEntity<String> {
logger.info { "Test command routing: $message." }
val response = commandGateway.sendAndWait<String>(
CreateSomethingCommand(message)
)
return ResponseEntity.status(HttpStatus.OK).body(response)
}
fun testEventRouting(message: String): ResponseEntity<String> {
logger.info { "Test event routing: $message." }
eventGateway.publish(SomethingCreatedEvent(message))
return ResponseEntity.status(HttpStatus.OK).build()
}
}
Service B
@Component
class ServiceB {
private val logger = KotlinLogging.logger {}
@CommandHandler
fun handle(cmd: CreateSomethingCommand): String {
logger.info { "Create something..." }
return "Something created..."
}
@EventHandler
fun on(evt: SomethingCreatedEvent) {
logger.info { "Something created." }
}
}
What else could I do, or am I missing some additional configuration? It seems to me, that the command and handler do not correspont to each other at all.
I have now created an external library for the commands and events so that the paths are identical and included in both services accordingly. Now, Service B is at least responding to something, and the NoHandlerForCommandException in Service A is no longer occurring, but now the following error is being thrown in Service B:
Exception in thread "CommandProcessor-0" com.thoughtworks.xstream.security.ForbiddenClassException: commands.TestRoutingCmd
at com.thoughtworks.xstream.security.NoTypePermission.allows(NoTypePermission.java:26)
at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:74)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
at org.axonframework.serialization.AbstractXStreamSerializer.classForType(AbstractXStreamSerializer.java:171)
at org.axonframework.serialization.LazyDeserializingObject.<init>(LazyDeserializingObject.java:83)
at org.axonframework.serialization.LazyDeserializingObject.<init>(LazyDeserializingObject.java:63)
at org.axonframework.axonserver.connector.command.GrpcBackedCommandMessage.<init>(GrpcBackedCommandMessage.java:54)
at org.axonframework.axonserver.connector.command.CommandSerializer.deserialize(CommandSerializer.java:146)
at org.axonframework.axonserver.connector.command.AxonServerCommandBus$CommandProcessingTask.run(AxonServerCommandBus.java:304)
at org.axonframework.axonserver.connector.PriorityRunnable.run(PriorityRunnable.java:58)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
I’m not sure if that goes into the right direction, but if so, does anybody know how to fix these permissions? ![]()
With the help of this Thread it seems to work right now.
Here is my adjusted version:
@SpringBootApplication
@Import(AxonConfig::class)
class Application
fun main(args: Array<String>) {
runApplication<Application>(*args)
}
@Configuration
class AxonConfig {
@Bean
fun xStream(): XStream {
val xStream = XStream()
xStream.allowTypesByWildcard(
arrayOf(
"com.myproject.**",
"commands.**",
"events.**"
)
)
return xStream
}
}