Call a java method in R using rJava - java

I use rJava to call a java code from R, trying to call an algorithm from SPMF tool. I tried to use a wrapper function as in this question, but this did not work with the SPMF code.
this is my R code:
library(rJava)
.jinit()
.jaddClassPath ( "C:/mydrive/eclipse-workspace/myfile/src")
print(.jclassPath())
obj <- .jnew("AlgoFPGrowth_Strings")
s <- .jcall(obj, returnSig= "V", method="runAlgorithm",
"input.csv","output.txt") , 0.4 )
it gives me error ,method runAlgorithm with signature (D)V not found
this is the main in java:
public static void main(String[] args) throws Exception {
AlgoFPGrowth_Strings fpwindow=new AlgoFPGrowth_Strings();
String input="input.csv";
String output="output.txt";
double minsupp = 0.4;
fpwindow.runAlgorithm( input, output, minsupp);
fpwindow.printStats();
}
I tried to change returnSig value into S and Ljava/lang/String; but I got the same error, could not find the method
when I apply the code on different java code with simple method it works, is there any idea how can I change my code?

Try the below methods,
Change your jclassPath, where you directly specify the complete pathname of your jar file including the jar name, say /home/user/mypath/myclass_name.jar
Or, you can unzip your jar file in a folder and refer to that path in your jclassPath.
If, the above does not work,
Try to write the 'runAlgorithm' method in the same class where you are calling. I have faced issues with calling external libraries/classes.

Related

Getting java.lang.UnsatisfiedLinkError at runtime

I'm trying to use JNI to access C++ methods from a Java class. I'm able to compile (both in Eclipse or on command line) my Java class fine, but on executing the class at runtime, I'm getting:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.domain.services.CallServiceAPIS.createSession()I
at com.domain.services.CallServiceAPIS.createSession(Native Method)
at com.domain.services.CallServiceAPIS.main(CallServiceAPIS.java:18)
Java code is as follows:
package com.domain.services;
public class CallServiceAPIS {
static {
System.loadLibrary("service.client");
}
public native int createSession();
public static void main(String[] args) {
System.out.println(System.getProperty("java.library.path"));
new CallServiceAPIS().createSession();
}
}
I included the printout of the java.library.path just to make sure it's pointing to the correct location of the C++ library - and it is. I also tried setting the LD_LIBRARY_PATH in my Eclipse environment. But neither worked.
Note that the System.loadLibrary call IS working since 1) the code compiles and 2) the error occurs on line 18, which is the new CallServiceAPIs call.
C++ code:
int createSession(const PosServiceInfo info, const SessionArgs& args, Domain::UUID& uuidSession)
{
return int::undefined;
}
Any ideas?
Never mind. I realized that I was using the JNI interface incorrectly. I was thinking you could load an EXISTING C++ library using EXISTING C++ source. But you basically have to rewrite the existing code to make use of the JNI interface.

Unsure about reason behind NoClassDefFoundError

I have built a DLL which I am attempting to wrap Java code with, however I am having some troubles with running my Java program. I wrote a simple test DLL and Java program and am producing the same error, and although there are plenty of resources regarding NoClassDefFoundError online I can't seem to solve mine with any troubleshooting methods.
Here is my D:\Test1.Java file
public class Test1 {
static {
//System.loadLibrary("HeyLand");
System.load("D://HeyLand.dll");
}
public native void displayHeyLand();
public static void main (String[] args) {
Test1 t = new Test1();
t.displayHeyLand();
}
}
After compiling, attempting to run D:\Test1.classresults in the following:
D:\>java Test1.class
Exception in thread "main" java.lang.NoClassDefFoundError: Test1.class
Caused by: java.lang.ClassNotFoundException: Test1.class
at java.net.URLClassLoader.findClass(URLClassLoader.java:434)
at java.lang.ClassLoader.loadClass(ClassLoader.java:660)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:358)
at java.lang.ClassLoader.loadClass(ClassLoader.java:626)
Could not find the main class: Test1.class. Program will exit.
Why I am stumped :
1. I have set my classpath to be D:\, so I believe my class definition would be in the classpath, and I do not see how my compile-time and run-time classpaths could be any different.
2. I don't see how this could have anything to do with static initialization, and I believe the exception would look different.
Perhaps I'm just missing something incredibly simple, I am very newbie with Java.
Any help is greatly appreciated!
The classpath environmental variable is taking precedence over that in the java run command. You need to specify the class location (as well as removing the .class file extension)
java -cp . Test1
Java normal syntax for executing class file is
Java [<options>....} <class-name> [<arguments>....]
For example
java com.package.name.Test1
here how compiler works
1. Compiler search for complete class name
2. Load that class
3. check for main method - in the same class
4. Call main method with passed arguments in command line string.
Now following are the possibilities why your class may not found main method.
1 - forgot to include package name
I am new developer in java but I found when I run application using eclips or intellJ editor it gives different path and package name and execute code as I noticed it on command line edior. So make sure you are including package name
For example:
java com.package.name.Test1 instead of
java Test1
2. File name or pathname rather then class name
As I noticed output file is in different location. That why class file path was different.
java Test1.class
java com/package/name/Test1.class
3. Typo
also I noticed you are using
static {
//System.loadLibrary("HeyLand");
System.load("D://HeyLand.dll");
}
Is this function ? or constructor? If it is function then where is name of the function? You cant write code without any reference in classs

