使用“META-INF / services”进行驱动程序的内部管道

时间:2013-09-20 16:17:43

标签: java netbeans jdbc meta-inf jaybird

我开发了Jaybird JDBC驱动程序,今天我遇到了一个问题(JDBC-325How to configure Jaybird with hibernate),它与Jaybird如何加载它的一些组件以及如何 - 在这种情况下 - NetBeans限制类加载。

问题与Jaybird使用META-INF/services中的条目加载部分内容的方式有关,并且NetBeans为Hibernate向导使用的类加载器明确忽略了这些文件(请参阅下面的详细信息)。

我可以通过(也)尝试加载作为Jaybird实现一部分的硬编码插件列表,或者将定义移动到其他位置来解决此问题。

然而,我想知道将META-INF/services用于像Jaybird这样的内部目的是否奇怪(或错误)?

我也不明白为什么NetBeans会排除加载META-INF/services 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,因此我们实际上并未使用{{1} })。对于即将推出的版本,我还计划将其用于支持的连接编码和(线路)协议定义。这将允许“自定义”编码定义(例如,扩展支持的编码,或使用备用编码)或不同的协议实现(例如,用于故障排除,自定义日志记录等)。

现在实际问题是Netbeans向导 Hibernate Mapping Files和数据库中的POJO 使用自定义类加载器(ServiceLoader),此类加载器忽略org.netbeans.modules.hibernate.util.CustomClassLoader中的文件。请注意,只有这个向导有问题,Netbeans本身可以毫无问题地使用驱动程序。

代码忽略META-INF/services

META-INF/services

这导致没有发现插件,并且驱动程序没有协议,这导致Netbeans内部@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); } } ,因为没有创建连接。

1 个答案:

答案 0 :(得分:3)

我认为Netbeans团队修复错误是错误的。无特殊原因忽略特定目录中的文件非常糟糕。主要在像META-INF / services这样重要的目录中。这不是安全问题或类似的问题。他们只是为了别人的糟糕书面代码而保护他们。他们应该用其他方式来做到这一点。我只能想象像你这样的人花多长时间找到这个问题的原因!

服务提供商API是公开的,原因之一是:每个人都应该使用它!这是让你的代码更少耦合的好方法,而且效果很好!我每次都使用它并建议每个人都使用它。

Java API显然支持使用服务提供程序机制添加JDBC驱动程序:

  

DriverManager方法getConnection和getDrivers已得到增强,可支持Java Standard Edition Service Provider机制。 JDBC 4.0驱动程序必须包含文件META-INF / services / java.sql.Driver。

这也说明在JDBC 4.0(2007)之后创建的驱动程序是预期,以提供通过该机制的入口。

虽然您应该/不能提供后备,但它没有说明。其他驱动程序必须这样做,否则他们将遇到相同的问题。但是他们可能出于其他原因(支持旧版本的JDBC API)这样做。

因此,您正在做正确的事情,如果支持特定用例对您来说非常重要,那么您需要将该代码维护为后备。否则,请删除代码并添加一些文档,以便人们可以解决它。