I want to trigger the execution of some commands from a python module from Java. My script is executed without error messages, but it has no effect. The code I'm using from Java is as follows:
ProcessBuilder pb = new ProcessBuilder("python", "nerDemoTP/python/spacy_test.py");
pb.redirectOutput(Redirect.INHERIT);
Process p;
try {
p = pb.start();
p.waitFor();
} catch (IOException e1) {
... }
It works if my .py file contains only print('hello world'), then I see it in the Eclipse console. But what my python script is supposed to do:
from SpacyNER import SpacyNERExtractor
ner_extractor = SpacyNERExtractor('medium', 'sentences_nyt_200.txt')
annotated_df, entities_dict = ner_extractor.generate_extractions()
ner_extractor.store_predictions('test.csv')
print('spacy extractions done!')
And my SpacyNER module is defined as follows:
import pandas as pd
import numpy as np
import spacy
import en_core_web_md
import en_core_web_lg
import operator
import time
import re
class SpacyNERExtractor:
def __init__(self, model, text_file):
if model == 'medium':
self.spacy_model = en_core_web_md.load()
else:
self.spacy_model = en_core_web_lg.load()
self.sent_df = pd.read_csv(text_file, sep='\n', header=None, error_bad_lines = False)
self.sent_df.columns=['sentence']
def set_new_sent_df(self, df_new):
self.sent_df = df_new
def store_predictions(self, file_name):
self.df_predictions_spacy.to_csv(file_name,sep="#", index=False)
...
It has to do something with the import of the custom module, but I don't know how to deal with this problem. Also when I execute the script from the command line, i.e. python3.6 spacy_test.py, it works.
Any help is appreciated!
Related
How do I call my cucumberTestRunner from another class (cucumberTestMaster) and get it to run? Currently, it just seems to skip the tests. Below is what I have tried. I am limited by JUnit 4.8 for project reasons, and both files are written in Groovy.
//cucumberTestMaster
package cucumber
import cucumber.testRunners.CucumberTestRunner
import org.junit.runner.JUnitCore
import org.junit.runner.Result
class CucumberTestMaster {
try {
Class runner = CucumberTestRunner as Class
Result result = JUnitCore.runClasses(runner.class)
}
catch (Exception e)
{
println(e)
}
}
//cucumberTestRunner
package cucumber.testRunners
import io.cucumber.junit.Cucumber
import io.cucumber.junit.CucumberOptions
import org.junit.runner.RunWith
#RunWith(Cucumber.class)
#CucumberOptions(
features = "src/main/groovy/cucumber/features/addDeal/",
glue = "cucumber.stepDefinitions",
publish = false,
monochrome = true,
tags = "#Daily",
plugin = ["pretty", "junit:target/JUNITReports/report.xml", "html:target/HTMLReports/report.html",
"json:target/JSONReports/report.json"]
)
class CucumberTestRunner {
}
Thank you in advance for any help.
I have written a java code which can execute the python script. Also, I have the Python script that converts xml-json and vice versa. how to pass the python xml method and python xml path in java code .Can someone help me with the java code to resolve this issue.
Below is the Py script and the java code which I am trying to execute to call the python script and its methods. Please help me with the java code.
Python script:
import json
from json import loads
import xmltodict
from dicttoxml import dicttoxml
def ConvertXMLtoJSON(xmltxt):
my_dict=xmltodict.parse(xmltxt)
json_data=json.dumps(my_dict)
print(json_data)
return json_data
def ConvertJSONtoXML(jsontxt):
json_obj = jsontxt
xml = dicttoxml(loads(json_obj), attr_type=False)
print(xml)
return xml
Java code:
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
interface PyFunction{
String XMLPath= ".xml file path";
public void ConvertXMLtoJSON(String XMLPath);
}
public class Conversion {
public static void main(String[] args) {
PythonInterpreter interpreter = new PythonInterpreter();
try {
interpreter.exec("from PythonScript import ConvertXMLtoJSON");
PyObject ConvertXMLtoJSON = interpreter.get("ConvertXMLtoJSON");
PyFunction function = (PyFunction) ConvertXMLtoJSON.__tojava__(PyFunction.class);
function.ConvertXMLtoJSON("python script path");
} catch (Exception e) {
e.printStackTrace();
e.getMessage();
e.toString();
}
I'm trying to generate and load from CSV filea and problem with CSVPrinter occured. The statement is the following:
Cannot resolve constructor 'CSVPrinter(java.io.BufferedWriter,org.apache.commons.csv.CSVFormat)"
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;
import java.io.BufferedWriter;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(file.getAbsolutePath()));
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT
.withHeader("title", "description", "priority"))
) {
for (int i = 0; i < serializer.toDO.size(); i++){
csvPrinter.printRecord(serializer.toDO.get(i).getTitle(),
serializer.toDO.get(i).getDescription().replace("\n"," "),
serializer.toDO.get(i).getPriority(),
serializer.toDO.get(i).getLocalDate(),
"toDo");
}
Assuming you are using the apache variant, your code worked for me.
I think you need to add some of the details that you assure us you have done. My guess is that you have the wrong library in your project/classpath.
In what environment are you running your code (within the IDE or standalone from the command prompt)?
How did you incorporate the library (download JAR directly from Apache or automatically via a service - e.g. maven)?
Here is my version of the source code:
package csvwriter;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVFormat;
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Main m = new Main();
m.go(args);
}
public void go(String [] args) {
File file = new File (args[0]);
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(file.getAbsolutePath()));
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT
.withHeader("title", "description", "priority"))
) {
System.out.println("Done.");
// for (int i = 0; i < serializer.toDO.size(); i++){
// csvPrinter.printRecord(serializer.toDO.get(i).getTitle(),
// serializer.toDO.get(i).getDescription().replace("\n"," "),
// serializer.toDO.get(i).getPriority(),
// serializer.toDO.get(i).getLocalDate(),
// "toDo");
// }
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Here are my libraries:
I downloaded the library from the apache download center
When I run, I get the following as the output:
run:
Done.
BUILD SUCCESSFUL (total time: 0 seconds)
Repeating this exercise in IntelliJ (Java Project, incorporate apache-commons-csv-1.6) via Maven, produces the same result:
"C:\Program Files\Java\jdk1.8.0_172\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.1\lib\idea_rt.jar=59482:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_172\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\rt.jar;C:\cygwin64\home\gm310509\Projects\Learning\Miscellaneous\CSVPrinter\out\production\CSVPrinter;C:\cygwin64\home\gm310509\Projects\Learning\Miscellaneous\CSVPrinter\lib\commons-csv-1.6.jar" stackoverflow.Main c:\temp\resistor.html
Done.
Process finished with exit code 0
Here is the "add library via maven" dialog:
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
public class TestUnZip {
public static void main(String[] args) throws IOException, InterruptedException{
String destFolder="E:\\TestScript";
/*
* Location where the Nodejs Project is Present
*/
System.out.println(destFolder);
String cmdPrompt="cmd";
String path="/c";
String npmUpdate="npm update";
String npm="npm";
String update="update";
File jsFile=new File(destFolder);
List<String> updateCommand=new ArrayList<String>();
updateCommand.add(cmdPrompt);
updateCommand.add(path);
updateCommand.add(npmUpdate);
runExecution(updateCommand,jsFile);
}
public static void runExecution(List<String> command, File navigatePath) throws IOException, InterruptedException{
System.out.println(command);
ProcessBuilder executeProcess=new ProcessBuilder(command);
executeProcess.directory(navigatePath);
Process resultExecution=executeProcess.start();
BufferedReader br=new BufferedReader(new InputStreamReader(resultExecution.getInputStream()));
StringBuffer sb=new StringBuffer();
String line;
while((line=br.readLine())!=null){
sb.append(line+System.getProperty("line.separator"));
}
br.close();
int resultStatust=resultExecution.waitFor();
System.out.println("Result of Execution"+(resultStatust==0?"\tSuccess":"\tFailure"));
}
}
The Above Program works fine, but this program is depend on Windows Machine, I want to run the same program in other Machine as well.
1) NPM is a Command comes as a bundle of NodeJS. (I run NodeJS as a service, I have defined the Environment Variable, so I can run npm update command from any folder)
2) I can't find a work around to run the npm update command without using the "cmd", "/c". If I do I get following error
Exception in thread "main" java.io.IOException: Cannot run program "npm update" (in directory "E:\TestScript"): CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
3) Do we have option of Running the npm update command as a parameter of Node.exe. If so can anyone provide me the proper work around.
4) Same as I like, I use mocha framework to run the test script and result generates the .xml file.
5) I want mocha command also being invoked using process builder.
The problem is that ProcessBuilder does not respect the PATHEXT variable on Windows.
It's true there is no npm binary on Windows, there's a npm.cmd. My best solution is to check the platform. Something like this:
static boolean isWindows() {
return System.getProperty("os.name").toLowerCase().contains("win");
}
static String npm = isWindows() ? "npm.cmd" : "npm";
static void run() {
Process process = new ProcessBuilder(npm, "update")
.directory(navigatePath)
.start()
}
In Unix or Linux os , the PathBuilder takes the default environment path , so we have to change the environment path and run the npm command through the bash.
import java.io.File;
import java.util.Map;
public class CommandExecutor {
public void exceuteCommand(String commandString,String
directoryToExecuteCommand) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(new String{"bash", "-c",commandString});
Map<String, String> env = processBuilder.environment();
processBuilder.directory(new File(directoryToExecuteCommand));
String envPath="/home/admin123/.nvm/versions/node/v10.15.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin";
env.put("PATH",envPath);
processBuilder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
CommandExecutor commandExecutor=new CommandExecutor();
commandExecutor.exceuteCommand("npm install", "/home/admin123/Desktop");
}
}
So I am trying to write an .sh file that will be executable, this is how I'm currently writing it:
Writer output = null;
try {
output = new BufferedWriter(new FileWriter(file2));
output.write(shellScriptContent);
output.close();
} catch (IOException ex) {
Logger.getLogger(PunchGUI.class.getName()).log(Level.SEVERE, null, ex);
}
So that writes the file just fine, but it is not executable. Is there a way to change the executable status when I write it?
Edit: To further clarify, I am trying to make it execute by default, so that for instance, if you double clicked the generated file, it would automatically execute.
You can call File.setExecutable() to set the owner's executable bit for the file, which might be sufficient for your case. Or you can just chmod it yourself with a system call with Process.
Alas, full-powered programmatic alteration of file permissions isn't available until Java 7. It'll be part of the New IO feature set, which you can read more about here.
You'd need to chmod it, and you can probably do it by exec'ing a system command like such:
Really all you'd need is to fire off something like this:
Runtime.getRuntime().exec("chmod u+x "+FILENAME);
But if you want to keep track of it more explicitly can capture stdin / stderr then something more like:
Process p = Runtime.getRuntime().exec("chmod u+x "+FILENAME);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
Which I got from here:
http://www.devdaily.com/java/edu/pj/pj010016/pj010016.shtml
Update:
Test program:
package junk;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class Main{
private String scriptContent = '#!/bin/bash \n echo "yeah toast!" > /tmp/toast.txt';
public void doIt(){
try{
Writer output = new BufferedWriter(new FileWriter("/tmp/toast.sh"));
output.write(scriptContent);
output.close();
Runtime.getRuntime().exec("chmod u+x /tmp/toast.sh");
}catch (IOException ex){}
}
public static void main(String[] args){
Main m = new Main();
m.doIt();
}
}
On linux if you open up a file browser and double click on /tmp/toast.sh and choose to run it, it should generate a text file /tmp/toast.txt with the words 'yeah toast'. I assume Mac would do the same since it's BSD under the hood.
In Java 7 you can call Files.setPosixFilePermissions. Here is an example:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;
class FilePermissionExample {
public static void main(String[] args) throws IOException {
final Path filepath = Paths.get("path", "to", "file.txt");
final Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(filepath);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
Files.setPosixFilePermissions(filepath, permissions);
}
}
On Mac OS X, besides chmod +x, you have to give a .command extension to your shell script if you want to launch it with a double-click.
This answer I wrote for the question how do I programmatically change file permissions shows a chmod example via a native call using jna, which should work on Mac OS X.