simple groovy program fails with error: No signature of method: java.lang.ProcessBuilder.inheritIO() is applicable for argument types: () values: []

I'm scratching my head on this one, The program is as follows:
class MyClass {
def static someMethod() {
def pb = new ProcessBuilder("")
pb.inheritIO()
pb.setCommand(/* command list */)
def process = pb.start()
...
println "profit"
}
}
except running the above (or the equivelant of) gives the output:
No signature of method: java.lang.ProcessBuilder.inheritIO() is applicable for argument types: () values: []
inheritIO is obviously a method defined in the ProcessBuilder class
so what is going wrong here?
CONTEXT: this is happening during a gradle build using jdk 7u55 except i imagine this info is unrelated. to me it looks like groovy has forgotten what it was doing.
EDIT: if i delete the pb.inheritIO() line then when i call pb.start() it throws another error:
java.lang.ArrayStoreException
Turns out the answer is quite involved but very specific to my setup:
although i have my org.gradle.java.home property set to the java 1.7 jdk, I am using a properties plugin that uses different property files according to an environment variable called environmentName this property was set to the incorrect value thus it was reading JAVA_HOME from my environment rather than the variable i set in the property file i wanted. I changed this and the jre was switched to the correct runtime.

Problems in passing contents of xml file as string to native function

I want to pass String containing contents of xml file to native function using JNA .But somehow it is giving me problems. The program goes into infinite loop and does not get terminated. The same thing is working when I am trying to access DLL through C.
This is how my code looks like -
Native side --
Class ABC{
...
long t = processValues(const * str1 ,char** output);
...}
JNA interface looks llke this -
public interface Add extends Library
{
Add INSTANCE = (Add) Native.loadLibrary("add", Add.class);
...
NativeLong processValues(String str1,PointerByReference output);
...}
main method in java class is as follows -
public static void main(String args[]){
Add lib = Add.INSTANCE;
PointerByReference ptrRef = new PointerByReference();
String strBuffer = "<?xml version= \"1.0\" ?><NRECORD> <SUBRECORD><ITEM1> <NAME> pqr</NAME> <MDATE>10/12/2012</MDATE><ENGINEER>TMAY</ENGINEER></ITEM1></SUBRECORD></NRECORD> "
Nativelong p = lib.processValues(strBuffer,ptrRef);
}
The program goes into infinite loop and never get terminated. DLL uses recursive function to parse input xml string, I think this is where problem lies. (I am using third party dll so cant access code.) But function processValues() get executed successfully when same dll is accessed through C.(with same input parameters) My questions are
is this right way to pass xml contents as string?
Is there any way by which I can get event logs how the dll functions are getting called.
Thanks in advance.

UnsatisfiedLinkerror

I was getting an exception: UnsatisfiedLinkError when I was trying to load a library. I had placed the library file in the right path and added the path to the PATH env variable. But nothing seemed to work. Untill I changed the Tomcat configuration and added -Djava.library.path=C:\Windows\System32 to the java options. One of my colleagues did not have to do this and yet it worked fine on her system, what is it that I am missing? Can anybody throw some light on this pleasE?
One option could be to register the dll
Regsvr32 “path to your dll.dll”.
This will install/register the dll (I am assuming it is a dll)
But I have generally observed that if it is COM dll then you have to register it and put it in System32
In JNI the name of Java native method and the name of corresponding C function are not same. In order to call C function, the name of C function MUST include the prefix "Java_", the class name and method name. The easy way is using the program "javah" in order to generate a header file including all definitions.
Try with following example for Windows:
(remember that the Java class name must be the same that corresponding file name)
Step 1. Create the following Java file (P.java):
class P
{
static
{
// "P" is the name of DLL without ".dll"
System.loadLibrary ("P");
}
public static native void f(int i);
public static void main(String[] args)
{
f(1);
}
}
Step 2. javac P.java
Step 3. javah P
Then, "javah" generates the header file "P.h"
Step 4. Create the file "P.def" including the following two lines (this file defines the exported symbols, in this case the name of C function):
EXPORTS
Java_P_f
Step 5. Create your C file (P.c):
#include "p.h"
JNIEXPORT void JNICALL Java_P_f(JNIEnv *env, jclass c, jint i)
{
printf("%i\n",i);
}
Step 6. Within Visual Studio command promt, define the following variables:
set JAVA_HOME= the path of JDK
set include=%include%;%JAVA_HOME%\include;%JAVA_HOME%\include\win32
Step 7. Generate DLL:
cl /LD P.c P.def
Step 8. Run the Java program:
java P
(Note: P.dll and P.class are located in the same directory)

Categories

Resources