FirebirdEmbeddedProvider SPI classloader

17 views
Skip to first unread message

Pierre Vacher

unread,
Jul 23, 2025, 12:16:22 PMJul 23
to firebird-java
Hi all,

I use now the FirebirdEmbeddedProvider as an SPI service.

I realize during this use that it is necessary to add this archive to the classpath in order to use it.

This is what the use of SPI services requires if they are implemented without specifying a classloader when searching for services.

It seems to me that it is possible to use the classloader that loaded the driver, thus overcoming this limitation initially imposed by SPI services, ie:

ServiceLoader.load(FirebirdEmbeddedProvider.class, FirebirdEmbeddedLookup.class.getClassLoader());


I think it's an error of the SDK to provided a load() method for SPI services not using, as default, the caller's classloader as is the case with new ClassName() .
This completely breaks the inheritance of the classloaders...

Look at https://github.com/FirebirdSQL/jaybird/blob/3677b8b175b54fd0cf9dba3828180d9ceba003a6/jaybird-native/src/main/java/org/firebirdsql/jna/embedded/FirebirdEmbeddedLookup.java#L42

Pierre Vacher

unread,
Jul 23, 2025, 1:35:41 PMJul 23
to firebird-java
I want to clarify that this is exactly the problem that requires us to provide Java with a java.lang.System.LoggerFinder SPI service present on the classpath, or at least loaded with Thread.currentThread().getContextClassLoader()...

Mark Rotteveel

unread,
Jul 24, 2025, 2:41:16 AMJul 24
to firebi...@googlegroups.com
On 23/07/2025 19:35, Pierre Vacher wrote:
> I want to clarify that this is exactly the problem that requires us to
> provide Java with a /java.lang.System.LoggerFinder/ SPI service present
> on the classpath, or at least loaded with /
> Thread.currentThread().getContextClassLoader().../

That is because the LoggerFinder needs to be present when Java is
loaded, otherwise it would use the default (java.util.logging) or
fallback to System.err.

> Le mercredi 23 juillet 2025 à 18:16:22 UTC+2, Pierre Vacher a écrit :
>
> Hi all,
>
> I use now the FirebirdEmbeddedProvider as an SPI service.
>
> I realize during this use that it is necessary to add this archive
> to the classpath in order to use it.
>
> This is what the use of SPI services requires if they are
> implemented without specifying a classloader when searching for
> services.
>
> It seems to me that it is possible to use the classloader that
> loaded the driver, thus overcoming this limitation initially imposed
> by SPI services, ie:
>
> /ServiceLoader.load(FirebirdEmbeddedProvider.class,
> FirebirdEmbeddedLookup.class.getClassLoader());/
> /
> /
> /See file /FirebirdEmbeddedLookup.java <http://
> FirebirdEmbeddedLookup.java>
>
> I think it's an error of the SDK to provided a /load()/ method for
> SPI services not using, as default, the caller's classloader as is
> the case with /new ClassName()/ .
> This completely breaks the inheritance of the classloaders...
I'm not sure that would work, as the class loader that loaded the SPI
interface might not be the class loader that can find _your_ classes. In
the face of modules, it might be even more complicated. Using the
context class loader should achieve exactly the opposite, allowing you
to configure the class loader of the Thread allowing it to be found.

Could you create a ticket, and maybe provide an example case that
demonstrates the problem, then I can look into it more closely. Other
parts in Jaybird actually do try to load plugins from the SPI
interface's class loader and then the context class loader, but I can't
recall why I didn't do that here, just that I intentionally decided not
to try multiple class loaders.

That said, every time I do something that involves class loaders, I find
that I don't fully understand them, and that the documentation available
is severely lacking in details. So, I might be completely wrong here.

Mark
--
Mark Rotteveel

Pierre Vacher

unread,
Jul 24, 2025, 8:25:50 AMJul 24
to firebird-java
There's nothing particularly important about this.

However, I was forced to look into these issues because any LibreOffice extension code written in Java is loaded by a URLClassLoader and therefore requires that the classloader inheritance never be broken.

And when it is really necessary to be present on the classpath as is the case when using SPI service from the SDK then I use Java Instrumentation which allows me to add resources to the system classloader.

But I am not at all a bootloader expert and so I have to verify that all this is true and will open an issue to try this out.

Mark Rotteveel

unread,
Jul 25, 2025, 4:04:36 AMJul 25
to firebi...@googlegroups.com
On 24/07/2025 14:25, Pierre Vacher wrote:
> There's nothing particularly important about this.
>
> However, I was forced to look into these issues because any LibreOffice
> extension code written in Java is loaded by a URLClassLoader and
> therefore requires that the classloader inheritance never be broken.
>
> And when it is really necessary to be present on the classpath as is the
> case when using SPI service from the SDK then I use Java Instrumentation
> <https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/
> Instrumentation.html#appendToSystemClassLoaderSearch-
> java.util.jar.JarFile-> which allows me to add resources to the system
> classloader.
>
> But I am not at all a bootloader expert and so I have to verify that all
> this is true and will open an issue to try this out.

I created https://github.com/FirebirdSQL/jaybird/issues/886. If you have
any specific examples or concerns, can you add them there?

Mark

--
Mark Rotteveel
Reply all
Reply to author
Forward
0 new messages