Executing python file from Java code giving errors - jython

I am executing python scripts from Java using the jython library(jython-standalone-2.7-b3). My only intention is to be able to trigger and execute python script files from my java code. I was able to do this properly writing standalone main classes and things went well. Now I put the same code inside my application(within my app server), and now for the same script i get errors at each and every stage. It says a few module cannot be found etc. But adding more to my confusion the same code and script executes just fine when i try it again from the main class. Is there anything that the running environment has to inject to make this run..
The code snippet used
public void executeScript(String inputFile, String outputFile) throws FileNotFoundException {
final PythonInterpreter inter = new PythonInterpreter(null, new PySystemState());
Writer writer = null;
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile)));
inter.setOut(writer);
inter.execfile(inputFile);
}
The exception that i get is
File "/data/WorkArea/anoj/APPNEW/com.anoj.commons.core/lib/jython-standalone-2.7-b3.jar/Lib/posixpath.py", line 392, in normpath
AttributeError: 'NoneType' object has no attribute 'startswith'
at org.python.core.Py.AttributeError(Py.java:177)
at org.python.core.PyObject.noAttributeError(PyObject.java:946)
at org.python.core.PyObject.__getattr__(PyObject.java:941)
at posixpath$py.normpath$27(/data/WorkArea/anoj/APPNEW/com.anoj.commons.core/lib/jython-standalone-2.7-b3.jar/Lib/posixpath.py:412)
at posixpath$py.call_function(/data/WorkArea/anoj/APPNEW/com.anoj.commons.core/lib/jython-standalone-2.7-b3.jar/Lib/posixpath.py)
at org.python.core.PyTableCode.call(PyTableCode.java:166)
at org.python.core.PyBaseCode.call(PyBaseCode.java:137)
at org.python.core.PyFunction.__call__(PyFunction.java:347)
at sysconfig$py.f$0(/data/WorkArea/anoj/APPNEW/com.anoj.commons.core/lib/jython-standalone-2.7-b3.jar/Lib/sysconfig.py:712)
at sysconfig$py.call_function(/data/WorkArea/anoj/APPNEW/com.anoj.commons.core/lib/jython-standalone-2.7-b3.jar/Lib/sysconfig.py)
at org.python.core.PyTableCode.call(PyTableCode.java:166)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.imp.createFromCode(imp.java:393)
at org.python.core.util.importer.importer_load_module(importer.java:109)
at org.python.modules.zipimport.zipimporter.zipimporter_load_module(zipimporter.java:161)
at org.python.modules.zipimport.zipimporter$zipimporter_load_module_exposer.__call__(Unknown Source)
at org.python.core.PyBuiltinMethodNarrow.__call__(PyBuiltinMethodNarrow.java:47)
at org.python.core.imp.loadFromLoader(imp.java:520)
at org.python.core.imp.loadFromLoader(imp.java:520)
Please help..

Related

Creating common test data for multiple feature files

