ProcessBuilder&Runtime exec could not find or load main class in Spring Project - spring-mvc

I want to compile a java file and exec its class in another class ( ← This class is a #service of a Spring MVC project ).
The service code is:
#Service
public class MRServiceImp implements MRService {
#Override
public String submitMR(int id, String fd) {
try {
// compile the java file
String[] cmd = {"javac", "P" + id + ".java"};
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(fd));
Process p = pb.start();
// exec the class file
String[] execmd = {"java", "P" + pz_id};
ProcessBuilder epb = new ProcessBuilder(execmd);
epb.directory(new File(fd));
p = epb.start();
// get normal output
BufferedReader pin = new BufferedReader(new InputStreamReader(p.getInputStream()));
String ptmp = pin.readLine();
while (ptmp != null) {
pout = pout == null ? ptmp + '\n' : pout + ptmp + '\n';
ptmp = pin.readLine();
}
// get error output
pin = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String wout = null;
ptmp = pin.readLine();
while (ptmp != null) {
wout = wout == null ? ptmp + '\n' : wout + ptmp + '\n';
ptmp = pin.readLine();
}
// print output
System.out.println(pout);
System.out.println(wout);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null; // for test
}
When this Service is invoked, I always get a Error: Could not find or load main class: P[id]
I cd theFilePath, the P[id].class file is existing.
And I can run java P[id] successfully in theFilePath.
And I try to replace ProcessBuilder with Runtime, like:
#Service
public class MRServiceImp implements MRService {
#Override
public String submitMR(int id, String fd) {
try {
// compile the java file
String[] cmd = {"javac", "P" + id + ".java"};
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(fd));
Process p = pb.start();
// exec the class file
String execmd = "java", fd + "/P" + pz_id;
p = Runtime.getRuntime().exec(execmd);
// get normal output
BufferedReader pin = new BufferedReader(new InputStreamReader(p.getInputStream()));
String ptmp = pin.readLine();
while (ptmp != null) {
pout = pout == null ? ptmp + '\n' : pout + ptmp + '\n';
ptmp = pin.readLine();
}
// get error output
pin = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String wout = null;
ptmp = pin.readLine();
while (ptmp != null) {
wout = wout == null ? ptmp + '\n' : wout + ptmp + '\n';
ptmp = pin.readLine();
}
// print output
System.out.println(pout);
System.out.println(wout);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null; // for test
}
I get the same Error again T^T
IDE is sts-bundle, server is tomcat8

I know what is wrong here.
pb.start(); does not mean the command of pb will be executed immediately.
So if I set pb of command javac hello.java; set epb of command java hello
And I call pb.start(); epb.start(); continuously, I will get an Error: could not find or load main class: hello, because when I exec epb.start(); The former command(pb.start) may have not been executed!
I got 2 solution:
First: set a finally field and exec epb.start() in this field, like:
#Service
public class MRServiceImp implements MRService {
#Override
public String submitMR(int id, String fd) {
try {
// compile the java file
String[] cmd = {"javac", "P" + id + ".java"};
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(fd));
Process p = pb.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// exec the class file
String[] execmd = {"java", "P" + pz_id};
ProcessBuilder epb = new ProcessBuilder(execmd);
epb.directory(new File(fd));
Process p = epb.start();
}
return null; // for test
}
Second: a trick of bash
#Service
public class MRServiceImp implements MRService {
#Override
public String submitMR(int id, String fd) {
try {
// compile & exec the java file
String[] cmd = {"/bin/bash"};
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(fd));
Process p = pb.start();
BufferedWriter pbw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
pbw.write("javac *.java;java P" + pz_id+";exit;");
pbw.newLine();
pbw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null; // for test
}
I use the second one.

Related

Problem to execute https connection from a servlet: http 404 error occours

From my Tomcat's servlet I execute an https connection to an external servlet.
This is the code:
HttpsURLConnection hpcon = null;
try {
URL url = new URL(surl);
hpcon = (HttpsURLConnection) url.openConnection();
hpcon.setRequestMethod("POST");
hpcon.setDoInput(true);
hpcon.setDoOutput(true);
hpcon.setUseCaches(false);
hpcon.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
OutputStreamWriter wr = new OutputStreamWriter(hpcon.getOutputStream());
String params = "user=" + URLEncoder.encode(user, "UTF-8");
params += "&psswd=" + URLEncoder.encode(pssw, "UTF-8");
params += "&metodo=" + URLEncoder.encode(metodo, "UTF-8");
wr.write(params);
wr.flush();
wr.close();
hpcon.connect();
int respCode = hpcon.getResponseCode();
if (respCode == 200) {
BufferedReader br = new BufferedReader(new InputStreamReader(hpcon.getInputStream()));
String response = "";
String output;
while ((output = br.readLine()) != null) {
response += output;
}
if (response.indexOf("-") > 0) {
response = "-12";
System.out.println("ret = -12 - response = " + response);
}
br.close();
} else {
ret = "-11";
System.out.println("ret = -11 - respCode = " + respCode);
}
} catch (Exception e) {
e.printStackTrace();
ret = "-10";
System.out.println("ret = -10");
} finally {
if (hpcon != null) {
hpcon.disconnect();
}
}
Where surl is the full url of a servlet present in a different domain and the three parameters are read from a db table (the third really is fixed and is the operation that is make by the external servlet).
The result is:
ret = -11 - respCode = 404
Before make the connection I turn off the certificate's verify using the above code:
try {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception e) {
e.printStackTrace();
}
If I execute the same servlet manually from a browser with parameters in get mode all run correctly.
I tried to execute it on my code using the get mode and passing the three parameters in query string, but the result is the same.
How can I do to resolve the problem?

Fixing a Zip Path Traversal Vulnerability in Android app in Google Play Store

The question has been asked (and answered) but I have not been able to get it to work in my code.
This is the support document:
https://support.google.com/faqs/answer/9294009
I have tried to use the answer from here:
Fixing a Zip Path Traversal Vulnerability In Android
My original code:
public void copyFiles() {
try {
String roms_dir = mm.getMainHelper().getInstallationDIR();
File fm = new File(roms_dir + File.separator + "saves/"
+ "dont-delete-" + getVersion() + ".bin");
if (fm.exists())
return;
fm.mkdirs();
fm.createNewFile();
// Create a ZipInputStream to read the zip file
BufferedOutputStream dest = null;
InputStream fis = mm.getResources().openRawResource(R.raw.files);
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(fis));
// Loop over all of the entries in the zip file
int count;
byte data[] = new byte[BUFFER_SIZE];
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (!entry.isDirectory()) {
String destination = roms_dir;
String destFN = destination + File.separator
+ entry.getName();
// Write the file to the file system
FileOutputStream fos = new FileOutputStream(destFN);
dest = new BufferedOutputStream(fos, BUFFER_SIZE);
while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
} else {
File f = new File(roms_dir + File.separator
+ entry.getName());
f.mkdirs();
}
}
zis.close();
String dir = this.getInstallationDIR();
if(!dir.endsWith("/"))dir+="/";
String rompath = mm.getPrefsHelper().getROMsDIR() != null && mm.getPrefsHelper().getROMsDIR()!="" ? mm
.getPrefsHelper().getROMsDIR() : dir + "roms";
mm.getDialogHelper()
.setInfoMsg(
"Created or updated: '"
+ dir
+ "' to store save states, cfg files and MAME assets.\n\nBeware, copy or move your zipped ROMs under '"
+ rompath
+ "' directory!\n\nMAME4droid 0.139 uses only 0.139 MAME romset.");
mm.showDialog(DialogHelper.DIALOG_INFO);
} catch (Exception e) {
e.printStackTrace();
}
}
I have tried this:
public void copyFiles() {
try {
String roms_dir = mm.getMainHelper().getInstallationDIR();
File fm = new File(roms_dir + File.separator + "saves/"
+ "dont-delete-" + getVersion() + ".bin");
if (fm.exists())
return;
fm.mkdirs();
fm.createNewFile();
// Create a ZipInputStream to read the zip file
BufferedOutputStream dest = null;
InputStream fis = mm.getResources().openRawResource(R.raw.files);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
// Loop over all of the entries in the zip file
int count;
byte data[] = new byte[BUFFER_SIZE];
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
// Create an outputFile object and check that the path is safe with ensureZipPathSafety
//*
String outputDir = "";
File outputFile = new File(outputDir, entry.getName());
String outputFileName = outputFile.getCanonicalPath();
System.out.println(outputFileName);
try {
ensureZipPathSafety(outputFile, outputDir);
} catch (Exception e) {
e.printStackTrace();
return;
}
//*/
if (!entry.isDirectory()) {
System.out.println("We get past !entry.isDirectory check");
String destination = roms_dir;
String destFN = destination + File.separator
+ entry.getName();
// Write the file to the file system
FileOutputStream fos = new FileOutputStream(destFN);
dest = new BufferedOutputStream(fos, BUFFER_SIZE);
while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
} else {
File f = new File(roms_dir + File.separator
+ entry.getName());
f.mkdirs();
}
}
zis.close();
String dir = this.getInstallationDIR();
if(!dir.endsWith("/"))dir+="/";
String rompath = mm.getPrefsHelper().getROMsDIR() != null && mm.getPrefsHelper().getROMsDIR()!="" ? mm
.getPrefsHelper().getROMsDIR() : dir + "roms";
mm.getDialogHelper()
.setInfoMsg(
"Created or updated: '"
+ dir
+ "' to store save states, cfg files and MAME assets.\n\nBeware, copy or move your zipped ROMs under '"
+ rompath
+ "' directory!\n\nMAME4droid 0.139 uses only 0.139 MAME romset.");
mm.showDialog(DialogHelper.DIALOG_INFO);
} catch (Exception e) {
e.printStackTrace();
}
}
private void ensureZipPathSafety(final File outputFile, final String destDirectory) throws Exception {
String destDirCanonicalPath = (new File(destDirectory)).getCanonicalPath();
String outputFilecanonicalPath = outputFile.getCanonicalPath();
String outputFileCanonicalPath = "";
if (!outputFileCanonicalPath.startsWith(destDirCanonicalPath)) {
Object canonicalPath = null;
throw new Exception(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath));
}
}

How can i append a pdf into another? Alfresco

How can i append a pdf into another?
I tried using this code, but I am getting java.lang.NullPointerException when i try to getContentInputStream.
what am I doing wrong? How can I attach one pdf to another?
PDDocument pdfTarget = null;
InputStream is = null;
InputStream tis = null;
for (ChildAssociationRef file: quotationsFiles) {
try {
NodeRef toAppend = file.getChildRef(); //workspace://SpacesStore/11bce382-45bf-4c67-95bc-a65361b323ef
ContentReader append = getReader(toAppend);
is = append.getContentInputStream(); // Here iam getting java.lang.NullPointerException
NodeRef targetNodeRef = reportFile.getNodeRef();
ContentReader targetReader = getReader(targetNodeRef);
tis = targetReader.getContentInputStream();
String fileName = String.valueOf(serviceRegistry.getNodeService().getProperty(targetNodeRef, ContentModel.PROP_NAME));
// stream the document in
pdf = PDDocument.load(is);
pdfTarget = PDDocument.load(tis);
// Append the PDFs
PDFMergerUtility merger = new PDFMergerUtility();
merger.appendDocument(pdfTarget, pdf);
merger.setDestinationFileName(fileName);
merger.mergeDocuments();
} catch (Exception e) {
//throw new AlfrescoRuntimeException("IOException", e);
ColorLogUtil.debug(LOGGER, "IOException Error caused by :" + e);
}
}
private ContentReader getReader(NodeRef nodeRef) {
if (serviceRegistry.getNodeService().exists(nodeRef) == false) {
throw new AlfrescoRuntimeException("NodeRef: " + nodeRef + " does not exist");
}
QName typeQName = serviceRegistry.getNodeService().getType(nodeRef);
if (serviceRegistry.getDictionaryService().isSubClass(typeQName, ContentModel.TYPE_CONTENT) == false) {
throw new AlfrescoRuntimeException("The selected node is not a content node");
}
ContentReader contentReader = serviceRegistry.getContentService().getReader(nodeRef, ContentModel.PROP_CONTENT);
if (contentReader == null) {
throw new AlfrescoRuntimeException("The content reader for NodeRef: " + nodeRef + "is null");
}
return contentReader;
}
See if this code works for you:
public NodeRef mergePdfs(List<NodeRef> nodeRefList, String fileName,NodeRef destinationNode)
throws FileNotFoundException,FileExistsException,Exception {
InputStream originalInputStream = null;
ContentReader reader = null;
NodeRef newDocNoderef = null;
PDFMergerUtility PDFmerger = new PDFMergerUtility();
ByteArrayOutputStream outputstream = new ByteArrayOutputStream();
try {
LOGGER.debug("Merging of Doc Started");
for (NodeRef node : nodeRefList) {
reader = contentService.getReader(node, ContentModel.PROP_CONTENT);
originalInputStream = reader.getContentInputStream();
PDFmerger.addSource(originalInputStream);
}
PDFmerger.setDestinationStream(outputstream);
PDFmerger.mergeDocuments();
if(originalInputStream!=null) {
originalInputStream.close();
}
newDocNoderef = writeContentToAlfresco(outputstream, nodeRefList, fileName,destinationNode);
LOGGER.debug("Documents are merged and new pdf is created at "+newDocNoderef);
} finally {
if(outputstream!=null)
outputstream.close();
}
return newDocNoderef;
}
public NodeRef writeContentToAlfresco(ByteArrayOutputStream outputstream, List<NodeRef> childRefList,
String fileName,NodeRef destinationNode) throws FileExistsException,IOException,Exception {
NodeRef pdf = null;
Map<QName, Serializable> props = new HashMap<>();
Map<Date, NodeRef> dateMap = new HashMap<Date, NodeRef>();
NodeRef parentNodeRef=null;
try {
LOGGER.debug("Upload to Alfresco Started");
for(NodeRef noderef : childRefList) {
Date date = (Date) nodeService.getProperty(noderef, ContentModel.PROP_MODIFIED);
dateMap.put(date, noderef);
}
Map<Date, NodeRef> m1 = new TreeMap<Date, NodeRef>(dateMap);
Map.Entry<Date, NodeRef> entry = m1.entrySet().iterator().next();
NodeRef finalnodeRef = entry.getValue();
if(destinationNode!=null) {
parentNodeRef = destinationNode;
}else {
parentNodeRef = nodeService.getPrimaryParent(finalnodeRef).getParentRef();
}
QName[] myModelProps = CommonConstants.myModelProps;
for (QName myModelProp : myModelProps) {
Serializable object = nodeService.getProperty(finalnodeRef, myModelProp);
props.put(myModelProp, object);
}
FileInfo pdfInfo = fileFolderService.create(parentNodeRef, fileName + ".pdf",
MyModel.TYPE_CUSTOM_MYMODEL_TYPE);
pdf = pdfInfo.getNodeRef();
nodeService.setProperties(pdf,props);
nodeService.setProperty(pdf, ContentModel.PROP_TITLE,
nodeService.getProperty(finalnodeRef, ContentModel.PROP_TITLE));
nodeService.setProperty(pdf, ContentModel.PROP_DESCRIPTION,
nodeService.getProperty(finalnodeRef, ContentModel.PROP_DESCRIPTION));
nodeService.setProperty(pdf,ContentModel.PROP_NAME,fileName + ".pdf");
ContentWriter writer = contentService.getWriter(pdf, ContentModel.PROP_CONTENT, true);
writer.setMimetype(MimetypeMap.MIMETYPE_PDF);
writer.setEncoding("UTF-8");
writer.putContent(new ByteArrayInputStream(outputstream.toByteArray()));
LOGGER.debug("Upload to Alfresco Ended");
} catch(FileExistsException fee) {
ExceptionUtils.printRootCauseStackTrace(fee);
throw new FileExistsException(parentNodeRef, fileName);
}
catch (Exception e) {
ExceptionUtils.printRootCauseStackTrace(e);
throw new Exception(e);
} finally {
if (outputstream != null)
outputstream.close();
}
return pdf;
}
This actually seems like one of the features we support in alfresco-pdf-toolkit out of the box. You could either use that addon, or get some inspiration from the code backing it.

