-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JDBI integration - ClassCastException on hot reload with possibe fix #83
Comments
Hi, thanks for reporting and investigating this issue. The same problem occurred with Hibernate and Morphia, and I "solved" it by not hot-reloading the changed entity classes. Once a class is loaded, it can't be reloaded with the same class loader. So, Rapidoid uses a new class loader for each hot reload, which provides a good isolation between different reloading life-cycles. So, when a hot reload happens, some classes are actually not reloaded:
|
P.S. Sure, it would be great if you can provide a simple example project. |
Hmm, is there a public method in Rapidoid that does this, so the process is more flexible? The strange thing is that I could avoid the issue by hot reloading/compiling a random class before opening the page that creates the entity objects. I was going to hack a fix to this by using reflection to invoke private method App.restartApp() after running Rapidoid.run() but since that method actually invokes the main method again it just created an endless loop. Also, JDBI itself doesn't itself provide Daos, but interfaces that allow you to map objects from a resultset. There is a premade class that uses reflection to do this automatically for all your fields. It's very fast. I'll give you an example project in a bit! |
Sorry, after experimenting with creating an example project I discovered that the bug was on my end. |
Well, the bug is still there, but it happens because I use a custom method to bind the classes using reflection instead of beans, which JDBI uses by default. Apparently the problem doesn't happen when you map using java.beans. I still think it's worth looking into why hot reloading everything and then mapping the table into the entity fixes the problem, it might fix it entirely without needing to check for annotations. Is it possible to test restarting the application on initialization? Do you still want an example project, even though most people using JDBI won't need this fix? |
@korri123 JDBI integration is unlikely to be supported by Rapidoid in foreseeable future. I am closing this one... |
I am using JDBI with Rapidoid.
The problem
When visiting a page that makes database bindings/mapping after hot reloading I get a ClassCastException.
java.lang.ClassCastException: is.kormakur.site.dao.EntryDao cannot be cast to is.kormakur.site.dao.EntryDao
How it happens
After some Googling I figured out it has something to do with mismatched ClassLoaders, because JDBI holds a cache of the bindings/map of a DAO class for the database table.
My personal fix
If I hot reload and visit some other page before ever loading the offending page that initially maps the Pojo to the table and does database calls, then the problem is fixed, I can hot reload after freely without any exceptions.
Potential fix
When Rapidoid initializes it should use the same ClassLoader as it does for hot reloading as it uses initially, if I understand the problem correctly.
If you need some more information, like maybe an example project feel free to ask.
The text was updated successfully, but these errors were encountered: