Submit and vote on feature ideas.

Welcome to the new Parasoft forums! We hope you will enjoy the site and try out some of the new features, like sharing an idea you may have for one of our products or following a category.

HOW TO EXECUTE JAR FILE USING JYTHON OR GROOVY SCRIPT VIA EXTENSION TOOL

mpreeti2001
mpreeti2001 Posts: 7
edited March 2017 in SOAtest

we are trying to run jar file with a parameter which will generate data files and load into a folder. used to do with windows bat file but its not working in linux, so was trying to see if groovy or jython can help.
Tried this but getting error in jython:
from java.lang import *
from java.io import *
from soaptest.api import *
from com.parasoft.api import IOUtil
from java.io import File
from com.parasoft.api import Application

def callJavaFromSoaTest(input, context):
command = 'java -jar input cksi'
result = command.execute().text
Application.showMessage(result)
return result.toString()

Error received: Error during script execution. View Details for more information.

Traceback (most recent call last):

File "", line 11, in callJavaFromSoaTest

AttributeError: 'str' object has no attribute 'execute'

Comments

  • Thomas Moore
    Thomas Moore Posts: 82 admin

    Hi mpreeti,

    Instead of using the extension tool, have you tried using an External tool?

    The external tool can be used to execute programs that are on your machine without having to use scripts, and can be found under "All Tools" in the add test wizard.

    Here is how I have my External Tool setup:

    If you wish to see the console output from this execution, you can chain an Edit tool to the output of the External Tool, and this will allow you to view the output.

    Additionally, if you do not have an external java installation on your machine, you can use the one that comes packaged with SOAtest at:
    C:\Program Files\Parasoft\Test\\plugins\com.parasoft.xtest.jdk.eclipse.core.win32.x86_64_\jdk\bin

    Hope this helps!

    Thomas

  • jakubiak
    jakubiak Posts: 795 admin

    Here is a groovy script that will execute the jar in a separate process and capture the output that gets sent to standard output (if you need standard error as well you will need to slightly modify it to also capture process.getErrorStream()):

    import java.lang.*;
    import java.io.*;
    import com.parasoft.api.*;
    
    public void runJar() {
        Process process;
        try {
            process = Runtime.getRuntime().exec("java -jar <full path to jar>")
            StringBuilder buf = new StringBuilder();
            InputStream is = process.getInputStream();
            int i = 0;
            while ((i = is.read()) != -1) {
                buf.append((char) i);
            }
            process.waitFor();
            Application.showMessage(buf.toString());
        } finally {
            closeStreams(process);
        }
    }
    public static void closeStreams(Process process) {
        if (process != null) {
            try {
                process.getInputStream().close();
            } catch (IOException e) {
            }
            try {
                process.getErrorStream().close();
            } catch (IOException e) {
            }
            try {
                process.getOutputStream().close();
            } catch (IOException e) {
            }
        }
    }
    
  • mpreeti2001
    mpreeti2001 Posts: 7

    Thank you for the response, i have tried both ways but when we run this jar file with parameter it should load the files into a different folder. when i run extension tool i am getting success but files are not loading. ALso i am not sure how we can give the parameter as we did in .bat file : java -jar Excel2Dat.jar cksi

    This is what i tried in extension tool:
    import java.lang.*;
    import java.io.*;
    import com.parasoft.api.*;

    public void runJar(input) {
    Process process;
    try {
    process = Runtime.getRuntime().exec("java -jar input"); //input i have attached the jar file. but where should i give the cksi as shown above.
    StringBuilder buf = new StringBuilder();
    InputStream is = process.getInputStream();
    int i = 0;
    while ((i = is.read()) != -1) {
    buf.append((char) i);
    }
    process.waitFor();
    Application.showMessage(buf.toString());
    } finally {
    closeStreams(process);
    }
    }
    public static void closeStreams(Process process) {
    if (process != null) {
    try {
    process.getInputStream().close();
    } catch (IOException e) {
    }
    try {
    process.getErrorStream().close();
    } catch (IOException e) {
    }
    try {
    process.getOutputStream().close();
    } catch (IOException e) {
    }
    }
    }

  • jakubiak
    jakubiak Posts: 795 admin

    In the string that you pass to Runtime.getRuntime().exec, you should include "cksi". Also, make sure that you don't just include the jar file name - you need to include the entire path to the jar file:

    Runtime.getRuntime().exec("java -jar c:/full/path/to/jar/file.jar cksi")

    Also ensure that Java is on your path before starting up SOAtest.

  • mpreeti2001
    mpreeti2001 Posts: 7

    so we are running these tests through jenkins so how can we give the full path for stash as its going to be different when it runs from remote machine

  • jakubiak
    jakubiak Posts: 795 admin

    You should put the jar file in the same directory as your .tst file, and then make a slight modification to the script like this (pay attention to the method signature, and the first two lines after the "try" keyword). I am using a method from the SOAtest Extensitibility API to get the location of a file that is relative to the .tst file (you can view the API JavaDocs by going to Help > Help Contents > Parasoft SOAtest Extensibility API):

    import java.lang.*;
    import java.io.*;
    import com.parasoft.api.*;
    
    public void runJar(Object input, ScriptingContext context) {
        Process process;
        try {
            File jarFile = context.getAbsolutePathFile("yourJarFile.jar");
            process = Runtime.getRuntime().exec("java -jar " + jarFile.getAbsolutePath() + " cksi")
            StringBuilder buf = new StringBuilder();
            InputStream is = process.getInputStream();
            int i = 0;
            while ((i = is.read()) != -1) {
                buf.append((char) i);
            }
            process.waitFor();
            Application.showMessage(buf.toString());
        } finally {
            closeStreams(process);
        }
    }
    
    public static void closeStreams(Process process) {
        if (process != null) {
            try {
                process.getInputStream().close();
            } catch (IOException e) {
            }
            try {
                process.getErrorStream().close();
            } catch (IOException e) {
            }
            try {
                process.getOutputStream().close();
            } catch (IOException e) {
            }
        }
    }
    
  • mpreeti2001
    mpreeti2001 Posts: 7

    Thank you , 1st option with external tool worked. Some how extension tool was not writing the data required from jar file. we are moving with external tool. Thank you for your time.

  • mpreeti2001
    mpreeti2001 Posts: 7

    Hi, i have changed the 2 lines under try as shown above:
    File jarFile = context.getAbsolutePathFile(${project_loc:PZN-QA}/PZN-QA/Manasi/Excel2Dat.jar);
    process = Runtime.getRuntime().exec("java -jar " + jarFile.getAbsolutePath() + " cksi")

    also moved the Excel2Dat.jar file under Manasi folder where the test suite exists.
    But still i am getting error:
    No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.$() is applicable for
    argument types: (Script290$_runJar_closure1) values: [Script290$_runJar_closure1@65ad5477]
    Possible solutions: is(java.lang.Object), any(), get(java.lang.String), any(groovy.lang.Closure),
    use([Ljava.lang.Object;), wait()

    java.lang.NoSuchMethodException: No signature of method:
    org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.$() is applicable for argument types:
    (Script290$_runJar_closure1) values: [Script290$_runJar_closure1@65ad5477]
    Possible solutions: is(java.lang.Object), any(), get(java.lang.String), any(groovy.lang.Closure),
    use([Ljava.lang.Object;), wait()

    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.invokeImpl(GroovyScriptEngineImpl.java:374)
    
    at
    

    org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.invokeFunction(GroovyScriptEngineImpl.java:171)

    at com.parasoft.scripting.jsr223.UScript.doInvokeFunction(UScript.java:109)
    
    at com.parasoft.scripting.jsr223.UScript.invokeFunction(UScript.java:101)
    
    at com.parasoft.scripting.jsr223.ScriptCode$ScriptMethodRunnable.run(ScriptCode.java:121)
    
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    
    at java.lang.Thread.run(Thread.java:745)
    
  • jakubiak
    jakubiak Posts: 795 admin

    Do not use the Eclipse variable in the argument to getAbsolutePathFile() - that method expects the argument to be a relative path from the .tst file to the file you are trying to reference. So, if your structure is the following:

    dir
        test.tst
        file.jar
    

    then you would simply pass "file.jar" to that method. If your structure is the following:

    test.tst
    dir
       file.jar
    

    then you would pass "dir/file.jar" to that method.

    Also ensure that your extension tool is set to run the "runJar" method and not the "closeStreams" method.

  • mpreeti2001
    mpreeti2001 Posts: 7

    I have specified:
    File jarFile = context.getAbsolutePathFile("Excel2Dat.jar");
    by moving the jar file to same directory as tst file.

    But the files need to be generated from that jar are not showing up. It shows success but does not show the output.

  • benken_parasoft
    benken_parasoft Posts: 1,228 ✭✭✭

    I highly recommend using built-in tooling before resorting to writing custom scripts. In other words, please use the External Tool. However, if for some reason you believe you absolutely must script this, I want to mention that the example provided earlier very trivial and therefore would not fits every user's specific needs. However, it does offer a good starting point if you really need such extra level of customization.

    As he noted, the script is not capturing any messages printed to STDERR. So, if your Excel2Dat.jar happens to be printing an error then you may not see it for this very reason. Instead of using java.lang.Runtime.getRuntime().exec(), I recommend using java.lang.ProcessBuilder instead and use the redirectErrorStream() method. Alternatively, forgo the scripting entirely and just use the External Tool to capture the process output. The External Tool already knows how to do all this kind of stuff correctly. :)

  • mpreeti2001
    mpreeti2001 Posts: 7

    hi , i have tried using external tool as attached below, but i am getting error:

    Exception in thread "main" java.lang.NullPointerException
    at execute.Execute.main(Execute.java:137)

  • Thomas Moore
    Thomas Moore Posts: 82 admin
    edited March 2017

    Hi mpreeti,

    Is cksi a separate flag? Have you tried putting it into the argument for the previous statement?

    Try deleting the current cksi flag and moving it into the argument for -jar. It should look like

    "<path_to_jar>/Excel2Dat.jar cksi"

    Hope this helps!

    Thomas

  • benken_parasoft
    benken_parasoft Posts: 1,228 ✭✭✭

    The NullPointerException sounds like it is coming from the "main" method in the java code in your jar. Unfortunately, I can't explain why your jar returns certain errors under certain conditions. You would need to understand the error from your jar in order to know what causes that, like if you are passing an incorrect argument to it or something.