JavaFX TextArea appendText works in initialize but not elsewhere

Simple enough problem but it's been driving me crazy.
In my program I have a TextArea, defined as:
<TextArea fx:id="output" editable="false" prefHeight="300.0" prefWidth="200.0" text="Output" GridPane.columnSpan="2" GridPane.rowIndex="4" />
#FXML private TextArea output;
...
public void initialize(URL url, ResourceBundle rb) {
output.setText("Test"); //Test appears correctly in output
...
}
#FXML
public void download() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); //Prints as expected
output.appendText(line + "\n"); //Has no effect
}
} catch (IOException e) {
e.printStackTrace();
}
}
Any ideas on how to get the text to appear would be great, I've done this before on different programs, just for some reason, this time it's being cantankerous
EDIT: Upon further tinkering, it actually will print out the results, but only after the Process ends and it exits the loop.
The text shown in the UI changes on a layout pulse. Layout pulses are done on the JavaFX application thread. Event handlers, like your download method run on the same thread effectively preventing it from doing any layouting or processing and other events until it completes. This is why you shouldn't block this thread with longrunning tasks, but execute them on a different thread.
Since updates to the UI should be done from the application thread, use Platform.runLater to append the text:
#FXML
public void download() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
Runnable r = () -> {
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); //Prints as expected
final String printText = line + "\n";
// append the line on the application thread
Platform.runLater(() -> output.appendText(printText));
}
} catch (IOException e) {
e.printStackTrace();
}
};
// run task on different thread
Thread t = new Thread(r);
t.start();
}
The problem is that you're doing this in the main thread. So stage can not be updated, until the cycle is finished. Try it in new thread:
#FXML
public void download() {
Task<Void> task = new Task<Void>() {
#Override
protected Void call() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); // Prints as expected
output.appendText(line + "\n"); // Has no effect
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
new Thread(task).start();
}

