Converting Perl to Java - java

I have a Perl file which is actually calling some jar files and I'm trying to make it an all Java program and remove the Perl. So I came up through this lines which is:
$blammercommand="$javapath $javaparams -jar $blammerpath -conf $blammerconf $blammerparams -cpu $cpu -i \"".$tmpdir."blastresults/*.bls\" -db \"$infilename $blastdb\"";
(system($blammercommand)==0) or die "unable to do $blammercommand\n";
I've already decompressed the jar files and added the source codes to my Eclipse project and have access to the main function of the related jar file. I'm just trying to pass the arguments as inputs.
My problem is exactly here that I don't know what "\"".$tmpdir."blastresults/*.bls\"" and "\"$infilename $blastdb\"" mean. I know what exactly each one of this variables are but I don't know how those \, / and * are working and how should I convert them to Java.

Those are just shell escaping and shell globbing. Literally written, it would look like this:
${javapath} ${javaparams} -jar ${blammerpath} -conf ${blammerconf} ${blammerparams} -cpu ${cpu} -i "${tmpdir}blastresults/*.bls" -db "${infilename} ${blastdb}
Here, the syntax ${name} is meant to indicated an inserted value of the variable. The system command in Perl runs a system command through the default system shell, usually something like bash. The quotes are used to make several space-separated strings "stick together" as one argument. The * is a wildcard, which is replaced by all filenames in a given directory.

Related

Can I use -cp argument twice when executing Java?

I am trying to run a Java application which has many dependencies. In the past I have use the following command to launch the application
java -cp "program.jar:jar1.jar:jar2.jar:jar3.jar:[...]" program
However as the list of dependencies have grown, I have moved them into an arguments file, the contents of this file are:
-cp "\
program.jar:\
jar1.jar:\
jar2.jar:\
jar3.jar:\
[...]"
And I am running the application with
java #arguments-file program
Everything up to this point works fine.
Sometimes I end up with beta versions of program.jar, they share all of the same dependencies, but program.jar is renamed program-beta.jar.
So to run the jar the following command would be used
java -cp "program-beta.jar:jar1.jar:jar2.jar:jar3.jar:[...]" program
or more specifically, I would use an environment variable, so that the same script can be used, and the variable would be set to either program.jar, or program-beta.jar, depending on the circumstance
java -cp "$PROGRAM_JAR:jar1.jar:jar2.jar:jar3.jar:[...]" program
Now that I am using an arguments file I was hoping to be able to be able to do something like:
java -cp "$PROGRAM_JAR" #arguments-file program
However using -cp twice causes one of the two to be ignored, resulting in a java.lang.ClassNotFoundException exception.
Is there any way around this that allows me to specify one jar file by name, but abstract away all of the others so that my java command isn't thousands of characters?
This will be running entirely on Linux, so any command line "magic", such as using grep is fine, so long as the resulting code is easily readable
You could just write two bash scripts production.sh and beta.sh that contain a reference on program.jar and program-beta.jar, respectively.
Also, the classpath can contain wildcards (see man-page), so if you can ensure that on disk exists only one of the two versions, you can write it like this:
java -cp "program*:jar1.jar:jar2.jar:jar3.jar:[...]"
In the long term, you might think about building/running it with Maven or Gradle, depending on your requirements.

Why does my batch file give an error if it has spaces in path?

