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
OSGi ServiceLoader still not working #3177
Comments
@alexgast this is still not working for me as of 7.11.13. Are you able to explain anything you did besides wrap the JAR in an OSGI Plugin to get this working? |
OSGi a has strict concept of classloader visibility/isolation. In general a classloader of some OSGi Bundle (=Plugin) A (for instance a client bundle containg migration files: *.sql etc.) has no access to resources of a different Bundle B (for instance the flyway core bundle 'org.flywaydb.core'). As a consequence the last two lines of the public Flyway(Configuration configuration) {
this.configuration = new ClassicConfiguration(configuration);
// Load callbacks from default package
this.configuration.loadCallbackLocation("db/callback", false);
// Set ClassLoader for ServiceLoader
DatabaseTypeRegister.classLoader = configuration.getClassLoader();
VersionPrinter.classLoader = configuration.getClassLoader();
} because "configuration.getClassLoader()" holds a classloader of Bundle A by Solution/Workaround: remove the followng lines from // Set ClassLoader for ServiceLoader
DatabaseTypeRegister.classLoader = configuration.getClassLoader();
VersionPrinter.classLoader = configuration.getClassLoader(); and optionally make for class private static ClassLoader classLoader = new DatabaseTypeRegister().getClass().getClassLoader(); and for private static ClassLoader classLoader = new VersionPrinter().getClass().getClassLoader(); A deeper discussion of Serviceloader and OSGi issues (maybe needed to get flyway extensions working) you can find here: https://aries.apache.org/documentation/modules/spi-fly.html. |
Thanks @alexgast! For my fellow OSGI devs that end up here, 7.11.4 fixed the issue Alex is describing. However, I was still having an issue causing Flyway to not recognize my migrations. This is because the
However, of course when Flyway does this with its own classLoader, this isn't available. The solution is to ensure there is an Import-Package line in your Flyway bundle's MANIFEST.MF for the OSGI Framework.
With 7.11.4 and this Import-Package line, it works! |
As seen in flyway#3177, DatabaseTypeRegister shouldn't really be using the classloader provided in the configuration. In OSGI, this causes Flyway to be unable to find the database drivers, since they are only visible to the Flyway bundle and the user's bundle is only really needed to provide resources like SQL migrations.
As seen in flyway#3177, DatabaseTypeRegister shouldn't really be using the classloader provided in the configuration. In OSGI, this causes Flyway to be unable to find the database drivers, since they are only visible to the Flyway bundle and the user's bundle is only really needed to provide resources like SQL migrations.
Problem
When using "Flyway" (7.9.1) in some (OSGi-) Bundle X, the classloader of Bundle X is responsible for loading classes of the Bundle
org.flywaydb.core
, incl. the static parts oforg.flywaydb.core.internal.database.DatabaseTypeRegister
, i.e.equals the classloader of Bundle X.
But in OSGi Classloader X has no access to any resource of bundle
org.flywaydb.core
, i.e. the ServiceLoader folder is notvisible for this classloader and we end up with: #3173.
Solution
We need a classloader explicitly tied to bundle
org.flywaydb.core
, for instance<...>.getClass().getClassloader
of a some internal instanciated class oforg.flywaydb.core
:or equivalently
and then
The text was updated successfully, but these errors were encountered: