Java and R integration - java

I am trying to build a java project which contains R codes. Main logic behind that is I want to automate the data structuring and data analysis with in a same project. Partially I am being able to do that. I connected R to Java and my R codes are running well. I did all my set up in the local machine and its giving me all output as I need. As data set is big I am trying to run this on amazon server. But when I am shifting it to server, my project is not working properly. Its not being able to execute library(XLConnect), library(rJava). When ever I am calling this two libraries in my java project it's crashing. Independently in R codes are running and giving me output. What I can I for that, and how to fix thus error. Please help me out from this.
My java codes is
import java.io.InputStreamReader;
import java.io.Reader;
public class TestRMain {
public static void main(String[] arg)throws Exception{
ProcessBuilder broker = new ProcessBuilder("R.exe","--file=E:\\New\\Modified_Best_Config.R");
Process runBroker = broker.start();
Reader reader = new InputStreamReader(runBroker.getInputStream());
int ch;
while((ch = reader.read())!= -1)
System.out.print((char)ch);
reader.close();
runBroker.waitFor();
System.out.println("Execution complete");
}
}
And in the Modified_Best_Config.R I have written these codes
library('ClustOfVar');
library("doBy");
library(XLConnect)
#library(rJava)
#library(xlsx)
path="E:/New/";
############Importing and reading the excel files into R##############
Automated_R <- loadWorkbook("E:/New/Option_Mix_Calculation1.xlsx")
sheet1 <- readWorksheet(Automated_R, sheet = "Current Output")
sheet2 <- readWorksheet(Automated_R, sheet = "Actual Sales monthly")
sheet3 <- readWorksheet(Automated_R, sheet = "Differences")
#####################Importing raw Data###############################
optionData<- read.csv(paste(path,"ModifiedStructureNewBestConfig1.csv",sep=""),head=TRUE,sep=",");
nrow(optionData)
optionDemand=sapply(split(optionData,optionData$Trim),trimSplit);
optionDemand1=t(optionDemand[c(-1,-2),]);
optionDemand1
################Calculating the equipment Demand####################
optionDemand2<-t(optionDemand2[c(-1,0)]);
Rownames <- as.data.frame(row.names(optionDemand2))
writeWorksheet(Automated_R,Rownames, sheet = "Current Output", startRow = 21, startCol = 1)
writeWorksheet(Automated_R,optionDemand2, sheet = "Current Output", startRow = 21, startCol = 2)
saveWorkbook(Automated_R)
But java is stopping its operation after these line.
library("doBy");
Whole set of codes are running on nicely on my local machine. But whenever I am trying to run this on amazon server it's not running. Individually in R this code is running on server. I have couple of more R codes which are running with out any error. What can I do for that, please help me out.

Thanks for updating your question with some example code. I cannot completely replicate your circumstances because I presently don't have immediate access to Amazon EC2, and I don't know the specific type of instance you are using. But here a couple of suggestions for de-bugging your issue, which I have a hunch is being caused by a missing package.
1. Try to install the offending packages via your R script
At the very beginning of your R script, before you try to load any packages, insert the following:
install.packages(c("XLConnect", "rJava"))
If your instance includes a specified CRAN mirror (essentially, the online repository where R will first look to download the package source code from), this should install the packages in the same repo where your other packages are kept on your server. Then, either library or require should load your packages.
(sidenote: rJava is actually a dependency of XLConnect, so it will automatically load anyway if you only specify library(XLConnect))
2. If the above does not work, try installing the packages via the command line
This is essentially what #Ben was suggesting with his comment. Alternatively, see perhaps this link, which deals with a similar problem with a different package. If you can, in terminal on the server, I would try entering the following three commands:
sudo add-apt-repository ppa:marutter/rrutter
sudo apt-get update
sudo apt-get install r-cran-XLConnect
In my experience this has been a good go-to repo when I can't seem to find a package I need to install. But you may or may not have permission to install packages on your server instance.

Related

Create/Read files with Python in Graal VM

Im working with Graal VM, using combined languages like Java and Python. I have a problem when try to execute Python sintax to read/create files using context.eval().
I use this code using Graalpython in terminal:
out_file = File.new("cadena.txt", "w+")
out_file.puts("write your stuff here")
out_file.close
and works, but when I tried to run a code to read the file in context.eval() with Java:
codigoPython += "fichw = open('cadena.txt','r')";
codigoPython += "fichw.read() ";
codigoPython += "fichw.close() ";
Value filecontent = context.eval("python", codigoPython);
it throws me this error:
PermissionError: (1, Operation not permitted, cadena.txt, None, None)
I also tried running it using sudo and sudo su but it gives me the same error. Does anyone know why this happened?
Thanks
You need to give your context permission to do IO:
Context context = Context.newBuilder("python").allowIO(true).build();
For experimenting/prototyping it may be useful to allow everything:
Context context = Context.newBuilder("python").allowAllAccess(true).build();

Why is java_executable_exec_path giving me a legacy "external" runfiles path

Suppose I've got a minimal Scala WORKSPACE file like this:
workspace(name = "scala_example")
git_repository(
name = "io_bazel_rules_scala",
commit = "e9e65ada59823c263352d10c30411f4739d5df25",
remote = "https://github.com/bazelbuild/rules_scala",
)
load("#io_bazel_rules_scala//scala:scala.bzl", "scala_repositories")
scala_repositories()
load("#io_bazel_rules_scala//scala:toolchains.bzl", "scala_register_toolchains")
scala_register_toolchains()
And then a BUILD:
load("#io_bazel_rules_scala//scala:scala.bzl", "scala_binary")
scala_binary(
name = "example-bin",
srcs = glob(["*.scala"]),
main_class = "Example",
)
And an Example.scala:
object Example { def main(args: Array[String]): Unit = println("running") }
I can run bazel run example-bin and everything works just fine. My problem is that this recent rules_scala PR changed the way the Java binary path is set to use the following:
ctx.attr._java_runtime[java_common.JavaRuntimeInfo].java_executable_exec_path
…instead of the previous ctx.executable._java.short_path.
After this change the Java binary path includes an external directory in the path, which seems to be a legacy thing (?). This means that after this change, if I run the following:
bazel run --nolegacy_external_runfiles example-bin
It no longer works:
INFO: Running command line: bazel-bin/example-bin
.../.cache/bazel/_bazel_travis/03e97e9dbbfe483081a6eca2764532e8/execroot/scala_example/bazel-out/k8-fastbuild/bin/example-bin.runfiles/scala_example/example-bin_wrapper.sh: line 4: .../.cache/bazel/_bazel_travis/03e97e9dbbfe483081a6eca2764532e8/execroot/scala_example/bazel-out/k8-fastbuild/bin/example-bin.runfiles/scala_example/external/local_jdk/bin/java: No such file or directory
ERROR: Non-zero return code '127' from command: Process exited with status 127
It also breaks some scripts I have that expect non-external paths.
Why is java_executable_exec_path giving me this external path? Is there some option I can give bazel to convince it not to do this?
Sorry for the slow reply -- it appears that this is because the Scala rules erroneously used java_executable_exec_path whereas they should have used java_executable_runfiles_path.
I sent a pull request to fix it, then I realized that you already did in https://github.com/bazelbuild/rules_scala/commit/4235ef58782ce2ec82981ea70b808397b64fe7df
Since the latter is now available at HEAD with Bazel, I'll remove the ugly if at least.

Using XLLoop for java

