execute bat with java program in task scheduler fail - java

I have the following script, which works fine if executed manually, but does not work if set as a task in the task scheduler.
I suspected a parameter may not be set correctly, but cannot spot it. Could someone please help me with that.
#echo off
setlocal EnableDelayedExpansion
cls
set AllSections=
Set Action=
rem set PARMS=-Xms64M -Xmx512M -Dfile.encoding=UTF-8 -Dsikuli.FromCommandLine
rem set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_202
rem set SIKULIX_HOME=%~dp0
set CurrentDate=%Date%
set CurrentTime=%Time: =0%
set CurrentTime=%CurrentTime:~0,8%
set DateTimeStamp=%CurrentDate:~6,4%-%CurrentDate:~3,2%-%CurrentDate:~0,2%_%CurrentTime:~0,2%-%CurrentTime:~3,2%-%CurrentTime:~6,2%
set FolderTimeStamp=%CurrentDate:~3,2%-%CurrentDate:~6,4%
set DestinationFolder=SCADA\Output\%FolderTimeStamp%\%DateTimeStamp%
md DestinationFolder=SCADA\Output > nul 2>&1
md DestinationFolder=SCADA\Output\%FolderTimeStamp% > nul 2>&1
md DestinationFolder=SCADA\Output\%FolderTimeStamp%\%DateTimeStamp% > nul 2>&1
md DestinationFolder=SCADA\Output\%FolderTimeStamp%\%DateTimeStamp%\Settings > nul 2>&1
md DestinationFolder=SCADA\Output\%FolderTimeStamp%\%DateTimeStamp%\Alarms > nul 2>&1
md DestinationFolder=SCADA\Output\%FolderTimeStamp%\%DateTimeStamp%\Network > nul 2>&1
rem Create Settings file
rem echo "Hello world" > %cd%\aa.txt
rem \\\--below instructions working as script from command prompt , but not from task scheduler
C:\sikulix\sikulixapi-2.0.5-win.jar -r C:\sikulix\Scada\Settings.sikuli
C:\sikulix\sikulixapi-2.0.5-win.jar -r C:\sikulix\Scada\Alarms.sikuli
C:\sikulix\sikulixapi-2.0.5-win.jar -r C:\sikulix\Scada\Networks.sikuli
rem /////
ENDLOCAL
:End
I highlighted the bit that does not work; the folders are set correctly, but the java part fails to be executed in the task scheduler.

The script runs in your account because you have set up Windows such that the file extension .jar mapped to the java application. If the task scheduler account doesn't map .jar to java application then it won't work.
Re-write the script to prefix the lines using jars with a valid Java runtime such as %JAVA_HOME%/bin/java and ensure that JAVA_HOME is defined, or check that the task scheduler account maps .jar handling to a suitable JVM. Example:
xyz.jar param1 param2 ...
becomes
%JAVA_HOME%\bin\java --class-path xyz.jar param1 param2 ..
In Windows Explorer, you can check the mappings with right mouse -> Properties then see "Open with:" field.

Related

BASH to BATCH java

There's this BASH file:
#!/bin/bash
set -eu
DIR=`dirname $0`
JAR=$DIR/myjar.jar
CLASSPATH=$JAR:./
HEAP_SIZE=-size
java $HEAP_SIZE -cp $CLASSPATH something.something2 "$#"
That I want to turn into a .bat file to run on windows
This is what I have so far:
#ECHO OFF
set DIR = %cd%
set JAR = DIR/myjar.jar
set CLASSPATH = %JAR%:./
set HEAP_SIZE = -size
java %HEAP_SIZE% -cp %CLASSPATH% something.something2
How would I complete it to have the same behavior as the bash file?
%CD% can work, but your bash script seems to be setting the directory based off the path of the script (i.e., argument in $0) and not the current directory. To use the same directory as the batch file, you use %~dp0.
You missed % around your DIR variable when you wanted to expand the value.
You shouldn't have spaces around equal signs in your set statements.
The equivalent of $# in batch is %*.
You should quote your %CLASSPATH%. On Windows you are much more likely to encounter paths with spaces in them.
#ECHO OFF
set "DIR=%~dp0"
set "JAR=%DIR%/myjar.jar"
set "CLASSPATH=%JAR%:./"
set "HEAP_SIZE=-size"
java %HEAP_SIZE% -cp "%CLASSPATH%" something.something2 %*

Command line options to batch file (Java application)

I've a java application which I run using a batch file- start.bat
Batch file:
#echo off
rem (
set JAVA_HOME=.\jre7
rem echo %JAVA_HOME%
java.exe -jar app-0.0.1-SNAPSHOT.jar
rem )
Manifest file has the name of class which has public static main(String[] args) method, and that's the start point of application.
I run the application from command prompt by typing start.bat
Now I need to give command line arguments to this bat file that can be received by main method.
so the task is to pass command line parameters to batch file and then send those parameter to java class main method.
I was exploring apache cli library but not sure if it can help me.
Basically this should be the input:
start.bat -a :
if -a is there then do task A in java application
start.bat -b :
if -b is there then do task B in java application
start.bat -a -b :
do task A and B
Help appreciated.
Thanks !
As user882813 points out above, the easiest solution is, if you want your .bat file to accept the same switches as your .jar file, just append %* (the batch variable containing all arguments) to the Java command like this:
java.exe jar app-0.0.1-SNAPSHOT.jar %*
If your .jar file can't accept the same switches for some reason, here's a way you can script a translation within your batch script. If you check for the existence of -a and -b within %*, you can construct your java launch command appropriately. This should work even if the switches are in backward order (like start.bat -b -a).
#echo off
setlocal
set "JAVA_HOME=.\jre7"
set a=& set b=& set "args=%*"
if "%*" neq "" (
if "%args%" neq "%args:-a=%" set "a=1"
if "%args%" neq "%args:-b=%" set "b=1"
)
if defined a (
if defined b (
rem :: Do both A and B
set "cmdArgs=/ABswitch"
) else (
rem :: Do work A
set "cmdArgs=/Aswitch"
)
) else if defined b (
rem :: Do work B
set "cmdArgs=/Bswitch"
) else (
rem :: Do no work
set cmdArgs=
)
java.exe -jar app-0.0.1-SNAPSHOT.jar %cmdArgs%
A quick note about the if "%args%" neq "%args:-a=%" set "a=1" lines: this works by variable substring substitution. Basically, %args:-a=% is %args% with -a replaced with nothing. So if %args% does not equal the same thing with -a removed, it must contain -a. Therefore, set a=1. See this page for more info on batch variable string manipulation.
Try something like the following in your batch script (after you have checked if those command line params are actually passed):
IF "%1" == "-a" GOTO DOWORKA
IF "%2" == "-b" GOTO DOWORKB
//as a third meassure , check for both -a and -b and invoke :DOWORKAB label
:DOWORKA
//invoke java program with param a
:DOWORKB
//invoke java program with param b
:DOWORKAB
//invoke java program with param a and b

Switching between different JDK versions in Windows

