I am completely new to Windows batch programming.
What I want to achieve is to write a startup script for a Java application. Yet, it does not start the Java application, but rather prints out
Usage: java [-options] class [args...]
(to execute a class)
or java [-options] -jar jarfile [args...]
(to execute a jar file)
...
which indicates that my parameters are not correctly recognized.
Here is my MCVE for the not-working script:
set memory=600000
java -XX:OnOutOfMemoryError="taskkill /PID %p" -Xmx%memory%K -jar MyApp.jar
In the real scenario, memory is calculated to set the optimal maximal heap size for the application.
Leaving out one of both parameters makes the app start. So
java -XX:OnOutOfMemoryError="taskkill /PID %p" -jar MyApp.jar
and
set memory=600000
java -Xmx%memory%K -jar MyApp.jar
works, but I need both parameters to work in one call.
If you put #echo on and #echo off in your script you can see what command is actually being executed.
You say that the resulting command is:
java -XX:OnOutOfMemoryError="taskkill /PID memoryK -jar MyApp.jar
which makes it look like the % of %p is being considered an "opening" % for the substitution.
Aside from the quotes not being balanced, this means that you are effectively not giving java a command to run - the -jar MyApp.jar is actually inside the -XX:OnOutOfMemoryError string.
Try replacing the single % with %% - according to this question, that is how to write a literal % in a BAT file:
java -XX:OnOutOfMemoryError="taskkill /PID %%p" -Xmx%memory%K -jar MyApp.jar
Related
I'm trying to run a java process via Powershell in Windows XP. Here's the command:
java.exe -cp .;./common.jar -Dcontext=atest1 -Dresourcepath=. DW_Install
So, the classpath is . and .\common.jar (I think java takes the wrong slashes, right?) There are two environment variables, one "atest1" the other "." and the class to execute main on is DW_Install (in the default package).
This command works in cmd.exe, but doesn't is PS. What's going on? What is PS doing while parsing this command that CMD doesn't do (or vice versa)?
Aaron
The problem is that PS for some reason parses -Dresourcepath=. differently than cmd. What works is
java -cp '.;.\common.jar' -Dcontext=atest1 "-Dresourcepath=." DW_Install
It doesn't matter which way the slash goes, and it doesn't matter which quotes one uses (' or "). The classpath must be escaped, however, with some kind of quotes. A good test to see what's getting by the PS interpreter is to echo it. The following:
echo java -cp '.;.\common.jar' -Dcontext=atest1 -Dresourcepath=. DW_Install
yields the following output:
java
-cp
.;.\common.jar
-Dcontext=atest1
-Dresourcepath=
.
DW_Install
(Notice the resourcepath and the value of resourcepath are not on the same line.) Whereas the output to
echo java -cp '.;.\common.jar' -Dcontext=atest1 '-Dresourcepath=.' DW_Install
yields the following output:
java
-cp
.;.\common.jar
-Dcontext=etaste1
-Dresourcepath=.
DW_Install
Which is much more to our liking.
Although I wish this upon none of you, I hope that this post helps those of you that must deploy java projects on Windows machines (even though they will not run on any other platform ever).
Running external command-line programs from PowerShell is sometimes a bit problematic because there PowerShell exposes two different parsing modes that get trumped by the different syntaxes of said external programs.
In any case, running a command in Powershell requires using either the . prefix (dot-"sourcing") or the & operator.
You can workaround this by passing each parameter to the external program as separate variables, like so:
PS> $classpath = ".;./common.jar"
PS> $env = "-Dcontext=atest1 -Dresourcepath=."
PS> $class = "DW_Install"
PS> . java.exe -cp $classpath $env $class
Another example based on https://gaming.stackexchange.com/questions/24543/how-do-i-change-player-name-in-minecraft-multiplayer-in-offline-mode-in-linux
function mineCraftAs {
Param (
[parameter(mandatory=$true, HelpMessage="Minecraft character name." ,ValueFromPipeline=$true)]
[string] $name
)
if(!(test-path $env:appdata)) { $(throw "Appdata not found at $env:appdata")}
$private:minecraftPath=Join-Path $env:appdata .minecraft
if(!(test-path $minecraftPath)) { $(throw "Minecraft not found at $minecraftpath")}
$private:minebinPath=join-path $minecraftPath "bin"
if(!(test-path $minebinPath)) { $(throw "Minecraft bin not found at $minebinPath")}
$minebinPath | write-debug
gci $minebinpath | write-debug
#java -Xms512m -Xmx1024m -cp "%APPDATA%/.minecraft\bin\*" -Djava.library.path="%APPDATA%\.minecraft\bin\natives" net.minecraft.client.Minecraft '"'%1'"'
echo java -Xms512m -Xmx1024m -cp ('"'+$minebinPath+'\*"') ('-Djava.library.path="'+$minebinPath+'\natives"') net.minecraft.client.Minecraft ($name)
$minecraftJob=& 'C:\Program Files (x86)\Java\jre6\bin\java.exe' -Xms512m -Xmx1024m -cp ('"'+$minebinPath+'\*"') ('-Djava.library.path="'+$minebinPath+'\natives"') net.minecraft.client.Minecraft ($name)
}
minecraftas newbie
The following should work:
java.exe -cp '.;./common.jar' -Dcontext=atest1 -Dresourcepath=. DW_Install
I guess that PowerShell interprets the ; in the classpath as command delimiter, thereby trying to run java -cp . and ./common.jar -D....
start-process -nnw java "-cp .;./common.jar -Dcontext=atest1 -Dresourcepath=. DW_Install"
If I want to launch one java executable java --jar sample.jar from command line, how could I write the bash script? The following doesn' work
#!/usr/bin/java
--jar $HOME/tools/sample.jar
#!/bin/sh
java --jar $HOME/tools/sample.jar
Java is NOT an interpreter and only a script interpreter can be used in the shebang(#!)
To be complete you cant pass parameters to the interpreter that way anyway..
The "correct" but still wrong way would have been
#!/usr/bin/java --jar
$HOME/tools/sample.jar
I am not fully clear, but Wikipedia hints that the second method might just work..
However, it is up to the interpreter to ignore the shebang line; thus, a script consisting of the following two lines simply echos both lines to standard output when run:
#!/bin/cat
Hello world!
#!/bin/bash
exec java -jar /path/to/jar/the-file.jar "$#"
With $# you pass the bash arguments to jar file
I wanna re-run a jar file from its own (with some additional parameters). How can I do this?
I need the solution to be OS independent.
If I deciphered the question correctly, we are talking about command line interface arguments. For this there's plenty tutorials: http://docs.oracle.com/javase/tutorial/essential/environment/cmdLineArgs.html
The code is simple, like you said yourself:
if ("-server".equalsIgnoreCase(argv)) {
// we are server
} else if ("-client".equalsIgnoreCase(argv)) {
// we are client
}
Now, depending on how you want to execute you program from the OS, there's a number of ways:
$java -jar yourjar.jar -client
Or
$java -cp yourjar.jar com.your.program.Main -client
Same for the "-server".
To run them together, either run them from separate terminal windows (or cmd prompts). Or - if in Linux - you can use ampersand:
$java -jar yourjar.jar -client &
$java -jar yourjar.jar -server &
I have a program in java which takes 0'th aargument as file location like
File f = new File(args[0]);
so when i execute it using a windows batch(.bat) file it works correctly .
but when i execute the same using a linux shell file(.sh) in linux i get ArrayIndexOutOfBoundsException.
WINDOWS BATCH FILE :
#echo off
for /f %%i in ("%0") do set scriptpath=%%~dpi
set cp=%scriptpath%/../lib/*.jar;
java -classpath %cp% com.synchronizer.main.MYSynchronizer %scriptpath% "%1" "%2"
LINUX SH FILE:
export JAVA_HOME=/usr/local/java
PATH=/usr/local/java/bin:${PATH}
THE_CLASSPATH=
for i in `ls ../lib/*.jar`
do
THE_CLASSPATH=${THE_CLASSPATH}:${i}
done
java -cp ".:${THE_CLASSPATH}" \
com.synchronizer.main.MYSynchronizer
please help!
It looks like a problem in script (no arguments are passed to the Java program).
You can consider to debug the script like this: debugging scripts
Hope this helps
Your shell script is not passing any parameters:
java -cp ".:${THE_CLASSPATH}" com.synchronizer.main.MYSynchronizer
Try:
java -cp ".:${THE_CLASSPATH}" com.synchronizer.main.MYSynchronizer "$1" "$2"
As stated above, your Linux shell script is not sending any arguments to the Java program that you are trying to start.
And, adding to that, you are not showing us how you run the Linux shell script. If no argument is given on the command line when you start the shell script, no arguments can be passed to your Java application from the shell script.
If you want to see the actual command that is going to be run by your shell script, you can always put "echo" in front of a line and see what all variables are expanded to. This is a simple way to debug shell scripts.
-java -classpath<> <classname> in the ".bat" file to launch java test from cmd windows
how to do that using perl to launch java test from linux ?
Don't use perl. For such a simple job, a simple shell script will do:
#!/bin/sh
/path/to/java -classpath foo.jar:bar.jar:. classname
Make the file executable with chmod +x filename and execute it with ./filename
A similar approach using the -jar option is possible. Additionally, you can forward any command line parameters using the special parameter #.
#!/bin/sh
/path/to/java -jar foo.jar "${#}"