Describe the bug
We need to use hibernate integrators to put events listener. And it seems that the custom integrator is only instantiated but never really called.
Expected behavior
I want to add custom integrator and the function integrate is called.
Actual behavior
We tried to add the file META-INF/services/org.hibernate.integrator.spi.Integrator with the following content :
com.decathlon.samourai.recorder.config.ReplicationEventListenerIntegrator
The integrator is added by hibernate as the log suggested :
2020-02-13 16:07:20,631 DEBUG [org.hib.int.int.IntegratorServiceImpl] (main) Adding Integrator [com.decathlon.samourai.recorder.config.ReplicationEventListenerIntegrator].
ReplicationEventListenerIntegrator code
When we set a debug point on the integrate function, we doesn't go in it. The listener are not set.
We try to log in the RecordEventListener but didn't see anything in the console. And the breakpoint on the log is not triggered.
A possible solution
I look at the code of the quarkus-hibernate-ormextensions and make some modification. With theses it work.
I first add the config in the HibernateOrmConfig
/**
* List of the integrator to set up. Comma separeted. Fully class name
*/
@ConfigItem
public Optional<List<String>> integrators;
Then i add in the HibernateOrmProcessor class at line 227 :
// add integrator present in configuration
hibernateConfig.integrators.ifPresent(integrators -> {
for (String integrator : integrators) {
integratorClasses.add((Class<? extends Integrator>) recorderContext.classProxy(integrator));
}
});
I modify my application.properties with :
quarkus.hibernate-orm.integrators=com.decathlon.samourai.recorder.config.ReplicationEventListenerIntegrator
After that all the breakpoints are triggered and i can see the log of the eventlistener.
I haven't tested natively if it works with or without the patch.
I also don't know if this fix is the best way to solve the problem.
It has the advantage of allowing custom integrator configuration.
Environment (please complete the following information):
uname -a or ver: Darwin FRL-C02P2645G3QC 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64
java -version: openjdk version "11.0.2" 2018-10-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.2+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.2+7, mixed mode)
1.2.0.Final
@kratisto that seems to be a decent solution, would you mind opening a PR so @Sanne can review it? Thanks!
We shouldn't require a new configuration property. I'd prefer it if we could figure out why the integrator isn't being called, it's probably something silly I forgot.
It's already done in:
https://github.com/quarkusio/quarkus/blob/8e0cce8b5ae30b46fbd21db6ddb3d5ade208d3be/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java#L225-L230 but I wonder if we should be using the TCCL instead of getClass().getClassloader()?
I'll have a look at it
I can change it to no longer require an entry in META-INF/services by doing index.getIndex().getAllKnownImplementors(DotName.createSimple("org.hibernate.integrator.spi.Integrator"), but I am not sure if we should be doing that.
WDYT?
I can change it to no longer require an entry in META-INF/services by doing
index.getIndex().getAllKnownImplementors(DotName.createSimple("org.hibernate.integrator.spi.Integrator"), but I am not sure if we should be doing that.
No I'd not do that. There's no benefit, other than the problem that it requires all integrators to have been indexed by Jandex. I'm not sure why RESTEasy decided to go for this approach, there's likely something different.
kratisto mentioned that his Integrators are being found just fine; the problem he's describing is that they are not being initialized: see the integrate method in his example.
No I'd not do that. There's no benefit, other than the problem that it requires all integrators to have been indexed by Jandex. I'm not sure why RESTEasy decided to go for this approach, there's likely something different.
:+1: Agreed.
kratisto mentioned that his Integrators are being found just fine; the problem he's describing is that they are not being initialized: see the
integratemethod in his example.
Not sure about that, I added some debug statements with a sample app and I don't see my integrator being found, but I'll investigate. One thing I noticed is that disintegrate is not called when the test finishes, probably because io.quarkus.hibernate.orm.runtime.JPAConfig#destroy(java.lang.Object) is not called after the test finishes
In fact
ServiceUtil.classNamesNamedIn(getClass().getClassLoader(),
"META-INF/services/org.hibernate.integrator.spi.Integrator"))
Doesn't read the file present in my project. I debugged ServiceUtil.
classLoader.getResource(fileName); return an empty Collections.
BootLoader.findResources(fileName); return null even if i set the absolute path ( /Users/JEFFREY/workspace/pro/java11/samourai-order-service/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator).
The file is loaded by Hibernate directly not Quarkus. This is why we can see it in log
@kratisto I created a PR (https://github.com/quarkusio/quarkus/pull/7208) which fixes this. Can you give it a try?
It works with your fix
@gastaldi @Sanne Thanks for your time and your work
@kratisto thank you for the bug report ;)