JRI REngine eval() method always returns null - linux

I have a Java servlet running on Tomcat6 which uses JRI (rJava) to communicate with R installed on an Amazon linux server. I installed R from source, installed rJava via cran and set R_HOME and my classpath for Tomcat. I had to setup a few symlinks in one of my java.library.path directories to the necessary native libraries (libjri.so, libR.so and libRblas.so) because I couldn't configure java.library.path to include the directories that they installed in, but I don't think that's a problem. When I run
./run rtest
from the command line in $R_HOME/library/rJava/jri/ I get the expected output and the REngine class seems to be making R statements via eval() fine. But when I call eval() from my class, I get a null instead of REXP object returned in almost all cases. There are no errors logged with or without DEBUG on. The only case where I've gotten a REXP returned is when I set an array, e.g.
array1=c(7245.0, 6003.0, 5504.0)
In this case, I get a REXP whose toString() value is
[REAL* (7245.0, 6003.0, 5504.0)]
But if I then make an eval() call with
summary(array1)
I get back a null instead of the expected REXP. The code, which works on my Mac, is:
private REXP multipleRegression(Datalist list) {
String fitStr = "fit <- lm(";
for (int i = 0; i < list.size(); i++) {
Datastream ds = list.get(i);
String dsStr = ds.getId() + "=" + ds.toArrayString();
System.out.println("VALUE: " + this.eval(dsStr));
System.out.println("SUMMARY: " + this.eval("summary(" + ds.getId() + ")"));
fitStr += ds.getId();
if (i == 0)
fitStr += " ~ ";
else if (i == list.size() - 1)
fitStr += ")";
else
fitStr += " + ";
}
if (list.size() == 1) {
fitStr += "1)";
}
this.eval(fitStr);
return this.eval("summary(fit)");
}
Again, this works on my Mac, so I'm pretty certain the problem is with the environment and not the code. I done several hours of searching and have yet to find a solution. Any help would be wonderful.

Alright, so it did have to do with the native libraries and their symlinks. I got exceptions in my application when I didn't get the symlinks for libjri.so, libR.so and libRblas.so into my java.library.path, but once I got those in, no more exceptions. It turned out I also needed libRlapack.so. Once I symlinked that, I started getting the expected REXP values back.

Related

String with the same content but comparison always returns false

