【发布时间】:2017-09-13 12:21:02
【问题描述】:
tl;dr: 我们的 Spring Boot jar 中的类似乎可以看到捆绑 jar 中的类,但它们的内容似乎不能。为什么?
我们的主要产品是一个网络应用程序,但所有业务逻辑都集中在一个核心 mac-guffin-api.jar 中。 mac-guffin-api.jar 不是 Spring Boot 项目,但有一个名为 net.initech.api.Configuration 的 Spring Java 配置文件,用于初始化所有服务和存储库等。我们使用 MS SQL Server 作为我们的后端,sqljdbc42:jar司机。
我们需要编写一个 ETL,该 ETL 需要重用 API 项目中的相同业务逻辑,因此我们创建了一个 Spring Boot Spring Batch 项目,该项目将 mac-guffin-api.jar 作为 Maven 依赖项导入。 ETL 的配置 (net.initech.etl.Configuration) 导入的 API 配置没有问题(我可以从控制台日志中看到)但是当 API 配置去创建数据库连接时找不到驱动程序。
Caused by: java.lang.ClassNotFoundException: 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:94)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:246)
... 113 more
但是,我可以清楚地看到包含驱动程序的 JAR 存在。 ETL jar 的内容是(Nb: mac-guffin-api.jar 和 sqljdbc42-4.2.jar 未解包,它们是 ETL jar 中的 jar):
mac-guffin-etl.jar
|
+- org.springframework.boot.loader...
|
+- BOOT-INF
|
+- classes
| |
| +- com.initech.etl.Main.class
| |
| +- com.initech.etl.Configuration.class
|
+- lib
|
+- mac-guffin-api.jar
| |
| +- com.initech.api.Configuration.class
|
+- sqljdbc42-4.2.jar
|
+- com.microsoft.sqlserver.jdbc.SQLServerDriver.class
所以显然ETL类的配置类可以看到包含的JAR的内容(或至少API jar的内容),但他们的API jar似乎无法在SQL Server中看到com.microsoft.sqlserver.jdbc.SQLServerDriver.class JDBC jar。
我什至可以在 Spring 上下文实例化之前执行 Class.forName( "com.microsoft.sqlserver.jdbc.SQLServerDriver.class" ) 并且没有问题。
这是类加载器的限制吗?这是因为API项目不是Spring Boot吗?是因为缺少配置参数吗?这里发生了什么?
【问题讨论】:
-
有趣的问题...可能是一些事情。你有什么方法可以在 GitHub 上分享一个非常小的、可重复的项目吗? stackoverflow.com/help/mcve
-
我记不太清了,但是类名总是出现在引号中吗?单引号也似乎有点非java
标签: spring-boot jar classloader