I am trying to run a .jar file using a .bat file. But my Batch file gives an error when I have spaces in my path.
For e.g.
#echo off
java -jar %~dp0\..\new\myFile.jar %*
This are the contents of my batch file. I know that %~dp0 will give the current drive letter and path to my batch file and then \..\ will go back to it's parent directory and then it will open the new directory and run the jar file from it.
But the problem here is if my path contains a space in it the batch file gives an error:
Error: Unable to access jarfile C:\Users\Vatsal
Assuming my path for .jar file is:
C:\Users\Vatsal Sura\myFolder\new\myFile.jar
and path for my .bat file is:
C:\Users\Vatsal Sura\myFolder\batch\batchFile.bat
Now if I move myFolder directly in C:\, which doesn't contain any spaces in it, then it won't give any error and the .jar file would run as expected.
I want to know why this is happening and what should I do to make spaces count in my path?
Put the offending part in double quotes: java -jar "%~dp0\..\new\myFile.jar" %*
If the expansion is C:\Users\Vatsal Sura\myFolder\new\myFile.jar, then without quotes, -jar is only seeing up to the first space as it's argument (i.e. -jar C:\Users\Vatsal) and the remainder (Sura\myFolder\new\myFile.jar) is a completely different argument not related to the -jar
You need to make the shell/cmd see all of that as one argument. Double quotes will still allow any expansion to happen but everything within the quotes will be seen as a single item (the quotes won't be there when java sees it).
The reason for your problem is simple
Batch Is Simple Too,
Windows needed to create command Line, powershell, blah blah, and with its awesome features. However, Batch only runs on one programmed line of code, yes its confusing lol but when you write the code it is nothing compared to the binary. Batch is not too advanced and therefore does not process spaces when its in the "heart" of the command, like it i do this it literally has the same error however batch can tell the difference:
ec ho
(supposed to be echo)
anyways, a simple solution to your problem can be changing the encoding that your batch file is working on or just simply taking out the spaces on you directory.
Plus, don't use
%~dp0\
(it suKs)
Instead, to simplify this just do
#echo off
java -jar %CD%\new\myFile.jar %*
you don't have to even set %CD% to be anything it just automatically used the current directory.
*even with all this, your initial problem will not be solved. It may if you change the encoding (use notepad++ for that) but i hope you found this answer at least a little helpful to explain how this is working.

Where to put files for a command-line Java program?

I have written a Java program that takes in arguments and then executes. I pass in these arguments from the command line (I am on a Macbook Pro using Terminal, using the bash shell). Let's say the name of my program is prgm. I want to be able to say "prgm " from any directory in the shell and then have that program execute. So I figure I need to write a bash script to reference the Java files and take in arguments, and put that bash script somewhere in my PATH. Where do I put the bash file, and where do I put my Java files? Also, am I right to assume that I only need the .class (binary) Java files?
Step-by-step:
Assuming that the name of the Java executable if myjavaprog.
Assuming that the name of your bash script is myscript.
Make sure myscript is calling myjavaprog using absolute path and the desired arguments.
call echo $PATH and you will see a bunch of paths: /some/path1:/some/other/path2:...
Put your bash script in whatever path you want from the ones returned by echo $PATH.
Go to a random path.
Call you bash script bash myscript. See the execution of myjavaprog.
Tips:
If java program is for personal use only, put it in a path starting with /usr/ or even in your $HOME directory (and add that location to your PATH)
If java program must be shared with other users, put it in an accessible place, so that other users don't need to modify their PATH variable.

convert a java program into a linux command

I have created one java program on my Linux system which indents and formats the given file. I want to make that program work like a command in Linux which will take file names and other options as arguments and then will produce the output. I can do this with a C program by just copying the compiled executable in /bin folder but I don't know how to do it with java.
Sample script that can might further help-
#!/bin/bash
#Set whatever number of arguments you expect for the Java jar you have
ARGS_EXPECTED=3
if [ $# -ne $ARGS_EXPECTED ]
then
echo "[$HOSTNAME]: Usage: `basename $0` filename arg1 arg2"
exit 1
fi
java -cp yourfile.jar com.yourpkg.Driver $1 $2 $3
Save the above content to a file, say test.sh
and use the command to give an executable permission chmod +x test.sh
run like ./test.sh filename arg1 arg2 from current directory where test.sh is
I thing this can be useful for your case: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/binfmt_misc.txt?id=HEAD
You can simply run a Java class file or jar file with "java" command from command line. Example:
java -jar yourprogram.jar argument1 argument2
If you save this line in a text file saved for example as "script.sh" and then give it the permission for execution you can run it double clicking or from terminal typing ./script.sh in the same folder containing the file script.sh.
You can also produce scripts that use arguments with $1 $2 etc. avoiding the need of editing file.
http://www.linuxquestions.org/questions/linux-newbie-8/how-to-pass-command-line-parameter-to-shell-script-254396/
You can use named parameters, too.
You can also produce a C program for a new command like you suggested that run the "java" command. In this case you can introduce arguments directly from terminal and pass them to java command in the C source.
As others have pointed out it is probably best to use a small shell script to run the Java application. There are several open source products that will help you wrap your Java code to produce a runnable (set of) .jar(s).
If you have correctly separated your business logic from your interface (as you should) then it is probably best if your Java application parses the parameters given on the command line interface. To do this create a separate class for parsing such parameters and calling the classes making up the business logic. Of course this will lead quickly - if not immediately - in writing a parser for Linux like CLI parameters. When this happens you may wish to consider the Apache Commons CLI project.
If you don't want to use any wrapping application/runtime, my method is generally pointing to all the class file containers in the classpath and directly pointing to the class containing the static main method:
java -cp "path_to_jar;path_to_class_folder;etc" "nl.owlstead.stackoverflow.LinuxMain"

Java path problems on Cygwin

I'm trying to compile a Java project under Cygwin using a native Win32 Java.
The Java binaries are correctly found under /cygdrive/c/jdk/bin on my machine.
The following command works fine:
javac -d . ./gnu/kawa/util/PreProcess.java
The PreProcess.class file is generated in ./gnu/kawa/util/. Trying to invoke Java on this fails however:
CLASSPATH=.:$CLASSPATH java gnu.kawa.util.PreProcess \
%java6 +use:com.sun.net.httpserver +enable:XML \
`sed -e 's|\([^ ]*\)|./\1|' < ./patch-source-list`
Error: Could not find or load main class gnu.kawa.util.PreProcess
...
This command was invoked by make, that's where the $CLASSPATH variable is set dynamically. patch-source-list is just a list of class names. The : in the classpath looks suspicious, but I'm not sure how to test ; while not annoying sh.
My only other suspicion is that the native Java is trying gnu\kawa\util\PreProcess, but I think cygwin can transparently handle that.
Any ideas? Thanks for your time.
Another option would be to build your path using the ':' and then fix the results using cygpath. This is probably overkill in your specific situation, but in a general case where you may have references to multiple directories, some of which may be referenced as absolute rather than relative paths, or if you are working with cygwin symlinks, it is much more useful.
$ ln -s /cygdrive/c/development/libraries/ ../libs
$ cygpath -pw /cygdrive/c/development/:.:../libs
C:\development\;.;C:\development\libraries\
so then you'd build your CLASSPATH variable as before, and in the final stage run
CLASSPATH="`cygpath -pw "$CLASSPATH"`" java (whatever)
Remember, the JVM has no idea that you are using the cygwin bash shell.
Two things:
for the classpath locations, use the windows path names. Thus, no "/cygdrive/c/somepath", but "c:\somepath\" ("/" and "\" can be used interchangeably however)
use ';' instead of ':' in the classpath list
This should work:
export CLASSPATH="./gnu/kawa/util/PreProcess.class"
CLASSPATH=".;$CLASSPATH" java gnu.kawa.util.PreProcess
The : in the classpath looks suspicious, but I'm not sure how to test ; while not annoying sh.
You're exactly right: you need to use ; instead of :. As for how to use it — as Mat alludes to above, you need to "quote" the semicolon. Any of these will work:
CLASSPATH=.\;$CLASSPATH java Foo
CLASSPATH=.';'$CLASSPATH java Foo
CLASSPATH='.;'$CLASSPATH java Foo
CLASSPATH=".;$CLASSPATH" java Foo
You can use whichever one you like best. (The first uses a backslash, which quotes a single following character. The second and third use single-quotes, which quote a sequence of zero or more characters. The fourth uses double-quotes, which are like single-quotes except that they still allow the variable $CLASSPATH to be expanded. For that matter, you could also write something like
CLASSPATH=".;"$CLASSPATH java Foo
if you want. See the above link for lots more information about quoting in Bash.)

Categories