Making a jar that accepts names and values on command line - java

Relevant Links:
Java: Passing combination of named and unnamed parameters to executable Jar/Main Method
Passing arguments to JAR which is required by Java Interpreter
I understand how to pass strings from the command line to execute my main method:
java -jar myApp.jar "argument1"
My question is: is it possible to set up my main method in a way that would accept:
java -jar myApp.jar -parameter1 "argument1"
Here is my simple main method for context if you need it
public class myApp {
public static void main (String[] args){
System.out.println("Argument1: "+args[0]);
}
}

Thing is: whatever you pass on the command line goes into that args array. To be precise:
java xxx -jar JAR yyy
xxx: would be arguments to the JVM itself, like -Dprop:value for properties
yyy: are passed as arguments to your main method
So, when you pass "-parameter 'argument1'" then ... that is what you will see inside main!
In other words: the idea that some command line strings are "arguments"; and other are "-switches", or "--flags", or "-h" shortcuts ... you simply have to write the code to do all of that.
Luckily, there are plenty of libraries out there that help with that; see enter link description here

Related

How to run a java jar file and get store the output in shell script variables

I have a java class, which has 3 methods and each method returns a String. I exported the .jar file out of that Java project. When I run the jar file from git bast using the command ./script1.sh, I get the output in the command window. My question is, how can I assign those values to the three variable that are in the script1.sh file. If I type echo ${"Source_branch"}, i should get output as "XXX_Source_Branch".
Here is my Java code :
package com.main;
public class Engine {
public static void main(String[] args) {
try {
getSourceBranch();
getDestinationBranch();
getDestEnv();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String getSourceBranch() {
return "XXX_Source_Branch";
}
public static String getDestinationBranch() {
return "XXX_Dest_Branch";
}
public static String getDestEnv() {
return "XXX_Dest_Env";
}
}
The name of the jar file is Engine.jar.
And my script file is
runjar.sh
java -jar Engine.jar
Source_branch
Destination_brnach
Destination_env
pass data from java to bash
If you want to save data from java to the overlaying String, you will need to print that to System.out and read them from the shell.
Java code:
System.out.println("your source branch")
System.out.println("your destination branch")
Shell code
out="$(java -jar Engine.jar)"
sBranch="$(echo "$out"|sed -n '1p' /dev/stdin)"
destBranch="$(echo "$out"|sed -n '2p' /dev/stdin)"
pass data from bash to java
If you hard-code the Strings, java will just use the Strings. If you want to change that, you will need to modify your java code.
option 1 - arguments
If you want to pass the strings in the script using java -jar Engine.jar Source_branch Destination_brnach Destination_env, you can use them in your main method with the args parameter.
For example, you can print the first String in your main method using
System.out.println(args[0]);
If you do that, please test if args.length is greater than the highest argument you are accessing.
option 2 - System properties
If you want to get parameters without accessing args(independent of your main method), you will need to use System properties.
At first, change the script to be like that:
java -jar -DSource_branch=yourSourceBranch -DDestination_branch=yourDestinationBranch -DDestination_env=yourDestinationEnv
Engine.jar
Note that -D. That indicates that you are passing System properties. The syntax for this is -D<key>=<value> and it should be located between java and -jar.
Also, you will need to use System.getProperty() to access it from anywhere in your code.
For example:
public static String getSourceBranch() {
return System.getProperty("Source_Branch");
}
Create a .sh file with any file editor, like-
$> vi runJar.sh
Then, paste the below script ,
#!/bin/sh
java -jar Engine.jar
After saving the file, give execution permission -
$> chmod +x runJar.sh
Then run using
$> ./runJar.sh
Make sure the jar file and shell script file are in the same directory.

Run single junit test with cli

I need to run a single test case run through the cli. I created a runner class
public class Runner {
public static void main(String ... args) throws ClassNotFoundException {
String[] classAndMethod = args[0].split("#");
Request request = Request.method(Class.forName(classAndMethod[0]),
classAndMethod[1]);
Result result = new JUnitCore().run(request);
System.exit(result.wasSuccessful() ? 0 : 1);
}
}
using this answer
Run single test from a JUnit class using command-line.
I downloaded from github a project (https://github.com/apache/incubator-dubbo) on which I want to run the single method, I positioned myself from terminal on the directory containing the Runner class I created and I launched the following command:
java -cp /path/incubator-dubbo/dubbo-cluster /usr/share/java/junit4-4.12.jar /pathClassRunner/src/com/company/Runner org.apache.dubbo.rpc.cluster.StickyTest#testHeartbeat
but I got the following error:
Error: Could not find or load main class pathClassRunner.src.com.company.Runner
can someone help me?
thanks
The command expects you to include any paths in the classpath with NO spaces. A space means that the arguments for the classpath has ended. It there is a space in one of your paths you may include double quotes:
java -cp path1:path2:path3 classname argument
java -cp "path1:path2:path3" classname argument
If a path starts with / it's a full path. If not it's relative to where you run your command. The classname must be the name of the class, not the file, so that means no .class. If your class specifies any package, then the classname is required to contain the package name too, and the path is to the root of the package, not the class itself.
Check that your user has proper access to the files, then try:
java -cp /path/incubator-dubbo/dubbo-cluster:/usr/share/java/junit4-4.12.jar:/pathClassRunner/src/com/company Runner org.apache.dubbo.rpc.cluster.StickyTest#testHeartbeat
I'm assuming your Runner is in the default package. In case it's in the com.company package, you'll want to run this instead:
java -cp /path/incubator-dubbo/dubbo-cluster:/usr/share/java/junit4-4.12.jar:/pathClassRunner/src com.company.Runner org.apache.dubbo.rpc.cluster.StickyTest#testHeartbeat
Another assumption is that your Runner.class is in your /pathClassRunner/src... directory.

Pass JVM argument with space in batch file

I had batch script which executes TestRun class by taking jvm arguments as shown below
java -cp "./lib/*;./statoil.jar" -DURI=localhost:8080 -DOWUser=abc -DOWPassword=abc123 -DpipelineName=EDMStatOil -Ddatabase=edm -DproviderName=141Provider -DdestinationName=110EDM -DproviderWellName=Serno Grad com.statoil.rts.test.TestRun
But while running batch script getting error:
Error: Could not find or load main class Grad
I know it is treating Grad as class file. But how we can avoid this error while passing jvm argument with space?
Java doesn't care if there is a space in the JVM argument's value, but the terminal will split -DproviderWellName=Serno Grad into two command line arguments and pass those to the java executable.
You have to put quotes around the whole argument:
java "-DproviderWellName=Serno Grad"
In you batch file try setting the variable first and then pass that parameter to the actual command like these.
set WellName="Serno Grad"
java -cp "./lib/*;./statoil.jar" -DURI=localhost:8080 -DOWUser=abc -DOWPassword=abc123 -DpipelineName=EDMStatOil -Ddatabase=edm -DproviderName=141Provider -DdestinationName=110EDM -DproviderWellName=%WellName% com.statoil.rts.test.TestRun
OR
set WellName="Serno Grad"
java -cp "./lib/*;./statoil.jar" -DURI=localhost:8080 -DOWUser=abc -DOWPassword=abc123 -DpipelineName=EDMStatOil -Ddatabase=edm -DproviderName=141Provider -DdestinationName=110EDM -DproviderWellName="%WellName%" com.statoil.rts.test.TestRun
On my system either of them works fine.
try with escape characters -DproviderWellName="\"Serno Grad\""

Passing empty shell variable to Java command line causes "Error: Could not find or load main class"

java "$homeOption" -cp "$classPath" "com.civilizer.extra.tools.DataBroker" -import "$importPath"
If $homeOption is not empty, the command above works, but $homeOption is empty, it can't find the main class
Error: Could not find or load main class
Looks like Empty $homeOption parameter affects classpath string in a bad way; It's so strange behavior to me;
Anyone running into this issue and understanding why?
Edit:
In case that it works:
The actual command line is as follows;
com.civilizer.extra.tools.DataBroker is a Java class with main method, and it is included in that verbose classpath;
in this case, $homeOption is -Dcivilizer.private_home_path=/Users/bsw/.civilizer
java -Dcivilizer.private_home_path=/Users/bsw/.civilizer -cp /Users/bsw/test/trysomething/civilizer/target/civilizer-1.0.0.CI-SNAPSHOT/WEB-INF/classes:/Users/bsw/test/trysomething/civilizer/extra/lib/:/Users/bsw/test/trysomething/civilizer/target/civilizer-1.0.0.CI-SNAPSHOT/WEB-INF/lib/:/Users/bsw/test/trysomething/civilizer/target/extra com.civilizer.extra.tools.DataBroker -import
In case that it can't find the main class:
java -cp /Users/bsw/test/trysomething/civilizer/target/civilizer-1.0.0.CI-SNAPSHOT/WEB-INF/classes:/Users/bsw/test/trysomething/civilizer/extra/lib/:/Users/bsw/test/trysomething/civilizer/target/civilizer-1.0.0.CI-SNAPSHOT/WEB-INF/lib/:/Users/bsw/test/trysomething/civilizer/target/extra com.civilizer.extra.tools.DataBroker -import
As I mentioned, only $homeOption is empty; but it just makes the issue; BTW, even if $homeOption is empty, the class will run without a problem, but you know, the main method is missing in the first place in this case, it doesn't matter
You could resolve this by populating an array and passing that to the java command instead.
opts=( )
if [[ -n "$homeOption" ]]; then
opts+=( "$homeOption" )
fi
java "${opts[#]}" -cp "$classPath" "com.civilizer.extra.tools.DataBroker" -import "$importPath"
The issue you are seeing is because bash is passing a blank string to java as the first argument, and java is taking the blank string to be the class:
compare:
$ java foo
Error: Could not find or load main class foo
vs:
$ java ''
Error: Could not find or load main class
You can see that java prints the class name it can't find in the error, but your case, and my second case above, the class name is an empty string, so the class name is blank in the error message as well.
The reason my solution works is if the array is empty then bash won't pass in any empty arguments. And the array is created empty, and left empty unless $homeOption has a non-empty string.

Calling the main method of another class

I am trying to call the main method of a function in another code.
The example from the command line I am trying to reproduce is:
java -cp stanford-ner.jar edu.stanford.nlp.ie.crf.CRFClassifier -loadClassifier ner-model.ser.gz -testFile jane-austen-emma-ch2.tsv
from here
In my code, I wrote:
String[] args = {"-loadClassifier ner-model.ser.gz",
"-testFile jane-austen-emma-ch2.tsv"};
CRFClassifier.main(args);
but when I try to execute this code, I get the following error:
Unknown property |loadClassifier ner-model.ser.gz|
Unknown property |testFile jane-austen-emma-ch2.tsv|
How can I call the main function from my code?
Every part of the command line, after the class name, is a separate argument. So the code should be
String[] args = {"-loadClassifier", "ner-model.ser.gz", "-testFile", "jane-austen-emma-ch2.tsv"};

Categories