.jcall error cannot determine object class - java

I want to use .jcall from the rJava package to call a custom java class method.
According to the following example from the rJava-documentation
.jcall("java/lang/System","S","getProperty","os.name")
I tried
.jcall("jrae/src/main/RAEBuilder.java","V","main")
Where "jrae/src/main/RAEBuilder.java" is the path I copied from the eclipse properties of the java class file, "V" represents a void return type and "main"
is the method I want to call from the RAEBuilder.java class.
However, the .jcall method returns with
RcallMethod: cannot determine object class
What could be wrong? (please be patient with me, I am a java-novice)

I found the problem:
I forgot to import the path of the class tree through
.jaddClassPath(path)
before I tried to call the class through .jcall.

Related

java.lang.NoSuchMethodError related with a class constructor

I have the following class signature:
public BlockstemRequester(RateLimiter throttler,
String url, List<String> payloadsToBeRequested, List<String> objRef) {
.
.
.
}
And I'm using that constructor at this following code:
threads.add(new BlockstemRequester(RateLimiter.create(1.0),
String.format("url...", apiKey),
chunks.get(index),
chunksObjRef.get(index)))
where:
RateLimiter is from import com.google.common.util.concurrent.RateLimiter
chunks is defined as val chunks:util.List[util.List[String]] = new util.Vector[util.List[String]]
chunksObjRef is defined as val chunksObjRef:util.List[util.List[String]] = new util.Vector[util.List[String]]
But, unfortunately I'm getting an error telling me that class constructor was not found or defined:
java.lang.NoSuchMethodError: BlockstemRequester.<init>(Lcom/google/common/util/concurrent/RateLimiter;Ljava/lang/String;Ljava/util/List;Ljava/util/List;)
Basically, I'm using this class defined in Scala at my java code project, and I did defined the scala class to use List from java to avoid any problem of incompatible types between the languages.
At runtime I'm getting this following types according to my debug process:
chunks is a Vector[Collections$SynchronizedRandomAccessList]
chunksObjRef is a Vector[Collections$SynchronizedRandomAccessList]
I appreciate any kind of help towards this problem. Thank you!
As per Java docs:
Thrown if an application tries to call a specified method of a class
(either static or instance), and that class no longer has a definition
of that method. Normally, this error is caught by the compiler; this
error can only occur at run time if the definition of a class has
incompatibly changed.
From you question it is not clear if you are getting this at compile time or run time but looks like you are having issue at run time. So, use a Java decompiler and check the .class of this class whether this method is present or not.
Most probable root cause of this issue is that library used at compile time have such a method but library used at runtime doesn't have it, and hence NoSuchMethodError.
Use decompiler and check .class file of the class.
Just solved the problem. So this was the scenario: I have a project X and using a library Y. So both X and Y have different definition of the class BlockstemRequester, both with different constructor signatures. I had to change that class name of my project and refactor my code. So, at runtime the constructor pointed out it was that one from my project X and not from that one defined in the library Y
I appreciate any advise if there is any way to approach this problem better than just renaming/refactoring my local classes
I think that the problem is with your 'typed' list.
If you change the signature to
public BlockstemRequester(RateLimiter throttler,
String url, List payloadsToBeRequested, List objRef)
Or
public BlockstemRequester(RateLimiter throttler,
String url, List<?> payloadsToBeRequested, List<?> objRef)
This will work.

java.lang.ClassNotFoundException for a specified class

In my main I have the following statement
Class booki = Class.forName("Book");
which throws a java.lang.ClassNotFoundException exception
when I use the full path like Class booki = Class.forName("javatests.Book"); it is ok.
The main class and the Book class are in the same package, I also tried using import static javatests.Book.*; but still it throws the exception if I don't set the full path javatests.Book. Can someone explain to me why?
Class.forName resolves a fully qualified class name to the class. Since a method does not know where it is called from neither the package of the calling class nor imports in the calling class play any role.
From docs Class#forName
public static Class<?> forName(String className)
throws ClassNotFoundException
Parameters:
className - the fully qualified name of the desired class.
So this will not throw ClassNotFoundException
Class booki = Class.forName("javatests.Book");
For example, it is not needed to import java.lang.* package in java program but to load class Thread from java.lang package you need to write
Class t = Class.forName("java.lang.Thread");
the above code fragment returns the runtime Class descriptor for the class named java.lang.Thread
You always need a qualified class name unless it's inside the same package. If i define a class foo in my package i can call a method Class testClass = Class.forName("foo") , but i can't call Class testClass = Class.forName("SecureRandom"); even if I import SecureRandom. That's just how the function works. It probably has a shortcut where it tries to find things inside local packages, but doesn't do much behind that.
Firstly the Book class must be in the package javatests.
the JVM load the class by name,through the classpath.
There is no class named "Book" in the classpath.
So JVM give you a ClassNotFoundException when excuse Class.forName("Book").
But 'Class.forName("javatests.Book")' tells JVM the class named 'Book' is in package 'javatests'.
So the JVM can find it and load it.
I hope my answer is helpful :)
JLS provides the following description:
Class lookup is always on behalf of a referencing class and is done through an instance of ClassLoader. Given the fully qualified name of a class, this method attempts to locate, load, and link the class.
The JDK uses one instance of ClassLoader that searches the set of directory tree roots specified by the CLASSPATH environment variable; and obviously it is not aware of the place (package) it has been called. That is why it needs fully qualified name.

How to mention the class path

How can I mention the path of a class as in following code?
Class cl=Class.forName("SomeClass");
This works well if the "SomeClass" is located in the same directory of the calling class. But how to check for a class from a different directory, I saw the syntax for that is like xxxx.yyyy.class, but could not make out what those 'x's and'y's stand for. please help.
Thanks in advance.
Use the fully-qualified class name. For instance, to do this with the Java SE String class, which is in the java.lang package:
Class clazz = Class.forName("java.lang.String");
Those xxx and yyy stands for package names. Packages are normally represented by directories on disk with the same name as the package. When you create a class file you can specify which package the class goes by stating package xxx.yyy at the top of the file.
Referring to "SomeClass" without a package name will try to load a class named SomeClass in the default package.
Use Class.forName although make sure you deal with a possible ClassNotFoundException exception. This is a runtime exception so it does not mean you need to catch it. This is how you will know if you path to the class is correct. The problem is that if it cannot find the class funny things can happen with your code.
Class.forName(com.my.package.ClassName)

Why is java.lang.IllegalStateException being generated when trying to access a class?

I'm trying to get a class whose instance has already been created and I want to use that instance. The name of the needed class and the correct package is specified. However. I'm getting an java.lang.IllegalStateException stating that the specified class could not be found. All of the package names and the imports in each class have been checked and they all match.
Does anyone knows why this is being generated please?
its possible the wanted class isnt on your runtime class path. for more info read this: http://docs.oracle.com/javase/tutorial/essential/environment/paths.html

Java: package cannot be resolved to a type

I have this error while using a package class in another package.
Can anybody help?
Based on my guess about your problem I suspect that you have something like this in your code:
System.out.println(java.lang);
Note that the parameter to the println method is the name of a package. The java compiler gives the error "java.lang can not be resolved to a class" when you do this.
Can you please post the package statement of your class AList.
I guess if your package statement is something like com.earth.europe.MyPackage, then what you are trying to do wont work.
I suggest you instead import the class AList and just use as -
public class List extends AList {}
Also, I suppose List is not the actual classname you are using.

Categories

Resources