My requirement is as follows:
I have a couple of .feature files. I want to create test data that would be common to all of these feature files. Once the test data is created the scenarios will be run from the feature files.
I also want some info back after the test data is created. eg., ids of the data that i have created. So i can use this info to call the api's, add in payloads in my scenarios.
I think we could do this by:
1. Creating a junit java file. I define a static method with #BeforeClass in there and use Karate's runner() to run my create-test-data.feature file (I can use Karate to hit application api to create some data). I define a property in my java class of type Object and set it with the result of Runner.runFeature().
Then I create a separate feature file test-data-details.feature. I define my Java Interop code here. eg.,
def test_data =
"""
var JavaOutput = Java.type('com.mycompany.JavaFile');
var testData = JavaOutput.propertyName;
"""
Now that I have my test data object in my test-data-details.feature file. I call this .feature file (callonce) in the Background section of my feature files that have test scenarios in. So I can retries the test data details like id, name. etc that I can then use in the api request paths and payloads.
I am not sure if the above design is the correct way to go ahead. I tried but getting some issues in my Java file where getClass() below complains that it cannot be used in static method.
#RunWith(Karate.class)
public class AccountRunner {
public static Object job = null;
#BeforeClass
public static void create_job(){
Map<String, Object> result = Runner.runFeature(getClass(), "test-data.feature", null, true);
job = result.get("job");
}
}
Now all of the above can be totally wrong. Need help on how to tackle this scenario in Karate.
Thanks
From your question I understand you have a common test data feature file, which you want to run before all the test and hold that response in a variable that can be used in all of the test features.
You can also achieve this in karate-config.js using karate.callSingle()
In your karate-config.js
config["testdata"] = karate.callSingle("test-data.feature")
Your test-data.feature will be executed once before all the tests and store the response in testdata you can use this variable directly in your feature.
So i have implemented the following design:
I have created two methods one with BeforeClass and other with AfterClass annotation in my TestRunner.java file. In these methods I am able to call the specific data creation and clean-up feature files and pass args as Json object.
#RunWith(Karate.class)
#KarateOptions(tags = {"~#ignore"})
public class AccountRunner {
public static Map<String, Object> result = null;
#BeforeClass
public static void create_job() throws IOException, ParseException {
Class clazz = AccountRunner.class;
URL file_loc = clazz.getResource("create-test-data-1.json");
File file = new File(file_loc.getFile());
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader(file));
JSONObject jsonObject = (JSONObject) obj;
Map<String, Object> args = new HashMap();
args.put("payload", jsonObject);
result = Runner.runFeature(CommonFeatures.class, "create-data.feature", args, true);
}
#AfterClass
public static void delete_investigation() {
Map<String, Object> args = new HashMap();
args.put("payload", result);
Runner.runFeature(CommonFeatures.class, "delete-job.feature", args, true);
}
}
To run these tests via command line using "mvn test" command, i have done following changes in pom.xml.
`<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<includes>
<include>**/*Runner.java</include>
</includes>
</configuration>
</plugin>`
With this solution I able to run my tests in IDE by executing the runner directly or by command line. However, I have not found a way to run all of my tests by following the karate suggested approach where I have a *Test.java file at test suite level and I use default maven configuration with "mvn test". The features fails to run as the .feature file is called before the Runner file is executed which has method to create test data for tests.
Maybe someone can suggest what else, I could do to use Karate approach of running *Test.java file instead of each *Runner.java file.

Create a PDF file using PDFTron and then rename or delete it

I am trying to create PDF file using PDFTron in application which runs in the UWP environment. I am able to create a file successfully. Depending on user input that newly created file might need to be renamed or completely deleted from the system. Although when I try to access the file that was just created the system throws the following exception:
Exception thrown: 'System.IO.IOException' in System.IO.FileSystem.dll The process cannot access the file (filename) because it is being used by another process.
The following part show what is used for the file to be created:
await sdfDoc.SaveAsync(filePath, SDFDocSaveOptions.e_linearized, "%PDF-1.5");
sdfDoc.Dispose();
And this is my delete implementation:
var filedelete = Task.Run(() => File.Delete(filePath));
The creation of the file is running on a seperate Task and the deletion takes place upon a button press.
I understand the nature of the exception, although I was wondering if the resources of the file are returned to the system from PDFTron after the creation of the file?
Any help or direction would be much appreciated.
Thank you.
PDFNet uses reference counting internally to know when to release the filesystem handles and memory.
For example, the following would trigger the issue where the file is still locked.
PDFDoc doc = new PDFDoc(input_filename);
doc.InitSecurityHandler();
SDFDoc sdfdoc = doc.GetSDFDoc();
await sdfdoc.SaveAsync(output_file_path, SDFDocSaveOptions.e_linearized, "%PDF-1.5");
sdfdoc.Dispose();
await Task.Run(() => File.Delete(output_file_path)); // fails, as PDFDoc still has reference.
But this would work as expected.
using(PDFDoc doc = new PDFDoc(input_filename))
{
doc.InitSecurityHandler();
SDFDoc sdfdoc = doc.GetSDFDoc();
await sdfdoc.SaveAsync(output_file_path, SDFDocSaveOptions.e_linearized, "%PDF-1.5");
sdfdoc.Dispose();
}
await Task.Run(() => File.Delete(output_file_path)); // works
Note the using statement for the PDFDoc instance, and the manual dispose of the SDFDoc instance, though you could use a using statement on that also.

How do I launch a certain project using SWTBot

