SpringBoot loader.path 无法加载外部 Jar

8

我正在使用Spring Boot开发Web应用程序,并试图设置一个外部目录,用于存放各种JDBC驱动程序,最终用户可以选择使用。为了做到这一点,我正在添加:

loader.path=/opt/myapp/lib/

将以下内容添加到application.properties文件中,PropertySourcesPropertyResolver会自动获取:

2016-04-28 17:27:38.739 DEBUG 22539 --- [restartedMain] o.s.c.e.PropertySourcesPropertyResolver  : Found key 'loader.path' in [applicationConfigurationProperties] with type [String] and value '/opt/myapp/lib/'

我的问题是我似乎无法从任何放入此���录的jar文件中加载任何JDBC驱动程序,我缺少什么?我正在使用默认的嵌入式Tomcat服务器。当我尝试使用Class.forName加载驱动程序时,我会得到以下错误消息,就好像这些jar文件不存在于该目录中。

 public Connection buildConnection(DataSource dataSource) throws ClassNotFoundException, SQLException {

    if (dataSource == null) {
        throw new NullPointerException("Data Source is null!");
    }

    if (!dataSource.isReady()) {
        throw new IllegalArgumentException("Data Source is reporting that it is not ready!");
    }

    logger.debug("Loading JDBC Driver: {}", dataSource.getDriverClass());
    Class.forName(dataSource.getDriverClass());
    logger.debug("Loaded Driver: {}", dataSource.getDriverClass());

    logger.debug("Attempting to build connection using: {}", dataSource.getConnectionString());

    DriverManager.setLoginTimeout(10);
    Connection c = DriverManager.getConnection(dataSource.getConnectionString(), dataSource.getUserName(), dataSource.getPassword());
    if (c != null) {
        c.setAutoCommit(true);
        c.setReadOnly(true);
        return c;
    }
    throw new NullPointerException("Unable to create connection!");
} 

这是抛出的异常。

2016-04-28 17:38:53.525 DEBUG 22539 --- [nio-8081-exec-5] c.c.reportout.processor.JobProcessor     : Loading JDBC Driver: com.mysql.jdbc.Driver
2016-04-28 17:38:53.526  WARN 22539 --- [nio-8081-exec-5] c.c.reportout.processor.JobProcessor     : Unable to successfully test connection: com.mysql.jdbc.Driver

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_91]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_91]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_91]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_91]
at org.springframework.boot.devtools.restart.classloader.RestartClassLoader.loadClass(RestartClassLoader.java:151) ~[spring-boot-devtools-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_91]
at java.lang.Class.forName0(Native Method) ~[na:1.8.0_91]
at java.lang.Class.forName(Class.java:264) ~[na:1.8.0_91]

有什么提示可以帮助我调试或者说明我做错了什么吗?谢谢。

你是如何构建和打包你的应用程序的?只有在使用PropertiesLauncher时,loader.path才会生效。 - Andy Wilkinson
是的,我做了。我刚刚构建了jar包并使用java -jar MyApp-1.0-SNAPSHOT.jar运行它,结果得到了相同的结果。 - csyperski
如果我将jdbc驱动程序依赖项添加到我的pom中,显然它可以工作,但是出于某种原因,我无法从外部目录加载它。 - csyperski
1个回答

16

所以在经过大量谷歌搜索后,我发现只需要添加以下内容就能解决这个问题:

<configuration>
    <layout>ZIP</layout>
</configuration>

在我的pom文件中添加 spring-boot-maven-plugin 插件。因此,现在的工作版本看起来是这样的:

<plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring-boot.version}</version>
            <configuration>
                <layout>ZIP</layout>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>

如果有帮助的话,据我所知,这只是告诉Spring Boot在运行可执行jar时使用PropertiesLauncher,而不是在使用mvn spring-boot:run时。 - Sean Connolly
额外说明: 生成完全可执行的jar包(通过添加<executable>true</executable><layout>ZIP</layout>两个属性), 我不得不使用环境变量LOADER_PATH代替loader.path属性。 - xonya
正如 @xonya 所指出的那样, LOADER_PATH 是有效的,而不是 loader.path 属性。 - ReeniMathew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接