我开发了Jaybird JDBC驱动程序,今天我遇到了一个问题(
JDBC-325,
How to configure Jaybird with hibernate),它与Jaybird如何加载它的一些组件以及如何 – 在这种情况下 – NetBeans限制类加载有关.
问题与Jaybird使用META-INF / services中的条目加载部分内容的方式有关,NetBeans为Hibernate向导使用的类加载器明确忽略了这些文件(请参阅下面的详细信息).
我可以通过(也)尝试加载作为Jaybird实现的一部分的硬编码插件列表,或者通过将定义移动到其他位置来解决此问题.
然而,我想知道像Jaybird这样的内部用途使用META-INF /服务是否奇怪(或错误)?
我也不明白为什么NetBeans会排除加载META-INF /服务? Drew的评论似乎表明NetBeans在加载驱动程序时使用它来解决错误(参见this issue),尽管我认为用户可以更好地解决这个问题,包括驱动程序的所有依赖关系.
问题的细节
Jaybird使用插件来支持协议,例如Type 4协议,自定义Type 4 Open Office协议,Type 2嵌入式(本机)协议和Type 2本机客户端协议.我还相信第三方曾经使用它来提供将Oracle特定语法转换为Firebird语法的驱动程序.
所有这些插件都列在META-INF / services / org.firebirdsql.gds.impl.GDSFactoryPlugin中,并以类似于java.util.ServiceLoader的方式加载(当前的2.2.x驱动程序仍支持Java 5,因此我们实际上并未使用ServiceLoader ).对于即将推出的版本,我还计划将其用于支持的连接编码和(线路)协议定义.这将允许“自定义”编码定义(例如,扩展支持的编码,或使用备用编码)或不同的协议实现(例如,用于故障排除,自定义日志记录等).
现在实际的问题是Netbeans向导Hibernate Mapping Files和来自Database的POJO使用自定义类加载器(org.netbeans.modules.hibernate.util.CustomClassLoader),这个类加载器忽略META-INF / services中的文件.请注意,只有这个向导有问题,Netbeans本身可以毫无问题地使用驱动程序.
忽略META-INF /服务的代码:
@Override
public URL findResource(String name) {
return name.startsWith("META-INF/services") ? null : super.findResource(name); //NOI18N
}
@Override
public Enumeration findResources(String name) throws IOException {
if (name.startsWith("META-INF/services")) { //NOI18N
return Collections.enumeration(Collections.emptyList());
} else {
return super.findResources(name);
}
}
这导致没有发现插件,并且驱动程序没有协议,这导致Netbeans内部出现NullPointerException,因为没有创建连接.