I m passing multiple tab delim files into R via Java.The R programm merges those tab delim files as single file and sends back to java and it is captured in the variable "name".Now I want to rename and save that file stored in "name" as tab delim using save dialog box in windows.Any help highly appreciated.Here is the java code:
import org.rosuda.REngine.*;
public class rjava {
// Before this run Rserve() command in R
public String ana(String filenames)
{
String name = "";
try{
System.out.println("INFO: Trying to connect to R ");
RConnection c = new RConnection();
System.out.println("INFO: Connected to R");
System.out.println("INFO: The Server version is "+ c.getServerVersion());
// c.voidEval("source('D:/combine/combining_files.r')");
c.voidEval("source('D:/combine/merge.r')");
c.assign("file",filenames);
// name = (c.eval("fn(file)").asString());
name = (c.eval("combine (file)").asString());
c.close();
}
catch(Exception e)
{
System.out.println("ERROR: In Connection to R");
System.out.println("The Exception is "+ e.getMessage());
e.printStackTrace();
}
return name;
}
}
I find passing complex objects between R and Java to be a pain the ass. I would not pass the full data, but rather would pass only file names as a string. Either have Java tell R to write out the new file (my pref) or have Java read in the file and then write out with a new name.
Can you modify the R program, so that it outputs files in the same path with a given file name, such as [path]/filename.out?
Otherwise, you can modify the execte string so that the R program outputs in a given location.
See http://cran.r-project.org/doc/manuals/R-intro.html#Invoking-R-from-the-command-line
When working at a command line on UNIX or Windows, the command ‘R’ can be used both for starting the main R program in the form R [options] [<infile] [>outfile]
-- EDIT
I just saw that you are using an RConnection. According to the R docs, you can define where to pipe stdout
The function sink, sink("record.lis") will divert all subsequent output from the console to an external file, record.lis.
Related
I wrote a Java program that creates an Excel Workbook with at least 4 sheets & loaded into it some vb modules (by loading a template.xlsm with vb modules) Now I want to transform this Excel workbook into a PDF so I have this code in Excel macro VBA
Dim saveLocation As String
saveLocation = Application.ThisWorkbook.path
Dim ws As Worksheet
For Each ws In Application.ThisWorkbook.Worksheets
With ws.PageSetup
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = False
.Orientation = xlLandscape
.CenterVertically = True
.CenterHorizontally = True
.PaperSize = xlPaperTabloid
End With
Next
ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=saveLocation
End Sub
I executed it from Excel VBA and its working fine
However, what I want is to run it from Java directly after it's been created
So what I did after writing the Excel Workbook (in Java) is the following
I wrote from Java into a text file having a VBS extension (module.vbs) the following code
Sub ExcelMacro()
Dim objExcel
Dim objWorkbook
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("PATH\Cost Sheet_233.xlsm")
objExcel.Run "'Cost Sheet_233.xlsm'!Module3.SaveActiveSheetsAsPDF"
objWorkbook.Save
objWorkbook.Close
objExcel.Quit
End Sub
then I executed the following command
try {
Runtime.getRuntime().exec( new String[] { "C:\\Windows\\System32\\wscript.exe", filePath + "\\module.vbs"} );
}
catch (Exception ex)
{
ex.printStackTrace();
}
The output is/should be a PDF file having all Excel sheets
Again, when I run the code from Excel VBA, it works fine. Both the one in the module.vbs and the macro work fine and generate the PDF File, but the Java exec statement isn't
Of course, the paths are right too 100% (wscript.exe exists)
I also tried cscript.exe but didn't work
What could the problem be or did I miss something?
I figured it out yesterday after asking the question.
I tried other ways in writing the .vbs file and the following seemed to work when I call it from Java
Set objShell = CreateObject("WScript.Shell")
Dim cur
cur="Path"
WScript.Echo cur
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Dim xlsFile
xlsFile=cur & "\Cost Sheet_274.xlsm"
Set xlApp=CreateObject("Excel.Application")
Set xlBook =xlApp.Workbooks.Open(xlsFile)
xlApp.Run "SaveActiveSheetsAsPDF"
xlBook.Save
xlApp.Quit
End Sub
and this the Java code that runs the .vbs file
try {
Runtime.getRuntime().exec(new String[] { "C:\\Windows\\System32\\wscript.exe", filePath + "\\module.vbs" });
} catch (Exception ex) {
ex.printStackTrace();
}
Hello working on a small program that just needs to run a python script I have. This python script will play a given .wav file, and draw a shape on the turtle screen. As such, I'm not looking for an output to be returned to java. Here is my java code:
public class Driver {
public static void main(String[] args){
try {
Process p = Runtime.getRuntime().exec("python " +
" D:/Coding Files/Python/MusicColors.py" +" teenagers.wav");
}
catch (Exception e){
System.out.println(e);
}
}
}
The exception I get is:
java.io.IOException: Cannot run program "python":
CreateProcess error=2, The system cannot find the file specified
I probably am making a very stupid mistake as I have limited knowledge in the subject of processes and such. I added python to my system path, so whenever I put "python" into command line, it returns with
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
And makes it the python shell.
Here is the exact line I added to my environment path:
C:\Users\Joe\AppData\Local\Programs\Python\Python35-32
If anyone can figure out where I went wrong I'd really appreciate it!
The $PATH variable you've set is not inherited in Java's execution context. Try passing the Python's bin path to exec()'s execution environment.
To do this, the code below first retrieve all the environment variables and create an array of ENV_KEY=ENV_VALUE pairs.
Then, the path to your Python's bin is appended to the PATH value.
Finally, we pass the array of all environment variables to exec() (via the second parameter).
import java.util.HashMap;
import java.util.Map;
public class Driver {
public static void main(String[] args){
try {
String[] commands = {"python D:/Coding Files/Python/MusicColors.py teenagers.wav"};
// Get a list of all environment variables
final Map<String, String> envMap = new HashMap<String, String>(System.getenv());
// Append Python bin path to Path
envMap.put("Path", envMap.get("Path") + ";C:/Users/Joe/AppData/Local/Programs/Python/Python35-32");
// Convert to an array of ENV_KEY=ENV_VALUE format strings
final String[] envs = new String[envMap.size()];
int i = 0;
for (Map.Entry<String, String> e : envMap.entrySet()) {
envs[i] = e.getKey() + '=' + e.getValue();
i++;
}
// Exec with the environment variables
Process p = Runtime.getRuntime().exec(commands, envs);
}
catch (Exception e){
System.out.println(e);
}
}
}
A nasty problem popped out with my software. I am making a program that interacts with another existing software (a game). User has reported that he runs the game with administrator privileges and under that circumstances, my program stops working for him.
Short investigation revealed that some people really need to run the game under administrator account and some don't. It would be great if my program would be able to detect this and warn user if the game is running under administrator account:
If the user clicks "Elevate", I'd like to ask windows to elevate the java.exe running my jar file and invoke the typical UAC dialog.
Obviously, this time the question would not be about java updater but JRE
My question is: Is this possible? Can windows elevate my java.exe instance's privilege? Does java have a way to do it? Or can I use command line command?
I want to avoid restarting the program (though it wouldn't probably be such a big deal).
Edit:
If you look in the comments, you'll see that there's no avoiding the restart of an application - process can only start elevated, not become elevated. This kinda shifts the question, unfortunately. Basically, it now sounds more like: "How to restart my application with admin rights?". Unless, of course, there's a trick like two java.exe sharing one jar...
If still of interest: In Windows 7 my JavaElevator works. It elevates a running Java process when used in the main method of the Java application. Simply add -elevate as last program parameter and use the elevator in the main method.
The elevator class:
package test;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.ShellAPI;
import com.sun.jna.platform.win32.WinDef;
/**
* Elevates a Java process to administrator rights if requested.
*/
public class JavaElevator {
/** The program argument indicating the need of being elevated */
private static final String ELEVATE_ARG = "-elevate";
/**
* If requested, elevates the Java process started with the given arguments to administrator level.
*
* #param args The Java program arguments
* #return The cleaned program arguments
*/
public static String[] elevate(String[] args) {
String[] result = args;
// Check for elevation marker.
boolean elevate = false;
if (args.length > 0) {
elevate = args[args.length - 1].equals(ELEVATE_ARG);
}
if (elevate) {
// Get the command and remove the elevation marker.
String command = System.getProperty("sun.java.command");
command = command.replace(ELEVATE_ARG, "");
// Get class path and default java home.
String classPath = System.getProperty("java.class.path");
String javaHome = System.getProperty("java.home");
String vm = javaHome + "\\bin\\java.exe";
// Check for alternate VM for elevation. Full path to the VM may be passed with: -Delevation.vm=...
if (System.getProperties().contains("elevation.vm")) {
vm = System.getProperty("elevation.vm");
}
String parameters = "-cp " + classPath;
parameters += " " + command;
Shell32.INSTANCE.ShellExecute(null, "runas", vm, parameters, null, 0);
int lastError = Kernel32.INSTANCE.GetLastError();
if (lastError != 0) {
String errorMessage = Kernel32Util.formatMessageFromLastErrorCode(lastError);
errorMessage += "\n vm: " + vm;
errorMessage += "\n parameters: " + parameters;
throw new IllegalStateException("Error performing elevation: " + lastError + ": " + errorMessage);
}
System.exit(0);
}
return result;
}
}
Usage in the main method of the Java application:
public static void main(String[] args) {
String[] args1 = JavaElevator.elevate(args);
if (args1.length > 0) {
// Continue as intended.
...
I know, this is a very basic implementation - sufficient for one of my daily hiccups: Starting an elevated process from Eclipse. But maybe it points someone in some dicrection...
As has been pointed in comments, sadly the Java (or any other process) cannot be elevated while running. While in the case of JWM, it could be theoretically possible to move whole program context from normal user java.exe to elevated one, I don't think it's possible. I hope some day someone will come and tell me I'm wrong.
Surprisingly, even with restart in place, this was a tricky task that took me a while to figure out.
The non java part
First, how do we exactly run a program elevated from command line? There's an answer and you can see it's not simple. But we can break it to this VBS script:
Set UAC = CreateObject("Shell.Application")
UAC.ShellExecute "program name", "command line parameters", "working directory", "runas", 1
Soon, it also turns out that we won't have any success running java.exe from VBS script. In the end, I decided to run a helper batch file. Finally, here (answer to question in the last link) we have a complete set of two scripts which really run the given .jar file elevated. Here's improved version that allows quick testing by drag'n'dropping the Jar file on it:
' Require first command line parameter
if WScript.Arguments.Count = 0 then
MsgBox("Jar file name required.")
WScript.Quit 1
end if
' Get the script location, the directorry where it's running
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPath)
strFolder = objFSO.GetParentFolderName(objFile)
'MsgBox(strFolder)
' Create the object that serves as runnable something
Set UAC = CreateObject("Shell.Application")
' Args:
' path to executable to run
' command line parameters - first parameter of this file, which is the jar file name
' working directory (this doesn't work but I use it nevertheless)
' runas command which invokes elevation
' 0 means do not show the window. Normally, you show the window, but not this console window
' which just blinks and disappears anyway
UAC.ShellExecute "run-normally.bat", WScript.Arguments(0), strFolder, "runas", 0
WScript.Quit 0
The Java part
Java part is more straightforward. What we need to do is to open new process and execute the prepared scripts in it.
/**
* Start this very jar file elevated on Windows. It is strongly recommended to close any existing IO
* before calling this method and avoid writing anything more to files. The new instance of this same
* program will be started and simultaneous write/write or read/write would cause errors.
* #throws FileNotFoundException if the helper vbs script was not found
* #throws IOException if there was another failure inboking VBS script
*/
public void StartWithAdminRights() throws FileNotFoundException, IOException {
//The path to the helper script. This scripts takes 1 argument which is a Jar file full path
File runAsAdmin = new File("run-as-admin.vbs");;
//Our
String jarPath;
//System.out.println("Current relative path is: " + s);
try {
jarPath = "\""+new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getAbsolutePath()+"\"";
} catch (URISyntaxException ex) {
throw new FileNotFoundException("Could not fetch the path to the current jar file. Got this URISyntax exception:"+ex);
}
//If the jar path was created but doesn't contain .jar, we're (most likely) not running from jar
//typically this happens when running the program from IDE
//These 4 lines just serve as a fallback in testing, should be deleted in production
//code and replaced with another FileNotFoundException
if(!jarPath.contains(".jar")) {
Path currentRelativePath = Paths.get("");
jarPath = "\""+currentRelativePath.toAbsolutePath().toString()+"\\AutoClient.jar\"";
}
//Now we check if the path to vbs script exists, if it does we execute it
if(runAsAdmin.exists()) {
String command = "cscript \""+runAsAdmin.getAbsolutePath()+"\" "+jarPath;
System.out.println("Executing '"+command+"'");
//Note that .exec is asynchronous
//After it starts, you must terminate your program ASAP, or you'll have 2 instances running
Runtime.getRuntime().exec(command);
}
else
throw new FileNotFoundException("The VBSScript used for elevation not found at "+runAsAdmin.getAbsolutePath());
}
This is my version. It creates a VBScript script, then executes it. This only works if the program that is being run is in a jar file, so you will have to run your IDE as administrator to actually test your program.
public static void relaunchAsAdmin() throws IOException {
relaunchAsAdmin(ThisClass.class); //Change ThisClass to the class that this method is in
}
public static void relaunchAsAdmin(Class<?> clazz) throws IOException {
if(isCurrentProcessElevated()) {
return;
}
final String dir = System.getProperty("java.io.tmpdir");
final File script = new File(dir, "relaunchAsAdmin" + System.nanoTime() +
".vbs");
try {
script.createNewFile();
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(script));
osw.append("Set s=CreateObject(\"Shell.Application\")" + ln + "s.ShellExecute \"" +
System.getProperty("java.home") + "\\bin\\java.exe" + "\",\"-jar \"\"" +
new File(clazz.getProtectionDomain().getCodeSource(
).getLocation().toURI()).getAbsolutePath() + "\"\"\",,\"runas\",0" +
ln + "x=createObject(\"scripting.fileSystemObject\").deleteFile(" +
"WScript.scriptfullname)");
osw.close();
if(System.getenv("processor_architecture").equals("x86")) {
Runtime.getRuntime().exec("C:\\Windows\\System32\\wscript.exe \"" +
script.getAbsolutePath() + "\"");
} else {
Runtime.getRuntime().exec("C:\\Windows\\SysWoW64\\wscript.exe \"" +
script.getAbsolutePath() + "\"");
}
} catch(URISyntaxException e) {
e.printStackTrace();
}
Runtime.getRuntime().exit(0);
}
Note that it is a bit messy. I have been using this method before, so it has been line wrapped to 100 characters (except the comment I wrote for this answer). The
isCurrentProcessElevated()
method will have to be implemented in one way or another. You could try using JNI, or you could use a pure Java method, such as writing in the Program Files or System32 directory and seeing if it failed.
Obviously, this solution will only work on Windows. I never needed to elevate on Linux or Mac systems (mainly because I don't have any Mac systems, and I don't use Linux - I just play with it).
I am using Rserve to access an R script through my Java project. The java code asks for a user input to enter the file location and stores in a String variable. This variable is then passes through to the R function which should read the file location perform some processes and then create a new folder and write the processed data in individual files and then print out on the console that all the files have been generated. I initially checked the R connection with a smaller version of the program and it worked. But, when I include the steps to write data to files, it shows the following error:
Enter the file path:
/home/workspace/TestR/test_file
Exception in thread "main" org.rosuda.REngine.Rserve.RserveException: eval failed, request status: error code: 127
at org.rosuda.REngine.Rserve.RConnection.eval(RConnection.java:234)
at testMain.main(testMain.java:23)
Moreover, the code also does not print any statements on the console which have to be printed via R from the Rscript. Here is the Java code:
import java.util.Scanner;
import org.rosuda.REngine.REXP;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.REngineException;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;
public class testMain {
static String dirPath;
public static void main(String[] args) throws REXPMismatchException, REngineException {
// For user input
Scanner scanner = new Scanner(System.in );
System.out.println("Enter the file path: ");
dirPath = scanner.nextLine();
RConnection c = new RConnection();
// source the Palindrome function
c.eval("source('/home/workspace/TestR/Main.R')");
REXP valueReturned = c.eval("Main(\""+dirPath+"\")");
//c.eval("Main(\""+dirPath+"\")");
System.out.println(valueReturned.length());
}
}
And, here is the R script:
Main <- function(FILE_PATH)
{
## load libraries
library(MALDIquant)
library(MALDIquantForeign)
library(dcemriS4)
require(gridExtra) # also loads grid
library(lattice)
library(fields)
library(matlab)
library(rJava)
#Call the source files of the function which this script will use
source('/home/workspace/TestR/importAnalyzeFormat.R', echo=TRUE)
source('/home/workspace/TestR/exportFile.R', echo=TRUE)
source('/home/workspace/TestR/readRecalibratedSpectra.R', echo=TRUE)
spectralDataObjects <- importAnalyzeFormat(FILE_PATH)
p <- detectPeaks(spectralDataObjects, method="MAD", halfWindowSize=1, SNR=1)
# Assign the p to preprocessedDataObjects
preprocessedDataObjects<-p
dir.create("PreprocessedSpectra", showWarnings = FALSE)
setwd("PreprocessedSpectra")
for(i in 1:length(preprocessedDataObjects))
{
coordinateValue<-metaData(preprocessedDataObjects[[i]])
coordinates<-coordinateValue$imaging$pos
mzValues<-mass(preprocessedDataObjects[[i]])
intensityValues<-intensity(preprocessedDataObjects[[i]])
exportFile(coordinates,mzValues,intensityValues)
}
print("Files exported. Program will now terminate")
print("############################################################")
return(preprocessedDataObjects)
}
Can someone please help me?
You have an error in your script, a 127 means that there is a parse exception.
If you use something like this it will print out the error in the script.
c is the rserve connection in this case.
c.assign(".tmp.", myCode);
REXP r = c.parseAndEval("try(eval(parse(text=.tmp.)),silent=TRUE)");
if (r.inherits("try-error")) System.err.println("Error: "+r.toString())
else { // success .. }
Error code 127 means parsing exception.
Change your line:
c.eval("source('/home/workspace/TestR/Main.R')");
to
c.eval("source(\"/home/workspace/TestR/Main.R\")");
Now it is suppose to work.
I am trying to copy a file 'project.jpg' from my /sdcard to /sdcard/temp/ folder, but for some reason , the file isn't getting copied. I am testing using a virtual device and have transferred the file 'project.jpg' via the adb shell. The function used to copy the file is,
public void $copyFile()
{
try
{
cpSrc = escapePath(this.cpSrc);
cpDest = escapePath(this.cpDest);
Log.d("$copyFile()","cpSrc = "+cpSrc);
Log.d("$copyFile()","cpDest = "+cpDest);
String destination = getFilename(cpDest,extractFilename(cpSrc));
Runtime.getRuntime().exec("dd in="+cpSrc+" of="+destination);
Log.d("$copyFile()","executed command : 'dd in="+cpSrc+" of="+destination+"'");
displayToast("File Copied Sucessfully.");
clearAllModes();
return;
}
catch(Exception e)
{
displayToast("$copyFile Error : "+e);
this.clearCopyBuffer();
clearAllModes();
}
}
where escapePath() is used to escape space characters(if any) in the given paths. I got the debug Logs as follows,
cpSrc = /sdcard/project.jpg
cpDest = /sdcard/temp
executed command : 'dd in=/sdcard/project.jpg of=/sdcard/temp/project.jpg
Could anyone point the error in the code,
BTW suggestions for other ways of coping files/folders ? it would be helpful as i am trying my hand at a file manager.