tl;dr:我们Spring中的类似乎在捆绑的jar中看到了类,但是它们的内容似乎不能。为什么?
我们的主要产品是一个web应用程序,但是所有的业务逻辑都集中在一个核心的mac-guffin-api.jar
中。mac-guffin-api.jar
不是Spring项目,而是一个名为net.initech.api.Configuration
的Spring文件,用于初始化所有服务和存储库等。我们使用MS作为后端,并使用sqljdbc42:jar
驱动程序。
我们需要编写一个ETL,它需要重用来自API项目的相同业务逻辑,因此我们创建了一个项目,该项目将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
但是,我可以清楚地看到,包含驱动程序的罐子是存在的。ETL的内容如下(Nb: mac-guffin-api.jar
和sqljdbc42-4.2.jar
未解压缩,它们是ETL中的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的内容),但是它们似乎无法在同类的Server中看到com.microsoft.sqlserver.jdbc.SQLServerDriver.class
。
我甚至可以在Spring上下文实例化之前执行一个Class.forName( "com.microsoft.sqlserver.jdbc.SQLServerDriver.class" )
,而且它没有问题。
这是类加载器的限制吗?这是因为API项目不是Spring吗?是因为缺少配置参数吗?这里发生什么事情?
发布于 2017-04-22 04:11:06
在您的配置中,您最终得到了用作值的类名:
'com.microsoft.sqlserver.jdbc.SQLServerDriver'
上面有单引号。通常,要加载的类名不带双引号或单引号。
这将解释为什么您能够加载类,但是API jar不能加载。检查设置驱动程序名称的配置/生成文件。
演示
我唯一能收到像你这样的信息的方法是:
Caused by: java.lang.ClassNotFoundException: 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
而不是:
Caused by: java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
是故意要求加载名称中带有单引号的类。例如:
import java.lang.*;
public class myclass {
public static void test(String thename) {
System.out.println("trying " + thename);
try {
myclass test = (myclass) myclass.class
.getClassLoader()
.loadClass(thename)
.newInstance();
System.out.println(test.toString());
} catch (Exception e){
System.out.println("failed to load " + thename);
e.printStackTrace();
}
}
public static void main(String[] args) {
test("my.package.itwontexist");
test("'my.package.itwontexist'");
}
}
产出:
trying my.package.itwontexist
failed to load my.package.itwontexist
java.lang.ClassNotFoundException: my.package.itwontexist
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at myclass.test(myclass.java:10)
at myclass.main(myclass.java:20)
trying 'my.package.itwontexist'
failed to load 'my.package.itwontexist'
java.lang.ClassNotFoundException: 'my.package.itwontexist'
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at myclass.test(myclass.java:10)
at myclass.main(myclass.java:21)
发布于 2017-04-26 19:18:21
您可能是从配置中获得驱动程序值的。
'com.microsoft.sqlserver.jdbc.SQLServerDriver‘= my.driver
该配置使用单引号返回值。请检查您的配置文件。
发布于 2017-04-27 13:39:48
看起来,您缺少了指导Spring如何加载嵌套jars的MANFIEST.MF文件。这里是Spring文档中的一个示例层次结构。您可以阅读如何配置它到这里来。
MANIFEST.MF应该包含此内容(用于下面的结构):
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.mycompany.project.MyApplication
Start-Class
是您进入应用程序的入口点,Main-Class
是加载嵌套jars所需的加载器。
示例结构:
example.war
|
+-META-INF
| +-MANIFEST.MF
+-org
| +-springframework
| +-boot
| +-loader
| +-<spring boot loader classes>
+-WEB-INF
+-classes
| +-com
| +-mycompany
| +-project
| +-YourClasses.class
+-lib
| +-dependency1.jar
| +-dependency2.jar
+-lib-provided
+-servlet-api.jar
+-dependency3.jar
https://stackoverflow.com/questions/43458991
复制相似问题