I'm trying to write a BASH script to get my Java program to run(common issue, right?). I just can't quite get it to work. After many edits, here's how I am trying to set the classpath and then execute the program:
java -classpath 'cygpath -u "/cygdrive/c/Projects/common/lib/rome-1.0.jar:/cygdrive
/c/Projects/common/lib/jdom-1.0.jar:/cygdrive/c/Projects/common/lib/jsoup-1.6.1.jar:
/cygdrive/c/Projects/common/lib/mysql-connector-java-5.1.18-bin.jar:/cygdrive/c/Projects
/Freereader/bin/"' com.free.syndication.SQLfeeder
Sorry the the jumble, I'm just trying to do everything at once. It tells me that the main class of my program cannot be found!((
Any ideas?
Java classpath uses semicolon as the token separator.
Use backticks instead of single quotes
Try:
java -classpath `cygpath -u "/cygdrive/c/Projects/common/lib/rome-1.0.jar;/cygdrive
/c/Projects/common/lib/jdom-1.0.jar;/cygdrive/c/Projects/common/lib/jsoup-1.6.1.jar;
/cygdrive/c/Projects/common/lib/mysql-connector-java-5.1.18-bin.jar;/cygdrive/c/Projects
/Freereader/bin/"` com.free.syndication.SQLfeeder
In bash, the syntax $(command) is clearer than the backticks `command`
cygpath has a -p option to convert PATH-like values (as opposed to single path names) between Windows and Unix, i.e.
cygpath -pu 'C:\Users\me\bin;C:\Users\me\project\bin' will give /cygdrive/c/Users/me/bin:/cygdrive/c/Users/me/project/bin
cygpath -pw will do the same in the opposite direction
Note that cygpath -u "/cygdrive/c" (as in your question) will not change anything, since the directory name is already in the desired (Unix) syntax. You could omit it just as well.
So, the command becomes:
CP="C:/Projects/common/lib/rome-1.0.jar;C:/Projects/common/lib/jdom-1.0.jar;C:/Projects/common/lib/jsoup-1.6.1.jar;
C:/Projects/common/lib/mysql-connector-java-5.1.18-bin.jar;C:/Projects
/Freereader/bin"
# for a Windows Java binary:
java -classpath "$(cygpath -pw "$CP")" com.free.syndication.SQLfeeder
# for a Unix Java binary:
java -classpath "$(cygpath -pu "$CP")" com.free.syndication.SQLfeeder
Alternatively, you can start with a Unix-style class path, but the commands stay the same. In either case, you can of course omit the call to cygpath if the class path is already in the desired syntax.
Don't you need backticks?
java -classpath `cygpath -u "/cygdrive/c/Projects/common/lib/rome-1.0.jar:/cygdrive
/c/Projects/common/lib/jdom-1.0.jar:/cygdrive/c/Projects/common/lib/jsoup-1.6.1.jar:
/cygdrive/c/Projects/common/lib/mysql-connector-java-5.1.18-bin.jar:/cygdrive/c/Projects
/Freereader/bin/"` com.free.syndication.SQLfeeder
You must use backticks ( '`' symbol ) or $(cmd) bash sytax to substitute cmd output
java do not understand unix- (cygwin-) style paths, only windows-style.
And at last first link in google answers you question
The main cause of the issue is NOT the backtic but instead the issue of colon versus semi-colon. Since in cygwin, the java running there is for DOS/Windows environment it is expecting ';' as the path separator.
While backtic does help, the main root cause of the issue must be emphasize the difference between ':' and ';' when Java is in Unix or in Windows environment.
Related
I have read this documentation including the section that exemplifies Command Line Argument Files but can't figure out how to get it working in PowerShell. Here's what I have done:
First, I can compile a Driver.java file using (in windows PowerShell, javac version 17.0.3):
>>javac Driver.java
But, I would like to figure out how to use argument files (#filename).
I have tried to create a file called files.txt with 1 entry in it listed as Driver.java and then use javac with #file to specify what to compile:
PS-pluto>>dir -n *.java >files
PS-pluto>javac #files
I tried creating files, and files.txt. Driver.java is definitely the entry, but the javac command doesn't work. I am running this from the folder where files and Driver are located.
I read the answer to this question which indicated that I needed to add quotes, and tried this (again, with and without .txt):
PS-pluto>>dir -n *.java >files
PS-pluto>>javac "#files"
This may work, but doesn't solve the problem. Now I get a new error:
error: invalid flag: ■Driver.java
I have looked for hidden formatting in my txt file and only see the line return at the end of Driver.java. Not sure what is wrong?
I know in this simplistic case using an argument file is overkill, but I am simply trying to figure out how it works...and cannot.
NOTE: I already know how to compile this in an IDE or with a build tool. I am trying to figure out how to do this in PowerShell, and admittedly, I am a novice PowerShell user.
An unquoted # at the start of an argument is a PowerShell metacharacter and therefore needs to either be escaped as `# or enclosed in a string literal.
In Windows PowerShell, > creates "Unicode" (UTF-16LE) files by default, which javac most likely cannot handle.
In PowerShell (Core) 7+, BOM-less UTF8 is now the (consistent) default, so > would work as is.
In Windows PowerShell, the simplest solution is to pipe to Set-Content -Encoding Ascii, assuming that the file names contain ASCII-range characters only.
# Create file "files" as an ASCII file.
# Note: The Get-ChildItem call is `dir -n *.java` fully spelled out.
Get-ChildItem -Name *.java | Set-Content -Encoding Ascii files
# Escape # as `# to treat it literally.
javac `#files
If the file names contain non-ASCII characters and javac requires BOM-less UTF-8 encoding, more work is needed, because in Windows PowerShell you cannot directly create BOM-less UTF-8 files - see this answer.
I've been trying to compile and run this example for javafx https://openjfx.io/openjfx-docs/#maven using Cygwin on Windows 10. It took awhile to get past the compile because my javafx is stored in C:\Program Files\javafx-sdk-13.0.1, the trouble being the space in the folder name. After trying lots of different things I finally found How to cd into a directory with space in the name?, which in a nutshell tells you to put quotes around your environment variable, "PATH_TO_FX".
Then I tried to run the example
$ java --module-path "PATH_TO_FX":mods -m hellofx/hellofx.HelloFX
Error occurred during initialization of boot layerjava.nio.file.InvalidPathException: Illegal char <:> at index 10: PATH_TO_FX:mods
So I thought the PATH_TO_FX was the problem but it turns out it is not.
$ java --module-path src:mods -m hellofx/hellofx.HelloFX
Error occurred during initialization of boot layerjava.nio.file.InvalidPathException: Illegal char <:> at index 3: src:mods
src is a valid directory and I still get the same problem. I think it is related to java being stored in a directory with spaces in it but I'm not sure.
#Ray_Write
isn't ; for Windows? Cygwin uses bash
This has nothing to do with the shell. The parsing of --module-path is handled entirely by the java interpreter, and according to the docs uses ; on Windows instead of :, presumably for congruence with Windows PATH separators.
Since this Java installation is a native Windows application and not one built for Cygwin, one should still use ;. So in effect, this has nothing to do with Cygwin.
For passing file paths to java you may also need to use cygpath to convert the path to its native Windows path.
You're right #Iguananaut, I do need a semi colon, to get my example to work I had to escape it.
java --module-path "$PATH_TO_FX"\;mods -m hellofx/hellofx.HelloFX
where PATH_TO_FX is in .bash_profile as
PATH_TO_FX="C:/Program Files/javafx-sdk-13.0.1/lib"
This is my exact batch file. I have tried to convert it doing some research online and get an error
"Failed to execute child process "/home/pi/Desktop/TeachVal/TeachValLinuxShell" (No such file or directory)
echo off
cls
echo Running TeachVAL II...
set path=%path%;/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/bin
java -classpath comm.jar;Robot.jar;TeachVAL TeachVAL
cls
exit
This one is my attempt at translating.
#!/bin/bash
set +v
clear
echo "Running TeachVAL II..."
java -cp ".dir1;dir2;path/home/pi/Desktop/TeachVAL/comm.jar;
path/home/pi/Desktop/TeachVAL/Robot.jar;/home/pi/Desktop/TeachVAL/TeachVAL"
clear
exit
Welcome to Linux--life is good here, but there are a few things that work slightly differently, when compared to Windows.
One difference is that Windows uses semicolon (;) to separate entries in a list of paths, but Linux uses colons (:) for that purpose.
So, the Windows command:
java -classpath comm.jar;Robot.jar;TeachVAL TeachVAL
would correspond to this on Linux:
java -classpath comm.jar:Robot.jar:TeachVAL TeachVAL
In general, on Linux, semicolons are used to put multiple command lines into a single line. Once you've learned that, I think you can then understand why:
java -cp .dir1;/home/pi/Desktop/TeachVAL/TeachVAL
would be the same as:
java -cp .dir1
/home/pi/Desktop/TeachVAL/TeachVAL
That would run java (with no class to be executed) and then try to run "/home/pi/Desktop/TeachVAL/TeachVAL" which can't be found.
There are many more differences to learn; here's a page that will help you get started: http://tldp.org/LDP/abs/html/dosbatch.html
I've searched throughout this site and tried a few solutions when receiving this message but nothing seems to work.
I am trying to invoke a shell script on Ubuntu 12.04.2 (with java-7-openjdk-amd64) that runs a java program and then I get a "Error: Could not find or load main class com.xx" error.
This is how my script invokes Java:
"$JAVA" $server_jvmargs $javaProps -Dxx.home="$XX_HOME" -Duser.dir="$XX_HOME" -cp $client_classpath $mainclass $args
And the arguments you see above are defined as follows:
args=$*
javaProps=
mainclass=com.xx
server_jvmargs="-Djava.awt.headless=true -Xms1024m -Xmx1024m $jvmargs"
XX_HOME="`pwd`/../.."
client_classpath="$XX_HOME/lib/client/patch.jar;$XX_HOME/lib/client/xyx-xxx.jar;$clientlibs;$XX_HOME/lib/server/standard-1.1.2.jar;$publictilesource;$respath;$XX_HOME/lib/client/xxmainclass.jar"
The mainclass variable is in the classpath located in the xxmainclass.jar file so I'm not sure as to why it cannot find it?
Does anyone have any ideas on what could be going on?
To see what actually happens when you run your script, invoke it with bash -x, or put set -x at the top; this will print each command before it's run, so you can see how it's actually starting the JVM. Without this information, it's hard to come up with a better diagnosis. That said...
You've been copying off Tomcat's startup scripts, it looks like. Don't; they're awful.
Something a little more correct on the shell side might look like this:
args=( "$#" )
javaProps=( )
mainclass=com.xx
server_jvmargs=( -Djava.awt.headless=true -Xms1024m -Xmx1024m "${jvmargs[#]}" )
XX_HOME="$PWD/../.."
client_classpath="$XX_HOME/lib/client/patch.jar:$XX_HOME/lib/client/xyx-xxx.jar:$clientlibs:$XX_HOME/lib/server/standard-1.1.2.jar:$publictilesource:$respath:$XX_HOME/lib/client/xxmainclass.jar"
java \
"${server_jvmargs[#]}" \
"${javaProps[#]}" \
-Dxx.home="$XX_HOME" \
-Duser.dir="$XX_HOME" \
-cp "$client_classpath" \
"$mainclass" "${args[#]}"
The use of ${foo[#]} expands the array foo with literal contents. Note that foo must be created as an array in this case, and you need to be using a shell that supports arrays (so your script needs to start with #!/bin/bash, not #!/bin/sh).
See http://mywiki.wooledge.org/BashFAQ/005 for an introduction to arrays in bash.
use a : instead of a ; in your classpath.
unix just rolls that way.
Try this:
Java -jar pathToYOurFile.jar
Please check if line end character is OS specific in your shell script
I'm complete Linux newbie, but still want to provide a simple way for Linux users to start my Java program.
Therefore I want to create a shellscript.
I can't test my script so I'll have to ask here if this is working correctly:
#!/bin/bash
java -cp "bin";"extres/junit.jar" data.ProgramOne
exit 0
Your mistake is in path delimiter. It is ; on Windows and : on Linux.
Moreover you should not wrap each classpath fragment with "". On unix you can escape spaces and other forbidden characters using \. So, I'd re-write the java execution line as:
java -cp bin:extres/junit.jar data.ProgramOne
This will run when you are executing script from your app directory where you have subdirectory bin and extres.
try this:
java -cp "bin:extres/junit.jar" data.ProgramOne
Java under Unixes uses : as the separator in the classpath, so you'd need (the quotes are not necessary):
#!/bin/bash
java -cp bin:extres/junit.jar data.ProgramOne