Skip to content

Commit c5003d9

Browse files
fix: Support reading liquibase.classpath from properties file (liquibase#7394)
Fixes liquibase#6194 The classpath property was being ignored when specified in liquibase.properties after version 4.19.0, causing "Cannot find database driver" errors. Root cause: The regex pattern in ParameterUtil only matched the short form "classpath" but not the official configuration key "liquibase.classpath". Changes: - Modified ParameterUtil.getPropertyFromInputStream() to match both "classpath" and "liquibase.classpath" property keys - Added comprehensive unit tests covering both property formats, command line parsing, and edge cases This maintains backward compatibility while fixing the issue where users had to use --classpath on command line as a workaround.
1 parent 418b9a4 commit c5003d9

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

liquibase-cli/src/main/java/liquibase/integration/commandline/util/ParameterUtil.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ private static String getPropertyFromInputStream(String cmd, InputStream default
8181
if (defaultsStream != null) {
8282
Properties properties = new Properties();
8383
properties.load(defaultsStream);
84+
// Match both "key" and "liquibase.key" forms (e.g., "classpath" and "liquibase.classpath")
85+
String pattern = "(liquibase\\.)?" + cmd;
8486
Optional<Map.Entry<Object, Object>> property = properties.entrySet().stream()
85-
.filter(entry -> entry.getKey().toString().matches(cmd))
87+
.filter(entry -> entry.getKey().toString().matches(pattern))
8688
.findFirst();
8789
if (property.isPresent()) {
8890
return property.get().getValue().toString();
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package liquibase.integration.commandline.util;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.io.TempDir;
5+
6+
import java.io.File;
7+
import java.io.FileWriter;
8+
import java.io.IOException;
9+
import java.nio.file.Path;
10+
11+
import static liquibase.util.LiquibaseLauncherSettings.LiquibaseLauncherSetting.LIQUIBASE_CLASSPATH;
12+
import static org.junit.jupiter.api.Assertions.assertEquals;
13+
import static org.junit.jupiter.api.Assertions.assertNull;
14+
15+
/**
16+
* Tests for ParameterUtil, specifically for reading parameters from properties files.
17+
*/
18+
public class ParameterUtilTest {
19+
20+
@Test
21+
public void testGetParameter_classpathFromPropertiesFile_shortForm(@TempDir Path tempDir) throws IOException {
22+
// Create a temporary properties file with "classpath" (short form)
23+
File propertiesFile = tempDir.resolve("liquibase.properties").toFile();
24+
try (FileWriter writer = new FileWriter(propertiesFile)) {
25+
writer.write("classpath=../drivers/mssql-jdbc-12.6.1.jre11.jar;./liquibase/db-migration.jar\n");
26+
}
27+
28+
String[] args = {"--defaults-file=" + propertiesFile.getAbsolutePath()};
29+
30+
String result = ParameterUtil.getParameter(LIQUIBASE_CLASSPATH, "classpath", args, true);
31+
32+
assertEquals("../drivers/mssql-jdbc-12.6.1.jre11.jar;./liquibase/db-migration.jar", result);
33+
}
34+
35+
@Test
36+
public void testGetParameter_classpathFromPropertiesFile_longForm(@TempDir Path tempDir) throws IOException {
37+
// Create a temporary properties file with "liquibase.classpath" (long form)
38+
File propertiesFile = tempDir.resolve("liquibase.properties").toFile();
39+
try (FileWriter writer = new FileWriter(propertiesFile)) {
40+
writer.write("liquibase.classpath=../drivers/mssql-jdbc-12.6.1.jre11.jar;./liquibase/db-migration.jar\n");
41+
}
42+
43+
String[] args = {"--defaults-file=" + propertiesFile.getAbsolutePath()};
44+
45+
String result = ParameterUtil.getParameter(LIQUIBASE_CLASSPATH, "classpath", args, true);
46+
47+
assertEquals("../drivers/mssql-jdbc-12.6.1.jre11.jar;./liquibase/db-migration.jar", result);
48+
}
49+
50+
@Test
51+
public void testGetParameter_classpathFromPropertiesFile_notPresent(@TempDir Path tempDir) throws IOException {
52+
// Create a temporary properties file without classpath
53+
File propertiesFile = tempDir.resolve("liquibase.properties").toFile();
54+
try (FileWriter writer = new FileWriter(propertiesFile)) {
55+
writer.write("driver=com.microsoft.sqlserver.jdbc.SQLServerDriver\n");
56+
}
57+
58+
String[] args = {"--defaults-file=" + propertiesFile.getAbsolutePath()};
59+
60+
String result = ParameterUtil.getParameter(LIQUIBASE_CLASSPATH, "classpath", args, true);
61+
62+
assertNull(result);
63+
}
64+
65+
@Test
66+
public void testGetParameter_classpathFromCommandLine() throws IOException {
67+
String[] args = {"--classpath=../drivers/test.jar"};
68+
69+
String result = ParameterUtil.getParameter(LIQUIBASE_CLASSPATH, "classpath", args, false);
70+
71+
assertEquals("../drivers/test.jar", result);
72+
}
73+
74+
@Test
75+
public void testGetParameter_classpathFromCommandLine_withSpace() throws IOException {
76+
String[] args = {"--classpath", "../drivers/test.jar"};
77+
78+
String result = ParameterUtil.getParameter(LIQUIBASE_CLASSPATH, "classpath", args, false);
79+
80+
assertEquals("../drivers/test.jar", result);
81+
}
82+
}

0 commit comments

Comments
 (0)