Execute Java class using groovy code - java

I am trying to execute a java .class file using groovy script :
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = "java ${fileName}".execute()
proc.consumeProcessOutput(sout, serr)
proc.waitFor()
println "out> $sout err> $serr"
It gives error: err> Error: Could not find or load main class cle47d1d78d99a44a8ba01f0bc7612ad16 (class name generated using uuid). But when I execute it in bash it gives proper output. I checked filename, pwd and ensured that the .class file exist in the folder where groovy tries to execute command.
I am able to run other commands and also compile .java file successfully using:
def proc = "javac ${file.path}".execute()
Please suggest.

What is the value of ${fileName} . I think it contains value like "ABC.java" . Where as you must use command "java ${className}".
Use:
java ${className}
ex:
If com.abc.ABC is the class containing the main function
java com.abc.ABC
Package is also necessary

Related

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.

Is there a way to have Java call a bash script which calls javac and java?

I'm trying to train a neural network to play Halite 3. The provided interface is a bash script which:
1. compiles my bot
2. calls the binary file with a string to run the bot java myBot
I'm trying to run this script from Java to train the network.
I've tried using a ProcessBuilder to run the script as well as the binary in the script. Running the script produces no output, and using echo I've determined that the program terminates when javac is called in the script. Removing that call, it terminates when the program is run.
I've tried calling the program directly as well using ProcessBuilder, and this does indeed produce output. The issue is it doesn't run the bots properly saying it can't find the file. I've tried changing the path to be relative to different directory levels as well as the absolute path (the java command doesn't seem to like absolute paths?).
Calling the binary directly:
List<String> cmd = new ArrayList<>();
cmd.add(dir+ "/src/halite");
// Replay
cmd.add("--replay-directory");
cmd.add(dir+"/replays/");
// Options
cmd.add("--results-as-json");
cmd.add("--no-logs");
// Dimensions
cmd.add("--width");
cmd.add("16");
cmd.add("--height");
cmd.add("16");
// Players
cmd.add("\"java -cp . myBot\"");
cmd.add("\"java -cp . myBot\"");
Process proc = new ProcessBuilder(cmd).start();
InputStream is = proc.getInputStream();
Scanner s = new Scanner(is);
while (s.hasNext()){
System.out.println((String) s.next());
}
This code does produce a JSON, however, I get an error in my logs saying that the bots do not run.

Error in Udf of pig

I am new to pig. I wrote a UDF in pig and used it in my pig script. But it gives following error
ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1070: Could not resolve UserDefined.PartsOfSpeech using imports: [, java.lang., org.apache.pig.builtin., org.apache.pig.impl.builtin.]
Here is my UDF code
public String exec(Tuple input) throws IOException {
//my code here
}
Here is my pig script
REGISTER /home/bigdata/NetBeansProjects/UserDefined/dist/UserDefined.jar
a = load '/user/bigdata/json' using TextLoader() as (input:chararray);
b = foreach a GENERATE UserDefined.PartsOfSpeech(input);
In the above code UserDefined is my package name and PartsOfSpeech is my class name
The error message says that Pig cannot find UserDefined.PartsOfSpeech.
What package declaration does PartsOfSpeech.java have at the top of the file?
If the package declaration is package com.my.company; try this instead:
REGISTER /home/bigdata/NetBeansProjects/UserDefined/dist/UserDefined.jar
a = load '/user/bigdata/json' using TextLoader() as (input:chararray);
b = foreach a GENERATE com.my.company.PartsOfSpeech(input);
That is, replace UserDefined.PartsOfSpeech(input) with com.my.company.PartsOfSpeech(input) since the UDF is located in the package com.my.company.
Also, consider using the DEFINE keyword in your Pig script so you don't need to repeat com.my.company every time you use PartsOfSpeech.
DEFINE PartsOfSpeech UserDefined.dist.PartsOfSpeech();
REGISTER /home/bigdata/NetBeansProjects/UserDefined/dist/UserDefined.jar
a = load '/user/bigdata/json' using TextLoader() as (input:chararray);
b = foreach a GENERATE PartsOfSpeech(input);
There is more information about DEFINE in Chapter 5 of Alan Gates' Programming Pig: http://chimera.labs.oreilly.com/books/1234000001811/ch05.html#udf_define.
Here is an example of DEFINE from Gates' book:
--define.pig
register 'your_path_to_piggybank/piggybank.jar';
define reverse org.apache.pig.piggybank.evaluation.string.Reverse();
divs = load 'NYSE_dividends' as (exchange:chararray, symbol:chararray,
date:chararray, dividends:float);
backwards = foreach divs generate reverse(symbol);
Before compiling your UDF(java class) make sure you have mentioned package name properly. for example if you have mentioned package name-
package com.pig.udf;
It means you need to take care of directory in your linux box as well.
you can follow below mentioned steps to create jar -
Create directory using
mkdir -p com/pig/udf
Create your java class with package com.pig.udf
Compile your java source code using command
javac -cp /usr/lib/pig-0.12.0.2.0.6.0-76.jar YourClass.java
Then go to the directory where you want to create jar for now -
cd ../../..
Now create jar using below command
jar -cvf yourJarName.jar com/
Register the jar in your script using keyword "register" followed by path of the jar
Now use your jar with keyword com.pig.udf.YourJavaClassName
for your scenerio -
REGISTER /home/bigdata/NetBeansProjects/UserDefined/dist/UserDefined.jar
a = load '/user/bigdata/json' using TextLoader() as (input:chararray);
b = foreach a GENERATE com.pig.udf.PartsOfSpeech(input);

ProcessBuilder not executing Java class file properly

In a java file I am calling command line statement to execute another java file. This is what I am doing:
List<String> paramsExecute = new ArrayList<String>();
paramsExecute.add("java");
paramsExecute.add("-cp");
paramsExecute.add("input\programs\User_K Program1");
paramsExecute.add("1 2 3");
ProcessBuilder builderExecute = new ProcessBuilder(paramsExecute);
builderExecute.redirectOutput(new File(a.txt));
builderExecute.redirectError(new File(b.txt));
Execution of one of the Java files is producing b.txt as:
Error: Could not find or load main class 1 2 3
Another java file is producing b.txt as:
Usage: java [-options] class [args...] ...
But, when I am running these statements directly from the command line, it is executing correctly. The folder input\programs\ is in the same path as the src folder. The src folder contains the Java file containing the ProcessBuilder program. I have verified that the .class file is getting created correctly and in the right folder. I am running the program in windows.
Any help appreciated!!
This paramsExecute.add("input\programs\User_K Program1"); is been treated as a single command/parameter, saying that the class path should be equal to input\programs\User_K Program1
I think you want to use something more like...
paramsExecute.add("input\programs\User_K");
paramsExecute.add("Program1");
You should specify the classpath after '-cp' like
List<String> params = new ArrayList<String>();
params.add("java"); /* name of program to run, java */
params.add("-cp"); /* -cp */
params.add(System.getProperty("java.class.path")); /* class path information */
params.add("pkg.to.yourclass.ClassToRun"); /* full quailified class name */
params.add("1"); params.add("2"); params.add("3"); /* this is parameter to main */
"input\programs\User_K Program1" in your code is treated as a classpath information, not class to run because it follows '-cp', and "1 2 3" as a class name, not arguments passed to the main method.
It is not easy to retrieve classpath from the scatch.
If you want to create a process using an class located in the sample src folder, It is good to use System.getProperty("java.class.path"); to inherite classpath, or You should type the path info manually.

Python: How can I execute a jar file through a python script

I have been looking for an answer for how to execute a java jar file through python and after looking at:
Execute .jar from Python
How can I get my python (version 2.5) script to run a jar file inside a folder instead of from command line?
How to run Python egg files directly without installing them?
I tried to do the following (both my jar and python file are in the same directory):
import os
if __name__ == "__main__":
os.system("java -jar Blender.jar")
and
import subprocess
subprocess.call(['(path)Blender.jar'])
Neither have worked. So, I was thinking that I should use Jython instead, but I think there must a be an easier way to execute jar files through python.
Do you have any idea what I may do wrong? Or, is there any other site that I study more about my problem?
I would use subprocess this way:
import subprocess
subprocess.call(['java', '-jar', 'Blender.jar'])
But, if you have a properly configured /proc/sys/fs/binfmt_misc/jar you should be able to run the jar directly, as you wrote.
So, which is exactly the error you are getting?
Please post somewhere all the output you are getting from the failed execution.
This always works for me:
from subprocess import *
def jarWrapper(*args):
process = Popen(['java', '-jar']+list(args), stdout=PIPE, stderr=PIPE)
ret = []
while process.poll() is None:
line = process.stdout.readline()
if line != '' and line.endswith('\n'):
ret.append(line[:-1])
stdout, stderr = process.communicate()
ret += stdout.split('\n')
if stderr != '':
ret += stderr.split('\n')
ret.remove('')
return ret
args = ['myJarFile.jar', 'arg1', 'arg2', 'argN'] # Any number of args to be passed to the jar file
result = jarWrapper(*args)
print result
I used the following way to execute tika jar to extract the content of a word document. It worked and I got the output also. The command I'm trying to run is "java -jar tika-app-1.24.1.jar -t 42250_EN_Upload.docx"
from subprocess import PIPE, Popen
process = Popen(['java', '-jar', 'tika-app-1.24.1.jar', '-t', '42250_EN_Upload.docx'], stdout=PIPE, stderr=PIPE)
result = process.communicate()
print(result[0].decode('utf-8'))
Here I got result as tuple, hence "result[0]". Also the string was in binary format (b-string). To convert it into normal string we need to decode with 'utf-8'.
With args: concrete example using Closure Compiler (https://developers.google.com/closure/) from python
import os
import re
src = test.js
os.execlp("java", 'blablabla', "-jar", './closure_compiler.jar', '--js', src, '--js_output_file', '{}'.format(re.sub('.js$', '.comp.js', src)))
(also see here When using os.execlp, why `python` needs `python` as argv[0])
How about using os.system() like:
os.system('java -jar blabla...')
os.system(command)
Execute the command (a string) in a subshell. This is implemented by calling the Standard C function system(), and has the same limitations. Changes to sys.stdin, etc. are not reflected in the environment of the executed command.

Categories