Handle file name duplication when creating files in alfresco

I have a Java-backed webscript in repo tier that creates files (with given name) in a given folder in Alfresco.
To handle the file name duplication issue I wrote this code:
NodeRef node = null;
try {
node = createNode(fullName, folderNodeRefId);
} catch (DuplicateChildNodeNameException e) {
System.out.println("Catched");
boolean done = false;
for (int i = 1; !done; i++) {
String newName = filename + "_" + i + "." + fileFormat;
System.out.println("Duplicate Name. Trying: " + newName);
try {
node = createNode(newName, folderNodeRefId);
done = true;
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
System.out.println("Done");
ContentWriter writer = serviceRegistry.getContentService().getWriter(node, ContentModel.PROP_CONTENT, true);
writer.setMimetype(getFileFormatMimetype(fileFormat));
writer.putContent(inputStream);
writer.guessEncoding();
and
private NodeRef createNode(String filename, String folderNodeRefId)
throws InvalidNodeRefException, InvalidTypeException, InvalidQNameException {
System.out.println("In " + filename);
NodeRef folderNodeRef = new NodeRef(folderNodeRefId);
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NAME, filename);
return serviceRegistry.getNodeService()
.createNode(folderNodeRef, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, filename), ContentModel.TYPE_CONTENT,
props)
.getChildRef();
}
The codes work very fine if there is no file name duplication (a new name). But it does nothing when there is a duplication, although it executes without any errors! When I test it it doesn't throw any exceptions but no file is created either!
Any hints about the cause of that?
Thanks,
I tested this code , It's working fine
#Test
public void createNode() {
AuthenticationUtil.setFullyAuthenticatedUser(ADMIN_USER_NAME);
NodeRef node = null;
String fileFormat = "txt";
String filename = "test";
NodeRef folderNodeRef = getCompanyHome();
//Create first node
node = createNode(filename, folderNodeRef);
try {
node = createNode(filename, folderNodeRef);
} catch (DuplicateChildNodeNameException e) {
System.out.println("Catched");
boolean done = false;
for (int i = 1; !done; i++) {
String newName = filename + "_" + i + "." + fileFormat;
System.out.println("Duplicate Name. Trying: " + newName);
try {
node = createNode(newName, folderNodeRef);
done = true;
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
System.out.println("Done");
}
private NodeRef getCompanyHome() {
return nodeLocatorService.getNode("companyhome", null, null);
}
private NodeRef createNode(String filename, NodeRef folderNodeRef) throws InvalidNodeRefException, InvalidTypeException, InvalidQNameException {
System.out.println("In " + filename);
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NAME, filename);
return serviceRegistry.getNodeService().createNode(folderNodeRef, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, filename), ContentModel.TYPE_CONTENT,props).getChildRef();
}

Resources