XLLoop is opensource framework to java. For example we can use function from java in excel. Below is very simple example of usage:
package org.boris.xlloop.util;
import org.boris.xlloop.FunctionServer;
import org.boris.xlloop.handler.*;
import org.boris.xlloop.reflect.*;
public class ServerExample
{
public static void main(String[] args) throws Exception {
// Create function server on the default port
FunctionServer fs = new FunctionServer();
// Create a reflection function handler and add the Math methods
ReflectFunctionHandler rfh = new ReflectFunctionHandler();
rfh.addMethods("Math.", Math.class);
rfh.addMethods("Math.", Maths.class);
rfh.addMethods("CSV.", CSV.class);
rfh.addMethods("Reflect.", Reflect.class);
// Create a function information handler to register our functions
FunctionInformationHandler firh = new FunctionInformationHandler();
firh.add(rfh.getFunctions());
// Set the handlers
CompositeFunctionHandler cfh = new CompositeFunctionHandler();
cfh.add(rfh);
cfh.add(firh);
fs.setFunctionHandler(new DebugFunctionHandler(cfh));
// Run the engine
System.out.println("Listening on port " + fs.getPort() + "...");
fs.run();
}
}
I understand it and generally programm is working. But if I go to excel, it isn't working.
I try:
=FS("Math.random")
=Math.random()
But I got #NAME? twice
So I suppose that I should make something yet. Could you tell me step by step how configure excel and java to do this? What should I do with xlloop-0.3.2 (Microsoft Excel XLL Add-In) file ?
I tried running the code and I got the following output.
All I had to do was to launch Excel and add the XLLoop addin.
. Press Alt+G or click on the Go button beside Manage Excel Add-ins.
. Click on Browse and provide the path to the xlloop-0.3.2.xll file. If you had downloaded xlloop-0.3.2.zip,extract it and you will find it inside /xlloop/bin
Hope that helps.
Edit:
Launch Excel.
Start the server(run the Main class) and test the formulas.
I tested the following 2(typed them on the Excel formula bar and hit/press Enter) and it worked fine. :)
=FS("Math.sin", 3.14)
=FS("Math.random")
For anyone running into the same problem:
You have to add the correct Addin Version to your excel installation.
If you are getting the error message: "The file format and extension [...] don't match.", it means that you are using a 64bit excel and the 32bit XLLoop addin.
You have to either install a 32bit Excel, or you have to get the 64bit version of the XLLoop Plugin.
We ran into the same problem, and created a 64bit version of the addin: https://github.com/PATRONAS/xlloop

how to create backup of postgres database using java

i want to take backup of postgres database using java. I am using following code for this
but this is not working and not generating dump.
String pgDump = "C:\\Program Files\\PostgreSQL\\9.2\\bin\\pg_dump";
String dumpFile = "D:\\test\\"+ tenant.getTenantAsTemplate()+".sql";
String sql = pgDump+" -h localhost -U postgres -P postgres " + tenant.getTenantAsTemplate()+" > "+dumpFile;
Process p = Runtime.getRuntime().exec(sql);
int time = p.waitFor();
System.out.println("time is "+time);
if(time == 0){
System.out.println("backup is created");
}
else{
System.out.println("fail to create backup");
}
Here i am getting time is 1.
This is also operating system dependent and we need also pg_dump. is there any other way to generate backup of database without pg_dump?
please reply soon.
No, there is no way to generate a database backup without pg_dump, using the regular SQL connection. It's a bit of an FAQ, but the people who want the feature never step up to do the work to implement the feature in PostgreSQL.
I guess technically you could use a replication connection to do a physical base backup like pg_basebackup does, but that's not really what you want, requires copying all databases on the machine, and would be a lot of work.
You should use the String[] form of Runtime.exec as I mentioned in a related answer regarding pg_restore.
You must also check the process exit value to see if it terminated successfully or not, and you must be careful to handle, not just swallow, any exceptions thrown.
Your code fails to check the exit value, and I think it's probably generating a malformed command that's failing with a non-zero exit code, probably because you are not correctly quoting the path to pg_dump. To see what's wrong, print the final assembled command line, you'll see something like:
C:\Program Files\PostgreSQL\9.2\bin\pg_dump -h localhost ....
which cmd.exe will split into:
c:\Program
Files\postgresql\9.2\bin\pg_dump
-h
localhost
... etc
See the problem?
Do not just quote the path to pg_dump to work around this. Use the String[] form of exec and you won't have to, plus it'll work correctly for other things like accidental %environmentvars% in paths.

How can I make OS X recognize drive letters?

