我正在尝试调试TopCoder提供的下面的启动脚本,以启动其用于制作UML图的Java应用程序。
@echo off
setlocal
cd /d "%~dp0"
set CP=.
for /r ./lib %%V IN (*.jar) DO call :pathmunge "%%V"
call :pathmunge .\resources
call :pathmunge .\conf
start javaw -Xmx256m -cp %CP% com.topcoder.umltool.deploy.UMLToolDeploy %1 %2 %3 %4
endlocal
goto :eof
:pathmunge
set CP=%CP%;%1
从命令行运行时,脚本会抛出错误。
The input line is too long.
The syntax of the command is incorrect.
所以,我试着深入研究这个名为run.cmd
的脚本正在做什么。我理解以javaw
开头的语句是启动应用程序的语句,它还需要四个参数。我无法找到这些论点的来源。
另外,我了解FOR
循环以递归方式从./lib
获取所有文件并将其添加到Classpath
。它是怎么做到的? (语法明智)
请让我也知道我错过的其他“精美版画”。
我希望我能够使用答案中提供的说明来解决问题的根源。
系统详细信息:Windows 8 x64,非管理员帐户。
答案 0 :(得分:1)
首先,通过将第一行批处理文件更改为@echo on
,您可以在命令提示符窗口中看到执行此批处理文件时cmd.exe
如何在执行期间逐行解释和处理此批处理文件
批处理文件首先将当前工作目录设置为批处理文件的目录,该文件显然是Java的目录。
pathmunge
是一个标签,在Java中被称为函数。 pathmunge
下面的代码是函数体。在此批处理文件中,函数pathmunge
只有一个代码行:
set CP=%CP%;%1
这是等效的批处理代码,用于将字符串附加到存储在环境变量CP
中的另一个字符串,这显然是类路径的缩写。
CP
的初始值仅为.
,表示当前目录。
每次调用pathmunge
时,* .jar文件的名称都会在当前工作目录(批处理文件的目录)的子目录lib
中找到完整路径,或者在其中一个子目录后附加分号。
如果* .jar文件的名称中包含完整路径的1个或多个空格,则文件名将附加在双引号中。这不正确,因为运行javaw.exe
的整个类路径字符串应该用双引号括起来,而不是每个* .jar文件。
%1
中的 pathmunge
引用第一个函数参数 - 调用FOR
时从pathmunge
循环传递的* .jar文件的名称。
根据批处理文件目录的子目录lib
中* .jar文件的数量,环境变量CP
中的字符串可能会变得很长,太长而无法由{{1 },请参阅Command prompt (Cmd. exe) command-line string limitation。
这是你的问题。有太多* .jar文件,这些文件的完整路径附加到一个非常长的字符串,最后太长时间无法进一步处理。
附加到类路径目录列表字符串也是具有相对路径的两个子目录cmd.exe
和resources
。
使用conf
引用用于启动批处理文件的前4个参数的字符串值作为参数传递给%1 %2 %3 %4
。如果您只是双击批处理文件,那么这4个变量都是空的。
最好是遵循代码(很可能是因为我没有使用Java测试过):
javaw.exe
现在不添加双引号的完整文件名而不是将每个* .jar文件的名称附加到双引号的完整路径中,而是在运行时将整个类路径字符串括在双引号中@echo off
setlocal
cd /D "%~dp0"
set "CP=."
for /R .\lib %%V in (*.jar) do call :pathmunge "%%V"
call :pathmunge .\resources
call :pathmunge .\conf
start "" javaw.exe -Xmx256m -cp "%CP%" com.topcoder.umltool.deploy.UMLToolDeploy %*
endlocal
goto :EOF
:pathmunge
set "CP=%CP%;%~1"
。
由于CP
而不是javaw.exe
,启动批处理文件时指定的所有参数现在都会根据其号码传递给javaw.exe
。
可能有助于避免将子目录%*
及其子目录中的* .jar文件附加到相对路径而不是完整路径。这使得类路径字符串更短。下面的批处理代码使用相对路径附加* .jar文件。
%1 %2 %3 %4
如果您想了解其中一个命令的更多信息,请打开命令提示符窗口并运行带参数lib
的命令,如
@echo off
setlocal EnableDelayedExpansion
set "UmlToolDirectory=%~dp0"
cd /D "%UmlToolDirectory%"
set "CP=."
for /R .\lib %%V in (*.jar) do (
set "LibraryFile=%%V"
set "LibraryFile=!LibraryFile:%UmlToolDirectory%=.\!"
call :pathmunge "!LibraryFile!"
)
call :pathmunge .\resources
call :pathmunge .\conf
start "" javaw.exe -Xmx256m -cp "%CP%" com.topcoder.umltool.deploy.UMLToolDeploy %*
endlocal
goto :EOF
:pathmunge
set "CP=%CP%;%~1"