Search code examples
windowsparsingjvm-arguments

How to parse JVM Command Line to add additional switches using Windows Batch Script


With the help of @Magoo in a previous question, I could write a batch script to parse text files with key/value pairs and load the keys as environment variables. Following is the script:

@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
rem This script ready text file and parses key/value pairs and loads the keys and their values as environment variables

SET "configfile=.\testconfigfile.txt"

:: remove variables starting count_
FOR  /F "delims==" %%e In ('set count_ 2^>Nul') DO SET "%%e="

FOR /f "usebackq tokens=1* delims==" %%b IN ("%configfile%") DO (
 IF "%%c" neq "" (
  set keyname=%%b
  echo Key Name = !keyname!
  if "!keyname:~-4!"=="_arr" (
    IF DEFINED count_%%b (SET /a count_%%b+=1) ELSE (SET /a count_%%b=0)
    SET "!keyname![!count_%%b!]=%%c"
  ) else (
    SET "!keyname!=%%c"
  )
 )
)
SET count
SET |FIND "["
SET do_
SET delete_

GOTO :EOF

Now I have a batch script apply_jvm_changes.bat that must parse the Java command line used to launch a Java Program and add additional JVM switches.

The batch script to be updated looks like the following:

%JRE_HOME%\bin\java.exe -Xbootclasspath/p:path1;path2; -classpath path1;path2; -Dswitch1 -Dswitch2 -Dhttps.protocol="TLSv1.2" -Dswitch3 -DswitchN com.main.class pram1 pram2 pramN

I want to parse the file and update it by adding -Djavax.net.ssl.trustStore="path\to\cacerts" -Djavax.net.ssl.trustStorePassword=changeit to look like the following:

%JRE_HOME%\bin\java.exe -Xbootclasspath/p:path1;path2; -classpath path1;path2; -Dswitch1 -Dswitch2 -Dhttps.protocol="TLSv1.2" -Dswitch3 -DswitchN -Djavax.net.ssl.trustStore="path\to\cacerts" -Djavax.net.ssl.trustStorePassword=changeit com.main.class pram1 pram2 pramN

Note that the addition need to be inserted before com.main.class pram1 pram2 pramN part in the above command line.

I am trying to figure out how to do that using batch script or other tool I appreciate your help.


Solution

  • @ECHO OFF
    SETLOCAL
    
    SET "jre_home=wherever"
    
    SET "original=%%JRE_HOME%%\bin\java.exe -Xbootclasspath/p:path1;path2; -classpath path1;path2; -Dswitch1 -Dswitch2 -Dhttps.protocol="TLSv1.2" -Dswitch3 -DswitchN com.main.class"
    SET "addition=-Djavax.net.ssl.trustStore="path\to\cacerts" -Djavax.net.ssl.trustStorePassword=changeit"
    
    SET "before=com.main.class"
    
    :: FOR %%e IN (%original%) DO SET "before=%%e"
    CALL SET "finalxxx=%%original:%before%=%addition% %before%%%"
    
    SET original
    SET finalxxx
    
    GOTO :EOF
    

    Not enough information to provide a proper answer - I've made a number of assumptions.

    First, I don't have a variable jre_home, so I simply assigned one.

    Next, there's no indication of whether the strings are fixed or may contain poison characters (those characters with special meaning to batch which may cause unexpected results.) % is one of those characters. In order to preserve the % in the original value, it needs to be "escaped" by an additional %.

    There's no indication of what the formula is for the insert-point. I've assumed that the new string is to be inserted before the last token of the original string.

    So - locate the last string (assumed to be unique) as before, then replace that string with addition+thestring. This uses the call set "var1=%%var2:%string1%=%string2%%%" syntax. To make this a little more obvious, the elements involved are call set "var1=%%var2: %string1% = %string2% %%" which executes set "var1=%var2: string1 = string2 %" in a subshell.

    Then show original and finalxxx - using variable-names with the same length makes them easier to compare.

    Since it now appears that the insertion point is before the unique constant string com.main.class, before is known hence it can simply be set. I've commented-out the original establishment of before to allow the narrative to make sense.