I am developing a Jaybird JDBC driver, and today I ran into a problem ( JDBC-325 , How to configure Jaybird with hibernate ), due to the way Jaybird loads some of its components and how - in this case - NetBeans restricts class loading.
The problem is how Jaybird loads parts of itself using entries in META-INF/services and the class loader used by NetBeans for the Hibernate wizard explicitly ignores these files (see details below).
I can get around this problem (also) by trying to download a hard list of plugins that are part of the Jaybird implementation, or by moving the definition to another location.
However, I was wondering if it is weird (or wrong) to use META-INF/services for internal purposes like Jaybird?
I also don't understand why NetBeans will exclude META-INF/services loading? Drew's comment seems to indicate that NetBeans used it to fix driver loading errors (see this question ), although I would have thought it would be better for the user to solve this, including all the driver dependencies.
Problem details
Jaybird uses plugins for supported protocols, such as Type 4 protocol, custom open type 4 protocol, built-in (native) Type 2 protocol and native Type 2 client protocol. I also believe that a third party once used it to provide a driver that Translated Oracle syntax to Firebird syntax.
All of these plugins are listed in META-INF/services/org.firebirdsql.gds.impl.GDSFactoryPlugin and are loaded in a way that is similar to java.util.ServiceLoader (current 2.2.x drivers still support Java 5, so we actually don’t use ServiceLoader ). For the upcoming version, I also planned to use this for supported encodings of connections and (wired) protocols. This will allow the use of “custom” encoding definitions (for example, expanding supported encodings or using an alternative encoding) or another protocol implementation (for example, for troubleshooting, user protocols, etc.).
Now the actual problem is that the Netbeans Hibernate Mapping Files and POJO wizard from the database uses a custom classloader ( org.netbeans.modules.hibernate.util.CustomClassLoader ), and this classloader ignores the files in META-INF/services . Please note that only this wizard has problems, Netbeans itself can use the driver without problems.
The code is ignored by META-INF/services :
@Override public URL findResource(String name) { return name.startsWith("META-INF/services") ? null : super.findResource(name); //NOI18N } @Override public Enumeration<URL> findResources(String name) throws IOException { if (name.startsWith("META-INF/services")) { //NOI18N return Collections.enumeration(Collections.<URL>emptyList()); } else { return super.findResources(name); } }
This causes the plugins to not be detected, and the driver has no protocols, which leads to a NullPointerException inside Netbeans, since the connection is not created.