If you have multiple jar files in your lib directory (i.e. diff-ing different RDBMs), the batch file will only include one of them in your classpath. This is apparently due to the use of SET in a dos FOR loop. SET is not evaluated until the for loop’s close so only the last thing in the set of files takes effect. The solution seems to be delayed variable expansion, but the requires the user to start a command prompt using CMD /v
Taken from the online SET help:
set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
in that it will NOT build up a list of files in the current directory,
but instead will just set the LIST variable to the last file found.
Again, this is because the %LIST% is expanded just once when the
FOR statement is read, and at that time the LIST variable is empty.
So the actual FOR loop we are executing is:
for %i in (*) do set LIST= %i
which just keeps setting LIST to the last file found.
Delayed environment variable expansion allows you to use a different
character (the exclamation mark) to expand environment variables at
execution time.
I haven’t done much .bat programming. Is there anything else we can do besides requiring starting the command prompt with /v? That seems like something we should not expect people to do.
Nathan
I’m sure something can be done. I haven’t done bat scripting in years. I didn’t see anything right away that looked promising and this got me up and running. I’ll poke around some more if I get some free time.
I solved the problem by calling a subroutine in FOR command this way (only lib directory is investigated):
set CP=.
for %%f in (%LIQUIBASE_HOME%lib*.jar) do call :addCP “%%f”
goto :continue
:addCP
set CP=%CP%;%1
rem echo %1
goto:eof
:continue
echo CP=%CP%
…
Jirka
Hi,
that bug should be fixed in 2.0 trunk. I sent a patch some time ago and nathan integrated it.
You can take it from there or use this to replace it:
@echo off
if "%OS%" == "Windows_NT" setlocal
setlocal enabledelayedexpansion
rem %~dp0 is expanded pathname of the current script under NT
set LIQUIBASE_HOME="%~dp0"
set CP=.
for /R %LIQUIBASE_HOME% %%f in (liquibase*.jar) do set CP=!CP!;%%f
for /R %LIQUIBASE_HOME%\lib %%f in (*.jar) do set CP=!CP!;%%f
rem get command line args into a variable
set CMD_LINE_ARGS=%1
if “”%1""=="""" goto done
shift
:setup
if “”%1""=="""" goto done
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setup
:done
set JAVA_OPTS=
java -cp “%CP%” %JAVA_OPTS% liquibase.commandline.Main %CMD_LINE_ARGS%
ah, setlocal… didn’t know about that. that’ll do it. thanks.