Not every plugin can be tested without project. For example, I want to test CDT-Plug-in, therefore I need to import a C-project. But there is no such point in Run Configuration and when I'm trying to record importing actions via SWT Plug-in Test recorder SWTBot can't replay them afterwards. Google is silent on this topic. How do I do that?
A nice way to do this is using the eclipse recource model
Have a look at the package
org.eclipse.core.resources
Here is a method, that creates a new project in the workspace
private IProject getNewOpenProject(IWorkspace wks, String name)
throws CoreException {
System.out.print("Creating project " + name + "...");
IProjectDescription prj1ProjectDescription = wks
.newProjectDescription(name);
IProject prj = wks.getRoot().getProject(name);
prj.create(prj1ProjectDescription, null);
prj.open(null);
System.out.println(" [OK]");
return prj;
}
This method will import your content into the eclipse project
private void importDirIntoProject(File srcPath, IProject prj,
IOverwriteQuery overwriteQuery) throws InvocationTargetException,
InterruptedException {
ImportOperation op = new ImportOperation(prj.getFullPath(), srcPath,
FileSystemStructureProvider.INSTANCE, overwriteQuery);
op.setCreateContainerStructure(false);
op.run(new NullProgressMonitor());
}
This approach uses native eclipse mechanisms. I think this is better than using the inconvenient way over SWTBot.
It's the responsibility of your test to create the necessary resources in its setup method, and clean them after. It's not something to configure in the Run Configuration, but to code in your test.
You can either use SWTBot to import/create a C project, or use the project APIs suggested by beanie.

FileStream security error

I am developing multithreaded application in Adobe Air 3.6 with Flex 4.6. I am using FileStream class inside the Worker thread which is created in separate SWF file. When I declare the variable like this:
var FS:FileStream = new FileStream();
It throws the following error without any further detail:
SecurityError: file
Using FileStream class on Main thread works fine. Is there any workaround to this?
Thanks.
Set createWorker attribute 'giveAppPrivileges' = true.
_worker = WorkerDomain.current.createWorker(Workers.myWorker,**true**);

Scoping in embedded groovy scripts

In my app, I use Groovy as a scripting language. To make things easier for my customers, I have a global scope where I define helper classes and constants.
Currently, I need to run the script (which builds the global scope) every time a user script is executed:
context = setupGroovy();
runScript( context, "global.groovy" ); // Can I avoid doing this step every time?
runScript( context, "user.groovy" );
Is there a way to setup this global scope once and just tell the embedded script interpreter: "Look here if you can't find a variable"? That way, I could run the global script once.
Note: Security is not an issue here but if you know a way to make sure the user can't modify the global scope, that's an additional plus.
Shamelessly stolen from groovy.codehaus :
The most complete solution for people
who want to embed groovy scripts into
their servers and have them reloaded
on modification is the
GroovyScriptEngine. You initialize the
GroovyScriptEngine with a set of
CLASSPATH like roots that can be URLs
or directory names. You can then
execute any Groovy script within those
roots. The GSE will also track
dependencies between scripts so that
if any dependent script is modified
the whole tree will be recompiled and
reloaded.
Additionally, each time you run a
script you can pass in a Binding that
contains properties that the script
can access. Any properties set in the
script will also be available in that
binding after the script has run. Here
is a simple example:
/my/groovy/script/path/hello.groovy:
output = "Hello, ${input}!"
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
String[] roots = new String[] { "/my/groovy/script/path" };
GroovyScriptEngine gse = new GroovyScriptEngine(roots);
Binding binding = new Binding();
binding.setVariable("input", "world");
gse.run("hello.groovy", binding);
System.out.println(binding.getVariable("output"));
This will print "Hello, world!".
Found: here
Would something like that work for you?
A simple solution is to use the code from groovy.lang.GroovyShell: You can precompile the script like so:
GroovyCodeSource gcs = AccessController.doPrivileged( new PrivilegedAction<GroovyCodeSource>() {
public GroovyCodeSource run() {
return new GroovyCodeSource( scriptCode, fileName, GroovyShell.DEFAULT_CODE_BASE );
}
} );
GroovyClassLoader loader = AccessController.doPrivileged( new PrivilegedAction<GroovyClassLoader>() {
public GroovyClassLoader run() {
return new GroovyClassLoader( parentLoader, CompilerConfiguration.DEFAULT );
}
} );
Class<?> scriptClass = loader.parseClass( gcs, false );
That's was the expensive part. Now use InvokeHelper to bind the compiled code to a context (with global variables) and run it:
Binding context = new javax.script.Binding();
Script script = InvokerHelper.createScript(scriptClass, context);
script.run();