I'm working on few projects and some of them are using different JDK. Switching between JDK versions is not comfortable. So I was wondering if there is any easy way to change it?
I found 2 ways, which should solve this problem, but it doesn't work.
First solution is creating a bat files like this:
#echo off
echo Setting JAVA_HOME
set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_72
echo setting PATH
set PATH=C:\Program Files\Java\jdk1.7.0_72\bin;%PATH%
echo Display java version
java -version
pause
And after running this bat, I see right version of Java. But when I close this CMD and open a new one and type "java -version" it says that I still have 1.8.0_25. So it doesn't work.
Second solution which I found is an application from this site. And it also doesn't work. The same effect as in the first solution.
Any ideas? Because changing JAVA_HOME and PAHT by: Win + Pause -> Advanced System Settings -> Environment Variables -> and editing these variables, is terrible way...
The set command only works for the current terminal. To permanently set a system or user environment variable you can use setx.
setx JAVA_HOME "C:\Program Files\Java\jdk1.7.0_72" /m
The /m option is used to set the variable system wide (and not just for the current user). The terminal must be run as administrator to use this option.
The variable will be available in all new terminal windows, but not the current one. If you also want to use the path in the same window, you need to use both set and setx.
You can avoid manipulating the PATH variable if you just once put %JAVA_HOME% in there, instead of the full JDK path. If you change JAVA_HOME, PATH will be updated too.
There are also a few environment variable editors as alternative to the cumbersome Windows environment variable settings. See "Is there a convenient way to edit PATH in Windows 7?" on Super User.
In case if someone want to switch frequently in each new command window then I am using following approach.
Command Prompt Version:
Create batch file using below code. You can add n number of version using if and else blocks.
#echo off
if "%~1" == "11" (
set "JAVA_HOME=C:\Software\openjdk-11+28_windows-x64_bin\jdk-11"
) else (
set "JAVA_HOME=C:\Program Files\Java\jdk1.8.0_151"
)
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
Save this batch file as SJV.bat and add this file location in your machine's Path environment variable. So now SJV will act as command to "Switch Java Version".
Now open new command window and just type SJV 11 it will switch to Java 11.
Type SJV 8 it will switch to Java 8.
PowerShell Version
Create powershell(ps1) file using below code. You can add n number of version using if and else blocks.
If($args[0] -eq "11")
{
$env:JAVA_HOME = 'C:\Software\openjdk-11+28_windows-x64_bin\jdk-11'
}else{
$env:JAVA_HOME = 'C:\Program Files\Java\jdk1.8.0_151'
}
$env:Path = $env:JAVA_HOME+'\bin;'+$env:Path
java -version
Save this script file as SJV.ps1 and add this file location in your machine's Path environment variable. So now SJV will act as command to "Switch Java Version".
Now open new powershell window and just type SJV 11 it will switch to Java 11.
Type SJV 8 OR SJV it will switch to Java 8.
I hope this help someone who want to change it frequently.
Open Environment Variables editor (File Explorer > right click on
This PC > Properties > Advanced system settings > Environment
Variables...)
Find Path variable in System variables list >
press Edit > put %JAVA_HOME%bin; at first position. This is required
because Java installer adds C:\Program Files (x86)\Common
Files\Oracle\Java\javapath to the PATH which references to the latest Java version installed.
Now you can switch between Java version using setx command (should be run under administrative permissions):
setx /m JAVA_HOME "c:\Program Files\Java\jdk-10.0.1\
(note: there is no double quote at the end of the line and should not be or you'll get c:\Program Files\Java\jdk-10.0.1\" in your JAVA_HOME variable and it breaks your PATH variable)
Solution with system variables (and administrative permissions) is more robust because it puts desired path to Java at the start of the resulting PATH variable.
If your path have less than 1024 characters can execute (Run as Administrator) this script:
#echo off
set "JAVA5_FOLDER=C:\Java\jdk1.5.0_22"
set "JAVA6_FOLDER=C:\Java\jdk1.6.0_45"
set "JAVA7_FOLDER=C:\Java\jdk1.7.0_80"
set "JAVA8_FOLDER=C:\Java\jdk1.8.0_121"
set "JAVA9_FOLDER=C:\Java\jdk-10.0.1"
set "CLEAR_FOLDER=C:\xxxxxx"
(echo "%PATH%" & echo.) | findstr /O . | more +1 | (set /P RESULT= & call exit /B %%RESULT%%)
set /A STRLENGTH=%ERRORLEVEL%
echo path length = %STRLENGTH%
if %STRLENGTH% GTR 1024 goto byebye
echo Old Path: %PATH%
echo ===================
echo Choose new Java Version:
echo [5] JDK5
echo [6] JDK6
echo [7] JDK7
echo [8] JDK8
echo [9] JDK10
echo [x] Exit
:choice
SET /P C=[5,6,7,8,9,x]?
for %%? in (5) do if /I "%C%"=="%%?" goto JDK_L5
for %%? in (6) do if /I "%C%"=="%%?" goto JDK_L6
for %%? in (7) do if /I "%C%"=="%%?" goto JDK_L7
for %%? in (8) do if /I "%C%"=="%%?" goto JDK_L8
for %%? in (9) do if /I "%C%"=="%%?" goto JDK_L9
for %%? in (x) do if /I "%C%"=="%%?" goto byebye
goto choice
#echo on
:JDK_L5
set "NEW_PATH=%JAVA5_FOLDER%"
goto setPath
:JDK_L6
#echo off
set "NEW_PATH=%JAVA6_FOLDER%"
goto setPath
:JDK_L7
#echo off
set "NEW_PATH=%JAVA7_FOLDER%"
goto setPath
:JDK_L8
#echo off
set "NEW_PATH=%JAVA8_FOLDER%"
goto setPath
:JDK_L9
#echo off
set NEW_PATH = %JAVA9_FOLDER%
:setPath
Call Set "PATH=%%PATH:%JAVA5_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA6_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA7_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA8_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA9_FOLDER%=%CLEAR_FOLDER%%%"
rem echo Interim Path: %PATH%
Call Set "PATH=%%PATH:%CLEAR_FOLDER%=%NEW_PATH%%%"
setx PATH "%PATH%" /M
call set "JAVA_HOME=%NEW_PATH%"
setx JAVA_HOME %JAVA_HOME%
echo New Path: %PATH%
:byebye
echo
java -version
pause
If more than 1024, try to remove some unnecessary paths, or can modify this scripts with some inputs from https://superuser.com/questions/387619/overcoming-the-1024-character-limit-with-setx
Run this BAT file to conveniently change the java version.
Pros:
It does NOT modify the PATH system environment variable.
The only thing that has to be maintained is the relational array (can be conveniently constructed as a sparse array) that holds the version number and the path at the beginning of the script.
Precondition:
The following entry %JAVA_HOME%\bin has to be appended to the PATH environment variable.
#echo off
#cls
#title Switch Java Version
setlocal EnableExtensions DisableDelayedExpansion
:: This bat file Switches the Java Version using the JAVA_HOME variable.
:: This script does NOT modify the PATH system environment variable.
:: Precondition: The following entry "%JAVA_HOME%\bin" has to be appended to the PATH environment variable.
:: Script Name: SwitchJavaVersion | Version 1 | 2021/11/04
rem Add items to vector as follows:
rem AvailableVersions["Java Major Version Number"]="Java Absolute Path"
set AvailableVersions[8]="D:\Program Files\Java\jdk8u252-b09"
set AvailableVersions[17]="D:\Program Files\Java\jdk-17.0.1"
call :PrintJavaVersion
call :PrintAvailableVersions
call :GetJavaVersion
call :SetJavaVersion
call :ResetLocalPath
if %errorlevel% neq 0 exit /b %errorlevel%
call :PrintJavaVersion
pause
endlocal
exit /b
rem Print available versions.
:PrintAvailableVersions
echo Available Java Versions:
for /f "tokens=2 delims=[]" %%I in ('set AvailableVersions[') do echo ^> %%I
exit /b
rem Get version from user input or command-line arguments.
:GetJavaVersion
set "JavaVersion="
if "%~1"=="" (
set /p JavaVersion="Type the major java version number you want to switch to: "
) else (
set /a JavaVersion="%~1"
)
exit /b
rem Update JAVA_HOME user variable with hardcoded paths.
:SetJavaVersion
set JavaPath=
for /f "tokens=2 delims=[]" %%I in ('set AvailableVersions[') do (
if "%%I" == "%JavaVersion%" (
setlocal EnableDelayedExpansion
set JavaPath=!AvailableVersions[%%I]!
setlocal EnableExtensions DisableDelayedExpansion
)
)
if not defined JavaPath (
echo "Specified version NOT found: Default settings applied."
for /f "tokens=2 delims==" %%I in ('set AvailableVersions[') do (
set JavaPath=%%I
goto exitForJavaPath
)
)
:exitForJavaPath
rem remove quotes from path
set JavaPath=%JavaPath:"=%
set "JAVA_HOME=%JavaPath%"
setx JAVA_HOME "%JAVA_HOME%"
rem setlocal statement was run 2 times previously inside the for loop; therefore, the endlocal statement must be executed 2 times to close those nested local scopes.
rem below endlocal statement will close local scope set by previous "setlocal EnableExtensions DisableDelayedExpansion" statement
endlocal & set "JavaPath=%JavaPath%"
rem JAVA_HOME's value rolls back due to endlocal statement so the appropriate value has to be reassigned
set "JAVA_HOME=%JavaPath%"
rem below endlocal statement will close local scope set by previous "setlocal EnableDelayedExpansion" statement
endlocal & set "JavaPath=%JavaPath%"
rem JAVA_HOME's value rolls back due to endlocal statement so the appropriate value has to be reassigned
set "JAVA_HOME=%JavaPath%"
exit /b
rem Get User and System Path variable's definition from Registry,
rem evaluate the definitions with the new values and reset
rem the local path variable so newly set java version
rem is properly displayed.
:ResetLocalPath
set "PathValue="
for /F "skip=2 tokens=1,2,*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V Path') do if /I "%%I" == "Path" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "PathValue=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "PathValue=%%~K"
if not defined PathValue goto pathError
set "UserPathValue="
for /F "skip=2 tokens=1,2,*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKCU\Environment" /V Path') do if /I "%%I" == "Path" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "UserPathValue=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "UserPathValue=%%~K"
if not defined UserPathValue goto pathError
call set "Path=%PathValue%;%UserPathValue%"
echo Path variable reset:
echo PATH=%Path%
echo.
exit /b
rem Display the Java version.
:PrintJavaVersion
echo Current Java Version:
java -version
echo.
exit /b
rem Error handling subroutine.
:pathError
echo.
echo Error while refreshing the PATH variable:
echo PathValue=%PathValue%
echo UserPathValue=%UserPathValue%
pause
exit /b 2
endlocal
exit
Load below mentioned PowerShell script at the start of the PowerShell. or generate the file using New-Item $profile -Type File -Force
this will create a file here C:\Users\{user_name}\Documents\WindowsPowerShell\Microsoft.PowerShell_profile
Now copy-paste the content given below in this file to be loaded each time the PowerShell is started
Set all the java versions you need as separate variables.
Java_8_home-> Points to Java 8 Location in local
Java_11_home -> Points to Java 11 Location in local
Java_17_home -> Points to Java 17 Location in local
Java_Home-> This points to the java version you want to use
Run in power shell to update the version to 8 update_java_version 8 $True
To update execution policy to allow script to be loaded at start of the PowerShell use below command
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
`
function update_java_version($version, [bool] $everywhere)
{
switch ($version)
{
8 {
$java_value = (Get-Item Env:Java_8_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
11 {
$java_value = (Get-Item Env:Java_11_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
17 {
$java_value = (Get-Item Env:Java_17_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
default {
throw "No matching java version found for `$version`: $version"
}
}
if ($everywhere)
{
[System.Environment]::SetEnvironmentVariable("Java_Home", $java_value, "User")
}
}
function refresh-path
{
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") +
";" +
[System.Environment]::GetEnvironmentVariable("Path", "User")
}
Adding to the answer provided here (https://stackoverflow.com/a/64459399/894565).
I manually created environment variables via UI for Java11, Java17 and Java8. To change across Java version:
From powershell (PJV.ps1):
if($args[0] -eq "11") {
$Env:JAVA_HOME="$ENV:JAVA11"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
} elseif($args[0] -eq "17") {
$Env:JAVA_HOME="$ENV:JAVA17"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
} elseif($args[0] -eq "8") {
$Env:JAVA_HOME="$ENV:JAVA8"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
}
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
From command line (JV.bat):
#echo off
if "%~1" == "11" (
set "JAVA_HOME=%JAVA11%"
setx JAVA_HOME "%JAVA11%"
) else if "%~1" == "17" (
set "JAVA_HOME=%JAVA17%"
setx JAVA_HOME "%JAVA17%"
) else (
set "JAVA_HOME=%JAVA8%"
setx JAVA_HOME "%JAVA8%"
)
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
Finally both these files are in the same folder. And this folder path has been added to my system PATH

Windows Batch File popd not working as expected

I am using the following batch script to run a Java Command Line tool.
#echo off
pushd %~dp0
setLocal EnableDelayedExpansion
set CLASSPATH="
for /R ./libs %%a in (*.jar) do (
set CLASSPATH=!CLASSPATH!;%%a
)
set CLASSPATH=!CLASSPATH!"
java -cp !CLASSPATH! com.example.CLIApplication %*
popd
I have added the tool's directory to the System Variables PATH so that I can run it from any directory via the command prompt. This is working but the problem I am seeing is:
The tool's dir is C:\tool\
The user is in C:\
After executing the batch file the user is left in C:\tool\ not C:\
popd is getting called but the console navigates back to C:\too\ instead of staying in C:\
How do I ensure they users directory is not changed after the script finishes?
The setlocal without endlocal causes this problem here.
You only need to add an endlocal just before calling popd.
In your code the popd returns to your first directory, but as setlocal stores all variables and all open setlocals are closed by implicit endlocals when the batch is exited, it will also restore the cd variable.
I may be off track, but why aren't you using:
pushd .

Input filename into jar from windows batch file

I want to input a file into my jar after it is executed from batch file.
I wrote the following batch code.
#echo off
set path=%PATH%;C:\Program Files\Java\jre7\bin
java -jar E:\ER\er_v.3.3.17.jar
The above code is working fine. However, after the jar file is executed I need to feed another file for it to run successfully.
I want something like this
#echo off
set path=%PATH%;C:\Program Files\Java\jre7\bin
java -jar E:\ER\er_v.3.3.17.jar
echo E:\Run.xml
Can somebody help me with this?
Here you go. I tested this and it works.
#echo off
setlocal
:: if java.exe is not in %path%
for %%I in (java.exe) do if "%%~$PATH:I" equ "" (
set "PATH=%PATH%;C:\Program Files\Java\jre7\bin;C:\Program Files (x86)\Java\jre7\bin"
)
echo E:\Run.xml| java -jar E:\ER\er_v.3.3.17.jar
This passes "E:\Run.xml" to the stdin of java -jar etc.

Categories