Liquibase执行Update时抛出IllegalArgumentException: URI非层级化
问题
我在一个简单项目中使用Liquibase,搭建了连接PostgreSQL数据库的Spring Boot项目并添加了Liquibase依赖,pom.xml依赖配置如下:
[OMISSIS] <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Liquibase --> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>3.6.2</version> </dependency> </dependencies> [OMISSIS]
创建了User.java实体类:
package [OMISSIS].liquidemo.entity; import jakarta.persistence.*; import lombok.Data; @Data @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; }
在src/main/resources/db/changelog目录下创建了db.changelog-master.xml文件,成功生成项目基线changelog。但执行Liquibase Update命令时,抛出java.lang.IllegalArgumentException: URI is not hierarchical异常,错误栈信息如下:
[OMISSIS]/java liquibase.integration.commandline.Main --driver org.postgresql.Driver --changeLogFile db/changelog/db.changelog-master.xml --url jdbc:postgresql://[DATABASE_URL]:[DATABASE_PORT]/[DATABASE_NAME] --username [USERNAME] --password [PASSWORD] update Starting Liquibase at [OMISSIS] CET (version 3.6.2 built at 2018-07-03 11:28:09) Unexpected error running Liquibase: URI is not hierarchical java.lang.IllegalArgumentException: URI is not hierarchical at java.base/java.io.File.<init>(File.java:420) at liquibase.resource.FileSystemResourceAccessor.addRootPath(FileSystemResourceAccessor.java:51) at liquibase.resource.AbstractResourceAccessor.init(AbstractResourceAccessor.java:39) at liquibase.resource.FileSystemResourceAccessor.init(FileSystemResourceAccessor.java:44) at liquibase.resource.FileSystemResourceAccessor.<init>(FileSystemResourceAccessor.java:26) at liquibase.integration.commandline.Main.doMigration(Main.java:949) at liquibase.integration.commandline.Main.run(Main.java:191) at liquibase.integration.commandline.Main.main(Main.java:129) For more information, please use the --logLevel flag
请问这是什么原因?
原因及解决方案
核心原因
- 版本兼容性问题:使用的Liquibase 3.6.2是2018年的旧版本,对Java 9及以上的模块系统支持不完善。错误栈显示依赖
java.base/java.io.File,说明运行环境是Java 9+,旧版Liquibase的资源访问逻辑未适配新的URI处理规则,导致将类路径资源URI转换为File对象时失败。 - 路径解析错误:执行命令的工作目录可能不在项目根目录,导致
--changeLogFile指定的相对路径无法映射为本地文件路径,触发URI解析异常。 - 资源加载方式错误:直接通过命令行运行时,若changelog文件在类路径(如
src/main/resources)中,未使用classpath:前缀指定路径,Liquibase会强制当作本地文件处理,无法正确加载类路径内的资源。
解决步骤
- 升级Liquibase版本
将pom.xml中的Liquibase依赖升级到支持Java 9+的4.x系列版本(推荐4.20+),修复版本兼容问题:
<dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>4.20.0</version> </dependency>
调整命令执行路径
确保执行命令时处于项目根目录下,让db/changelog/db.changelog-master.xml相对路径能正确指向目标文件。修改changeLogFile路径前缀
若changelog文件在类路径中,将命令中的路径改为带classpath:前缀的形式,让Liquibase通过类路径加载资源:
--changeLogFile classpath:db/changelog/db.changelog-master.xml
- 使用Spring Boot集成方式执行
更推荐通过Maven插件集成Liquibase,利用Spring的资源加载机制避免路径问题。在pom.xml的build/plugins中添加:
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>4.20.0</version> <configuration> <changeLogFile>src/main/resources/db/changelog/db.changelog-master.xml</changeLogFile> <driver>org.postgresql.Driver</driver> <url>jdbc:postgresql://[DATABASE_URL]:[DATABASE_PORT]/[DATABASE_NAME]</url> <username>[USERNAME]</username> <password>[PASSWORD]</password> </configuration> <executions> <execution> <phase>process-resources</phase> <goals> <goal>update</goal> </goals> </execution> </executions> </plugin>
执行mvn liquibase:update即可完成变更操作。
内容的提问来源于stack exchange,提问作者EM90
相关产品推荐
相关产品推荐