I know. Heresy. But I'm in a bind. I have a lot of config files that use absolute path names, which creates an incompatibility between OS X and Windows. If I can get OS X (which I'm betting is the more flexible of the two) to recognize Q:/foo/bar/bim.properties as a valid absolute file name, it'll save me days of work spelunking through stack traces and config files.
In the end, I need this bit of Java test code to print "SUCCESS!" when it runs:
import java.io.*;
class DriveLetterTest {
static public void main(String... args) {
File f = new File("S:");
if (f.isDirectory()) {
System.out.println("SUCCESS!");
} else {
System.out.println("FAIL!");
}
}
}
Anyone know how this can be done?
UPDATE: Thanks for all the feedback, everyone. It's now obvious to me I really should have been clearer in my question.
Both the config files and the code that uses them belong to a third-party package I cannot change. (Well, I can change them, but that means incurring an ongoing maintenance load, which I want to avoid if at all possible.)
I'm in complete agreement with all of you who are appalled by this state of affairs. But the fact remains: I can't change the third-party code, and I really want to avoid forking the config files.
Short answer: No.
Long answer: For Java you should use System.getProperties(XXX).
Then you can load a Properties file or Configuration based on what you find in os.name.
Alternate Solution just strip off the S: when you read the existing configuration files on non-Windows machines and replace them with the appropriate things.
Opinion: Personally I would bite the bullet and deal with the technical debt now, fix all the configuration files at build time when the deployment for OSX is built and be done with it.
public class WhichOS
{
public static void main(final String[] args)
{
System.out.format("System.getProperty(\"os.name\") = %s\n", System.getProperty("os.name"));
System.out.format("System.getProperty(\"os.arch\") = %s\n", System.getProperty("os.arch"));
System.out.format("System.getProperty(\"os.version\") = %s\n", System.getProperty("os.version"));
}
}
the output on my iMac is:
System.getProperty("os.name") = Mac OS X
System.getProperty("os.arch") = x86_64
System.getProperty("os.version") = 10.6.4
Honestly, don't hard-code absolute paths in a program, even for a single-platform app. Do the correct thing.
The following is my wrong solution, saved to remind myself not to repeat giving a misdirected advice ... shame on me.
Just create a symbolic link named Q: just at the root directory / to / itself.
$ cd /
$ ln -s / Q:
$ ln -s / S:
You might need to use sudo. Then, at the start of your program, just chdir to /.
If you don't want Q: and S: to show up in the Finder, perform
$ /Developer/Tools/SetFile -P -a V Q:
$ /Developer/Tools/SetFile -P -a V S:
which set the invisible-to-the-Finder bit of the files.
The only way you can replace java.io.File is to replace that class in rt.jar.
I don't recommend that, but the best way to do this is to grab a bsd-port of the OpenJDK code, make necessary changes, build it and redistribute the binary with your project. Write a shell script to use your own java binary and not the built-in one.
PS. Just change your config files! Practice your regex skills and save yourself a lot of time.
If you are not willing to change your config file per OS, what are they for in first place?
Every installation should have its own set of config files and use it accordingly.
But if you insist.. you just have to detect the OS version and if is not Windows, ignore the letter:
Something along the lines:
boolean isWindows = System.getProperty("os.name").toLowerCase()
.contains("windows");
String folder = "S:";
if (isWindows && folder.matches("\\w:")) {
folder = "/";
} else if (isWindows && folder.matches("\\w:.+")) {
folder = folder.substring(2);// ignoring the first two letters S:
}
You get the idea
Most likely you'd have to provide a different java.io.File implementation that can parse out the file paths correctly, maybe there's one someone already made.
The real solution is to put this kind of stuff (hard-coded file paths) in configuration files and not in the source code.
Just tested something out, and discovered something interesting: In Windows, if the current directory is on the same logical volume (i.e. root is the same drive letter), you can leave off the drive letter when using a path. So you could just trim off all those drive letters and colons and you should be fine as long as you aren't using paths to items on different disks.
Here's what I finally ended up doing:
I downloaded the source code for the java.io package, and tweaked the code for java.io.File to look for path names that start with a letter and a colon. If it finds one, it prepends "/Volumes/" to the path name, coughs a warning into System.err, then continues as normal.
I've added symlinks under /Volumes to the "drives" I need mapped, so I have:
/Volumes/S:
/Volumes/Q:
I put it into its own jar, and put that jar at the front of the classpath for this project only. This way, the hack affects only me, and only this project.
Net result: java.io.File sees a path like "S:/bling.properties", and then checks the OS. If the OS is OS X, it prepends "/Volumes/", and looks for a file in /Volumes/S:/bling.properties, which is fine, because it can just follow the symlink.
Yeah, it's ugly as hell. But it gets the job done for today.

Categories

Resources