I have the following code, in which using the WiFi library I perform a scan of the available WiFi networks and want to detect if a specific network is available. I am using ESP32 and Arduino IDE. EEPROM memory handling seems to work, but I don't understand why the comparison always returns zero.
SSID = EEPROM.readString(500); // I read from eeprom the string stored in pos 500
WiFi.mode(WIFI_STA);
delay(100);
Serial.println(logg + "SCAN!");
int n = WiFi.scanNetworks();
Serial.println(logg + "SE DETECTARON: " + String(n) + " REDES WIFI!");
for (int i = 0; i < n; ++i) {
// Print SSID and RSSI for each network found
Serial.println("'" + WiFi.SSID(i) + "' vs '" + SSID + "' SizeOf: " + String(WiFi.SSID(i).length()) + " - " + String(SSID.length()) + " Comparacion " + String(WiFi.SSID(i) == SSID );
}
delay(10);
What I get on the serial monitor is the following:
'WRT1900AC 2.4GHz' vs 'WRT1900AC 2.4GHz' SizeOf: 16 - 16 Comparacion 0
The two strings look the same, they are the same size. I already tried replacing comparator "==" with strcmp and I get -244.
I also tried using .c_str as follows:
WiFi.SSID(i).c_str() == SSID.c_str()
but with the same results. If someone comes up with something I would be very grateful.
The two strings look the same, they are the same size.
Although the WiFI.SSID() return a String object, however it does not necessary to be ASCII-encoded. The string encoding is depend on the locale setting of the router, and the reason it looks the same is because the Serial.print() cast it into ASCII. This can be proof by the following sketch by using both Serial.print() and Serial.printf() in ESP32 which shown what is actually received (Serial.printf() however does not support Unicode formatting in ESP32 implementation, so it will produce some garbage characters).
int n = WiFi.scanNetworks();
for (int i=0; i<n; i++) {
// Serial.print() will cast the WiFi.SSID() to ASCII
Serial.print(WiFi.SSID(i));
// this shown what WiFi.SSID() truly return
Serial.printf(" --- %s\n", WiFi.SSID(i));
}
This will produce results in show in this picture. As you can see some SSIDs produce the correct results but some shown up as garbage.
So String comparison operator does do the job correctly when you compare WiFi.SSID(i) == SSID and the result indeed is not necessary equal for some SSID, even though it "looks" the same to human.
So how to solve it? If you want to treat them "as the same", ironically, converting String object to char array with .c_str() does do the job because it convert each char to an ASCII. I guess you just didn't use the char array comparison strcmp() correctly.
if(strcmp(WiFi.SSID(i).c_str(), SSID.c_str()) == 0) {
// match
}
else {
// not match
}
If you are saying that this c.str() comparison return -244, then edit your question and do a Serial.printf() on both String or better off to loop through the String character by charter and print out the HEX code to see what's going on.

Groovy script overwriting first byte?

Hi so this string I'm creating and appending in groovy is somehow corrupting the first byte and I have no idea why this happening. Its the second string creation. In this script I'm making a query and the first one works but the second initialization somehow messes up the first byte in the string and I have to do a substring of an extra index (it's two because I'm initializing a comma). Any insight would be very appreciated!!
Note: I'm using mulesoft runtime 3.8.5 in Anypoint studio 6.4.4. Not sure if this is the reason but it is a candidate in my mind...
flowVars.queryIds = "Id IN ("
for (Integer i = 0; i < payload.size(); i++) {
flowVars.queryIds += "\'" + payload[i].Id + "\',"
}
flowVars.queryIds = flowVars.queryIds.substring(0,flowVars.queryIds.size() - 1) + ")"
//Assigning comma because a random byte is getting inserted and this makes that error explicit & deterministic
flowVars.queryFields = ",";
for (String key : payload[0].keySet()) {
flowVars.queryFields += key + ",";
}
//Skipping over custom field isMatch
flowVars.queryFields = flowVars.queryFields.substring(2, flowVars.queryFields.size() - 9);
return payload
I can't reproduce your problem but since you use groovy, you can write your code a bit shorter:
flowVars.queryIds = "Id IN ("
flowVars.queryIds += payload.collect{"'${it.Id}'"}.join(", ")
flowVars.queryIds += ")"
flowVars.queryFields = payload[0].keySet().join(", ");
this should produce the same output in a more understandable way
So I found out the reason this issue was happening is actually because the csv file I am parsing is corrupted (I thought it was mulesoft and was mistaken). This blog does a greater job explaining the issue than I could. Thanks for your review on the groovy code though Rdmueller! Is definitely a lot cleaner with your suggestions. https://medium.freecodecamp.org/a-quick-tale-about-feff-the-invisible-character-cd25cd4630e7

Clearing String/Text

Redirect me if this is already a previously solved issue!
In my program, I have a Stage in which the user can view a list of content, stored in a list consisting of Strings.
goToView.setOnAction(event ->{
menuStage.close();
viewStage.show();
String horseNameList = "";
for(int i = 0; i < accountList.size(); i++){
if(accountList.get(i).userName.equals(uName)){
for(int j = 0; j < accountList.get(i).createdHorses.size(); j++){
horseNameList += accountList.get(i).createdHorses.get(j);
horseNameList += "\n" + "\n";
}
}
Text hNameListTXT = new Text(horseNameList);
hNameListTXT.setFont(Font.font("Tahoma", FontWeight.NORMAL, 12));
listVbox.getChildren().add(hNameListTXT);
}
createdHorses is a List of Strings, listVbox is as you may think a VBox where the String (which converts to a Text) is printed. Now, when I close the Stage with the following EventHandler, nothing in particular happens:
backView.setOnAction(event -> {
viewStage.close();
menuStage.show();
});
But as I then open the Stage once again (by using another EventHandler similar to the one I use to close the first Stage with), my List (or String) har been doubled. What should I do to clear the String (or possibly the Text) so that it doesn't display it twice?
What should I do to clear the String (or possibly the Text) so that it
doesn't display it twice?
The VBox has a method getChildren() which returns an ObservableList. So you could use clear() on it to remove all the children.

Different output from toBase64() in CFML on 2 different machines

FINAL EDIT: SOLVED, upgrading local dev to railo 3.3.4.003 resolved the issue.
I have to RC4 encrypt some strings and have them base64 encoded and I'm running into a situation where the same input will generate different outputs on 2 different dev setups.
For instance, if I have a string test2#mail.com
On one machine (DEV-1) I'll get: DunU+ucIPz/Z7Ar+HTw=
and on the other (DEV-2) it'll be: DunU+ucIlZfZ7Ar+HTw=
First, I'm rc4 encrypting it through a function found here.
Next I'm feeding it to: toBase64( my_rc4_encrypted_data, "iso-8859-1")
As far as I can tell the rc4 encryption output is the same on both (or I'm missing something).
Below are SERVER variables from both machines as well as the encryption function.
Is this something we'll simply have to live with or is there something I can do to 'handle it properly' (for a lack of a better word).
I'm concerned that in the future this will bite me and wonder it it can be averted.
edit 1:
Output from my_rc4_encrypted_data.getBytes() returns:
dev-1:
Native Array (byte[])
14--23--44--6--25-8-63-63--39--20-10--2-29-60
dev-2:
Native Array (byte[])
14--23--44--6--25-8-63-63--39--20-10--2-29-60
(no encoding passed to getBytes() )
DEV-1 (remote)
server.coldfusion
productname Railo
productversion 9,0,0,1
server.java
archModel 64
vendor Sun Microsystems Inc.
version 1.6.0_26
server.os
arch amd64
archModel 64
name Windows Server 2008 R2
version 6.1
server.railo
version 3.3.2.002
server.servlet
name Resin/4.0.18
DEV-2 (local)
server.coldfusion
productname Railo
productversion 9,0,0,1
server.java
vendor Oracle Corporation
version 1.7.0_01
server.os
arch x86
name Windows 7
version 6.1
server.railo
version 3.2.2.000
server.servlet
name Resin/4.0.18
RC4 function:
function RC4(strPwd,plaintxt) {
var sbox = ArrayNew(1);
var key = ArrayNew(1);
var tempSwap = 0;
var a = 0;
var b = 0;
var intLength = len(strPwd);
var temp = 0;
var i = 0;
var j = 0;
var k = 0;
var cipherby = 0;
var cipher = "";
for(a=0; a lte 255; a=a+1) {
key[a + 1] = asc(mid(strPwd,(a MOD intLength)+1,1));
sbox[a + 1] = a;
}
for(a=0; a lte 255; a=a+1) {
b = (b + sbox[a + 1] + key[a + 1]) Mod 256;
tempSwap = sbox[a + 1];
sbox[a + 1] = sbox[b + 1];
sbox[b + 1] = tempSwap;
}
for(a=1; a lte len(plaintxt); a=a+1) {
i = (i + 1) mod 256;
j = (j + sbox[i + 1]) Mod 256;
temp = sbox[i + 1];
sbox[i + 1] = sbox[j + 1];
sbox[j + 1] = temp;
k = sbox[((sbox[i + 1] + sbox[j + 1]) mod 256) + 1];
cipherby = BitXor(asc(mid(plaintxt, a, 1)), k);
cipher = cipher & chr(cipherby);
}
return cipher;
}
Leigh wrote:
But be sure to use the same encoding in your test ie
String.getBytes(encoding) (Edit) If you omit it, the jvm default is
used.
Leigh is right - RAILO-1393 resulted in a change to toBase64 related to charset encodings in 3.3.0.017, which is between the 3.3.2.002 and 3.2.2.000 versions you are using.
As far as I can tell the rc4 encryption output is the same on both (or I'm missing something). Below are SERVER variables from both machines as well as the encryption function.
I would suggest saving the output to two files and then comparing the file size or, even better, a file comparison tool. Base64 encoding is a standard approach to converting binary data into string data.
Assuming that your binary files are both exactly 100% the same, on both of your servers try converting the data to base 64 and then back to binary again. I would predict that only one (or neither) of the servers are able to convert the data back to binary again. At that point, you should have a clue about which server is causing your problem and can dig in further.
If they both can reverse the base 64 data to binary and the binary is correct on both servers... well, I'm not sure.

Proper way to transform column and table names in SubSonic 3

I am attempting to transform a table named app_user which has a column named created_dt into AppUser.CreatedDt in SubSonic3 using the ActiveRecord template. From what I've seen one should be able to modify table and column names as needed in the CleanUp method of Settings.ttinclude
So I added this method to Settings.ttinclude
string UnderscoreToCamelCase(string input) {
if( !input.Contains("_"))
return input;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
if (input[i] == '_')
{
while (i < input.Length && input[i] == '_')
i++;
if (i < input.Length)
sb.Append(input[i].ToString().ToUpper());
}
else
{
if (sb.Length == 0)
sb.Append(input[i].ToString().ToUpper());
else
sb.Append(input[i]);
}
}
return sb.ToString();
}
And then this call to CleanUp
result=UnderscoreToCamelCase(result);
If I run a query such as :
var count = (from u in AppUser.All()
where u.CreatedDt >= DateTime.Parse("1/1/2009 0:0:0")
select u).Count();
I get a NotSupportedException, The member 'CreatedDt' is not supported
which comes from a method in TSqlFormatter.sql line 152
protected override Expression VisitMemberAccess(MemberExpression m)
If I comment out the call to UnderscoreToCamelCase and use the names as they are in the database everything works fine.
One interesting thing is that when everything is working OK the VisitMemberAccess method is never called.
Has anyone else been able to convert table/column names with undersores in them to camel case in SubSonic3 ?
There may be an answer to this on another thread within StackOverflow, but it entails modifying the source code for Subsonic.core.
link text

Resources