在Java开发中,使用Maven来管理项目依赖是一种非常常见且方便的方式。然而,对于Oracle JDBC Driver的依赖管理却稍显特殊,因为Oracle并没有将其JDBC Driver发布到公开的Maven仓库中。本文将详细介绍如何通过手动安装到本地仓库以及使用<scope>system</scope>
的方式来引入Oracle JDBC Driver依赖,并探讨在SpringBoot项目中可能遇到的坑及其解决方法。
前言
由于Oracle JDBC Driver并未公开发布到Maven中央仓库,我们无法像引入MySQL、SQLite等数据库驱动那样直接通过Maven加载依赖。因此,我们需要手动下载Oracle JDBC Driver的Jar包,并将其安装到本地Maven仓库(.m2目录或自定义的localRepository)中,或者通过<scope>system</scope>
的方式引入。
手动安装到本地仓库
-
下载Oracle JDBC Driver Jar包
首先,我们需要从Oracle官网下载所需的JDBC Driver Jar包,例如
ojdbc7-12.1.0.2.jar
。 -
将Jar包放置到项目目录中
将下载的
ojdbc7-12.1.0.2.jar
放置到项目的根目录下的lib
目录中,以便随项目进行版本管理。 -
在POM.xml中加入依赖定义
在项目的
POM.xml
文件中加入以下依赖定义(但暂时不指定具体路径,因为接下来我们会通过命令行安装):xml<dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc7</artifactId> <version>12.1.0.2</version> </dependency>
注意:这里的
<groupId>
和<artifactId>
可以根据实际情况自定义。 -
安装JAR包到本地仓库
使用以下Maven命令将Jar包安装到本地仓库:
bashmvn install:install-file -Dfile=lib/ojdbc7-12.1.0.2.jar -DgroupId=com.oracle -DartifactId=ojdbc7 -Dversion=12.1.0.2 -Dpackaging=jar
执行上述命令后,Oracle JDBC Driver将被安装到本地Maven仓库中,之后Maven在构建项目时就能够找到这个依赖。
使用<scope>system</scope>
方式引入
除了手动安装到本地仓库外,我们还可以在POM.xml
中将依赖定义为<scope>system</scope>
。这种方式下,即使本地仓库(.m2目录)下没有Oracle JDBC Driver依赖,执行mvn compile
和mvn spring-boot:run
依然能够成功执行。
示例代码:
xml
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/ojdbc7-12.1.0.2.jar</systemPath>
</dependency>
注意 :<systemPath>
需要指定为Jar包的绝对路径或相对于项目的路径。
<scope>system</scope>
在SpringBoot中的坑
虽然使用<scope>system</scope>
可以方便地在开发环境中运行SpringBoot应用,但在执行mvn package
打包时,生成的SpringBoot UberJar包中并不会包含Oracle JDBC Driver依赖。直接部署到服务器上会报错,如:
############ application failed to start
Description: ..................................
Reason: Failed to load driver class oracle.jdbc.driver.OracleDriver in either of HikariConfig class loader or Thread context classloader.
Action: Update your application's configuration ############
解决方法:
-
对于外置Web容器的SpringBoot应用,将Oracle JDBC Driver Jar包放置在容器的
lib
目录下。 -
对于内置Web容器的SpringBoot应用,修改
spring-boot-maven-plugin
插件配置:xml<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <includeSystemScope>true</includeSystemScope> </configuration> </plugin> </plugins> </build>
通过配置
<includeSystemScope>true</includeSystemScope>
,可以使得scope
为system
的Jar包也被打包到最终的发布包中。
Maven依赖定义中的scope
属性
scope
属性用于限制依赖在Maven项目各生命周期的作用范围。常见的scope
值有:
- compile:默认值,依赖将参与编译阶段,并会被打包到最终发布包(如Jar、War、UberJar)内的Lib目录下。具有传递性。
- provided:依赖将参与编译阶段但不会被打包到最终的发布包,运行阶段由容器或JDK提供。不具备传递性。
- runtime:依赖不参与编译阶段(即不加入到classpath),但会打包到最终发布包,从而参与运行和测试阶段。
- test:依赖参加编译阶段,但不打包到最终发布包,依赖仅参与测试阶段。
- system :表示该依赖项的路径为基于文件系统的Jar包路径,并且必须通过
systemPath
指定本地文件路径。依赖参与编译阶段,默认不会被打包到最终发布包。 - import (仅能在
<dependencyManagement>
中使用):用于引用其它项目的依赖项。
示例:
xml
<!-- 引入项目io.fsjohnhuang.deps的依赖项 -->
<dependencyManagement>
<dependency>
<groupId>io.fsjohnhuang</groupId>
<artifactId>deps</artifactId>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
关于type
属性,默认的type
属性值为jar
,即Maven将项目编译打包为Jar包。当设置为pom
时,表示该项目为一堆相关依赖项的打包定义。当设置为apk
或ejb
等时,表示Maven在编译打包时采用相应的插件执行任务。