【问题标题】:Jar file dependencies in Java 1.4Java 1.4 中的 Jar 文件依赖项
【发布时间】:2010-11-23 00:48:31
【问题描述】:

我正在开发一个小型 Java 项目,该项目现在连接到 MS SQL Server 2000 数据库,但很快将连接到 MS SQL Server 2005 数据库。我正在创建一个 jar 以便于部署。我试图设置它,这样我就可以更改配置文件并更改驱动程序(就像在 .NET 中一样)。但是,由于 Java 的 Jar embedded classpath 的限制,以及嵌入式类路径 (1) 上缺少通配符。有没有办法在不明确引用每个驱动程序 jar 的情况下解决这个问题? 如果我必须这样做,每次数据库更改时我都必须重新编译......

(1):但是,Class-Path jar-manifest 标头中不支持类路径通配符。

【问题讨论】:

  • 您的链接指向 Java 6。在 1.4 中,根本没有类路径通配符。

标签: java jar classpath executable-jar


【解决方案1】:

一般情况下,您可以修改classpath at runtime。像这样的方法是处理 Java 中“插件”类型 jar 的一般方法(与您的情况非常相似)。

【讨论】:

    【解决方案2】:

    您可以包含有关使用哪个驱动程序的信息,例如一个配置文件。或者在 JAR 文件本身的清单中。启动应用程序时只需包含所有 JAR 文件,但从配置中加载驱动程序的名称。

    【讨论】:

      【解决方案3】:

      我会说,在您部署的同一个 Jar 中包含第三方代码不是 Java 方式(如在标准实践中)。但是 jar 只是一个 zip 文件,所以在大多数情况下(除了清单中的一些花哨的东西),如果需要,您可以将它们组合起来。

      话虽如此,您可以在 jar 文件中包含对所有潜在 JDBC 驱动程序 jar 的类路径引用,或者简单地以正确的方式调用 JDBC 驱动程序 jar。然后在同一目录下有一个配置文件(确保在你的 JAR 的类路径中包含 .),然后从中读取驱动程序名称,并使用 Class.forName() 加载驱动程序。

      你可以做一些更有趣的事情(比如在运行时找到正确的 jar 并动态加载它,即使它不在类路径上)但是这些事情有点复杂,所以像上面这样简单的事情应该可以工作。

      您永远不必重新编译。如果您在更改驱动程序时必须重新编译,那么您实际上并没有正确使用 JDBC。

      【讨论】:

      • 我可以对不在我的 ClassPath 上的 Jar 中的类执行 Class.ForName() 吗?如果没有,那么我仍然仅限于类路径中专门列出的 Jar,并且当新的驱动程序 jar 出现时仍然需要重新编译(重新 jar?)。
      • Class.forName 必须在类路径运行时。无需重新编译。当一个新的jar出来时,你只需替换文件,无需重新编译。
      • 微软有个很好的习惯,就是用不同的方式命名他们的驱动 jar 文件。
      【解决方案4】:

      您必须将驱动程序 jar 文件和特定提供程序的 JDBC 驱动程序的实际名称分开。

      我真的鼓励不要在您自己的 jar 中包含 jdbc 驱动程序 jar。 就在他们到运行时的路径。 同样,您可以在运行时从系统属性甚至配置文件中获取 JDBC 驱动程序管理器的名称。

      所以像这样运行应用程序:

      java -jar myapp.jar -cp sqlserver.jar -DdriverManager=com.microsoft.sqlserver.jdbc.SQLServerDriver -DdbUrl=jdbc:some:url
      

      在你的应用程序中,做这样的事情(我省略了异常处理):

      Class.forName(System.getProperty("driverManager"));
      Connection conn = DriverManager.getConnection(System.getProperty("dbUrl"))
      

      ;

      这样,您只需将适当的 jar 文件添加到类路径并更改 driverManager 和 dbUrl 属性即可更改驱动程序。这样您就不必重新编译来支持新的驱动程序。

      这是我能想到的最简单的解决方案。

      【讨论】:

      • 我可以对不在我的 ClassPath 上的 Jar 中的类执行 Class.ForName() 吗?如果没有,那么我仍然仅限于类路径中特别列出的 jar,并且当新的驱动程序 jar 出现时仍然需要重新编译(重新 jar?)。
      • 在 Class.forName() 中,您提供了一个字符串,因此您可以在其中放置您想要的任何内容,并捕获异常以查看是否找到了某些内容。但。为什么要硬编码 Class.forName() ?上面提供的解决方案允许您在运行时更改它,这样您的应用程序就可以支持任何数据库,只要提供正确的 driverManager 和 db url(并且带有数据库驱动程序的 jar 在类路径中)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 2013-06-30
      • 1970-01-01
      相关资源
      最近更新 更多