WegenenVerkeer / akka-persistence-postgresql

An akka-persistence plugin for Postgresql
MIT License
40 stars 25 forks source link

Unable to use any other WriterStrategy but the default - throws InvocationTargetException: null #64

Open Andycharalambous opened 3 years ago

Andycharalambous commented 3 years ago

The following method in PluginConfig.scala throws java.lang.reflect.InvocationTargetException: null

def writeStrategy(context: ActorContext): WriteStrategy = {
    val clazz = config.getString("writestrategy")
    val writeStrategyClazz =
      Thread.currentThread().getContextClassLoader.loadClass(clazz).asInstanceOf[Class[_ <: WriteStrategy]]
    writeStrategyClazz.getConstructor(classOf[PluginConfig], classOf[ActorSystem]).newInstance(this, context.system)
  }

when any WriteStrategy except the default is configured:

writestrategy = "akka.persistence.pg.journal.RowIdUpdatingStrategy"

akka.persistence.typed.internal.JournalFailureException: Failed to persist event type [..] with sequence number [1] for persistenceId [..]
    at akka.persistence.typed.internal.Running$PersistingEvents.onJournalResponse(Running.scala:754)
....
Caused by: java.lang.reflect.InvocationTargetException: null
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at akka.persistence.pg.PluginConfig.writeStrategy(PluginConfig.scala:115)
    at akka.persistence.pg.journal.PgAsyncWriteJournal.writeStrategy$lzycompute(PgAsyncWriteJournal.scala:31)
    at akka.persistence.pg.journal.PgAsyncWriteJournal.writeStrategy(PgAsyncWriteJournal.scala:31)
    at akka.persistence.pg.journal.PgAsyncWriteJournal.storeBatch$1(PgAsyncWriteJournal.scala:51)
Andycharalambous commented 3 years ago

Some more information:

EDIT: was able to get TransactionalWriteStrategy to work - i've looked at it's constructor signature vs RowIdUpdatingStrategy and SingleThreadedBatchWriteStrategy and they are identical :-/

Andycharalambous commented 3 years ago

Ok - so i'm way off about it being a constructor signature thing. I found this in the logs:

Caused by: java.lang.UnsupportedOperationException: cannot create top-level actor [AkkaPgRowIdUpdater] from the outside on ActorSystem with custom user guardian at akka.actor.ActorSystemImpl.actorOf(ActorSystem.scala:890) at akka.persistence.pg.journal.RowIdUpdatingStrategy.<init>(WriteStrategy.scala:106) ... 31 common frames omitted

So when using the RowIdUpdatingStrategy, it fails during the creation of the internal actor it uses. This might be an akka 2.6 issue or something I'm doing when I bootstrap the application by messing with the user guardian? I don't believe I am - I'm using typed actors, and have to have a single point of entry actor - thats just how it works.

Andycharalambous commented 3 years ago

I think the solution here is to use systemActorOf(...) instead of actorOf(...) when running in a typed actor system. I can't downgrade to classic akka, so I'm not sure how to proceed - genuine issue or akka 2.6 not supported yet?

EDIT: obviously I've never written an akka extension - systemActorOf is only available to extensions (I think). I'm stumped on this - i'll have to use something else (table-lock strategy is no-go for me - cockroachdb doesn't support table locks)