Pass input to an application not reading from stdin - java

I have an application that reads a text file.
If the application reads it from stdin, then I could forward the input / pipe it
$ app < input.txt
$ cat input.txt | app
Unfortunately, the application expects a filename as an argument..
$ app --input input.txt
and I can't easily change the source of input (eg. swap local file [as in example] for a result of a wget).
Is there an option to somehow trick this app?
If a solution requires a temporary file, it is necessary that this file is not left on the FS..
The app is actually an executable JAR; I'd like the trick to run on Win/Lin..

I am not sure if it could work for you, but I have already solve a similar problem with a fifo.
http://linux.die.net/man/3/mkfifo
This could give you the indirection between your app and your source.
mkfifo fifo.input
app --input fifo.input
Now you can fill the pipe with different sources.
cat input > fifo.input
ctrl-c
cat otherInput > fifo.unput
Hope it solve your problem on Linux. So far I know it does not exist on Windows.

You want to do something like this.
java -jar myjar.jar arg1 arg2
where myjar.jar is the executable jar and arg1 arg2 etc are parameters the program expects.
So suppose you want to pass input.txt to your application and its the only commandline parameter required then command will be
java -jar myjar.jar input.txt

Related

how to build Executable jar to return string to shell script

I have to run executable jar file from shell script to get a string value. The executable jar can't return a value as the main returns void. I can't use System.exit(int) as jar has to return value of String type.
Please suggest.
This data should be written to stdout (System.out in Java), and captured with $(command expansion).
Here's what all good Unix citizens (and far too few Java programs) make sure to do:
Write program result to stdout (System.out)
Write error messages and debugging to stderr (System.err)
Use System.exit(0) to indicate success (this is also the default if no System.exit is used)
Use System.exit(1) (or higher, up to 255) to indicate failure
Here's a complete example for demonstrating the interplay between Java and shell scripts:
$ cat Foo.java
class Foo {
public static void main(String[] args) {
System.out.println("This data should be captured");
System.err.println("This is other unrelated data.");
System.exit(0);
}
}
A very basic manifest:
$ cat manifest
Main-Class: Foo
A simple shell script:
#!/bin/sh
if var=$(java -jar foo.jar)
then
echo "The program exited with success."
echo "Here's what it said: $var"
else
echo "The program failed with System.exit($?)"
echo "Look at the errors above. The failing output was: $var"
fi
Now let's compile and build the jar and make the script executable:
$ javac Foo.java
$ jar cfm foo.jar manifest Foo.class
$ chmod +x myscript
And now to run it:
$ ./myscript
This is other unrelated data.
The program exited with success.
Here's what it said: This data should be captured
Can you run a Java application that will launch a shell and capture the string from that? I am thinking of many applications which capture username / password from a shell. For example if using spring check out:
https://github.com/spring-projects/spring-shell
Suggestion: Try to write your String to System.stdout and read it from there. Maybe you can write output to a file and read it from there?
Another suggestion : Get the java application to save its output to a temporary file and then get the shell script to read in the contents of the file such as VAR=cat /tmp/temp_file

"No such file or directory" when running java from shell script

I'm trying to run a script from an Amazon Linux machine. The script invokes checkstyle like this (in a script called eval.sh):
CHECKSTYLE="java -jar /home/ec2-user/grader/ext/checkstyle-6.15-all.jar"
CHECKSTYLE_RULES="/home/ec2-user/grader/config/checks.xml"
CHECKSTYLE_OUT="quality.log"
"${CHECKSTYLE}" -c "${CHECKSTYLE_RULES}" -f xml -o "${CHECKSTYLE_OUT}" $(find "${_toCheck}" -name "*.java") 2>"quality.err"
When I run this, I get the following error in quality.err:
./grader/eval.sh: line 10: java -jar /home/ec2-user/grader/ext/checkstyle-6.15-all.jar: No such file or directory
I have tried to run the same command directly in the terminal and it is working. Both checkstyle-6.15-all.jar and checks.xml are where they should be.
What could cause this problem?
Change "${CHECKSTYLE}" to ${CHECKSTYLE} (without the quotes).
You are passing the entire value of the CHECKSTYLE variable as a single word (that's what the quotes do), so the shell is looking for a relative directory named java -jar, and is trying to find a file under that (nonexistent) directory with the path home/ec2-user/grader/ext/checkstyle-6.15-all.jar.
When you envoke "${CHECKSTYLE}" the shell thinks that is the command you are running. There is no such file name with the spaces and options have you have included there. If you envoke it simply as ${CHECKSTYLE} (drop the quotes) the shell will process it for whitespace as normal and split it into the appropriate pieces for creating the process.

run java app on unix machine a :> sign to input something

I run my java application on unix machine. After I input the command, it show me ">" sign. It seems I am in a interactive state with my application, but my application shouldn't interact with me. Instead, it just write something to files.
root#ip...:/mnt/test/java -cp "./" pack.foo
>
On windows machine, it just works file.
I also tried:
nohup root#ip...:/mnt/test/java -cp "./" pack.foo &
but still
On any UNIX system, the java syntax should be:
javac -cp <classpath of application> MyClass.java
java -cp <same classpath as above> MyClass
the second command should just be the name of the .class file you are attempting to run, and if everything is in the current directory, the argument for -cp should be "." without quotation marks
java -cp . MyClass

Java Jar file SoftLink in Linux

I have created a jar file , it reads from standard input and print them out to the standard output.
Below is how you can use the app:
cat /ephemeral/test/input | java -jar /ephemeral/test/Hello.jar >> /ephemeral/test/output
I am wondering is it possible to add my Hello.jar to be a Linux Command, let's say -hello-:
So next time I could just do something like:
hello /ephemeral/test/input /ephemeral/test/output
I am not that much familiar with Linux Soft Link and Java, so any help or information would be appricated!
UPDATE:
thanks for reno's inspiring answer, I put the cat ... | .. >> .. into a shell script hello.sh.
Now I can do something like:
./hello.sh /inputpath/input outputpath/output
(Note: you should not use $0, $0 is actually the name the file itself instead of input arguments)
Now, the last question is how could you access the shell script EVERYWHERE, like how you call basic shell cmds: ls..cat..echo..
I have read a tutorial described exactly what I want(reach to the end of the tutorial directly):
I did add the path of the directory where the hello.sh exists into the path variable.
I created a bin folder which is like mkdir /home/ubuntu/bin and put my shell script there.
However, I still have problem do what the author described:
hello input output (in my case)
Does anyone know what is going wrong here?
you can write a shell script say test.sh and copy your code to test.sh
!/bin/bash
cat $0 | java -jar /ephemeral/test/Hello.jar >> $1
and execute the script by passing your input and output file name something like this:
test.sh /ephemeral/test/input /ephemeral/test/output
The way to do this is to write a shell script (usually hello.sh) that contains the necessary java -jar command.

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"

Categories