java.lang.NoSuchMethodError related with a class constructor - java

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.

Related

Two java files. Getting IllegalAccessError when running class with main method trying to access a method from the other file

Learning Java. I have two files, each containing one java class. When I run the file with the main method, I get the following error:
Exception in thread "main" java.lang.IllegalAccessError: failed to access class TapeDeck from class TapeDeckTestDrive (TapeDeck is in unnamed module of loader 'app'; TapeDeckTestDrive is in unnamed module of loader com.sun.tools.javac.launcher.Main$MemoryClassLoader #18bf3d14)
at TapeDeckTestDrive.main(TapeDeckTestDrive.java:3)
class TapeDeckTestDrive{
public static void main(String[] args){
TapeDeck t = new TapeDeck();
t.canRecord = true;
t.playTape();
if (t.canRecord == true) {
t.recordTape();
}
}
}
class TapeDeck {
boolean canRecord = false;
void playTape(){
System.out.println("tape playing");
}
void recordTape(){
System.out.println("tape recording");
}
}
Any help please?
Actual Issue
I got this exact same error* doing something very silly:
I tried to run the file as java {main-class}.java. That simple!
Instead, be sure to run it simply as java {main-class}.
*Specifically, the error format I had, like yours:
Exception in thread "main" java.lang.IllegalAccessError: failed to access class {pack.other-class} from class {pack.main-class} ({pack.other-class} is in unnamed module of loader 'app'; {pack.main-class} is in unnamed module of loader com.sun.tools.javac.launcher.Main$MemoryClassLoader #29f69090)
  at {pack.main-class}.{who-cares-where}
  at {pack.main-class}.{who-cares-why}
             . . .
Extra Advice
You can get a similarly annoying error on the same issue, namely inability to access packages in the same directory, if you only compile your {main-class}.
So instead of javac {directory}/{main-class}.java
Be sure to compile all of them at the same time, so there's no issue in cross-referencing:   javac {directory}/*.java
OP Specific
This would just be a silly command-line mistake. If it's occurring in IntelliJ as well, as you say, this isn't your issue. However, I hope it's at least helpful to the others who come across your question with this error!
Make sure each class is in the same folder, since the error is saying TapeDeckTestDrive can not find TapeDeck. I would recommend starting out with an IDE like Eclipse since it will help you focus more on coding and less with folder problems.
I know your code is all good (in java 8 at least) since when I copied it in eclipse it works no problem, meaning it has to be a folder problem, a problem with the installed version of java, or the way you are running the code is not working for some reason. If both files are in the exact same folder then I would make sure your java version says 1.8 something in the system files (Program Files(x86) most likely in windows), if it does not say that version then it could be another problem with the code and syntax for that version.
Another thing that might help is to put public behind the "class" on the first line of each class and make the Boolean public. This might be a syntax requirement on other versions of java or something that is needed when running off command prompt.
Quick possible fix, try making the classes and methods "Public".
Under normal circumstances this shouldn't be necessary but you may be hitting a specific case where it might be (It's an edge case so I don't know if it's a problem or not off the top of my head):
Java is really uncomfortable with stuff being in the "Default" package--code from other packages can't access objects in the default package (Meaning no package statement). Although this shouldn't cause problems in your case, maybe your "package" level security settings are also not working in the default package.
If this is actually the problem, the two fixes would be to make the packages and methods public (as I said above) or move both classes into a package.
What worked for me was to add the key word 'public' in both methods (playTape and recordPlay) and variables (canRecord).

How can I change classloader of getSystemJavaCompiler

I am dynamically compiling Java sources using the Java compiler API. My generated source files inherit from com.example.BaseClass, which is just a normal class, not dynamically generated. The generated Java sources look like this:
public class Foo implements com.example.BaseClass
{
#Override
public Integer getAnswer(com.example.Context context) throws Exception
{
return ...;
}
}
All works fine when running in IDE, but after packaging into a Springboot jar, my com.example.BaseClass is moved to BOOT-INF/classes/com.example.BaseClass. When dynamically compiling I now get:
/Foo.java:1: error: package com.example does not exist
public class Foo implements com.example.BaseClass
^
I try to change the classloader of the compiler so that the compiler will search in BOOT-INF/classes.
ClassLoader before = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(new CustomClassloader(before));
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
Thread.currentThread().setContextClassLoader(before);
However, debugging shows that my CustomClassloader.loadClass(String name) method is never called. More debugging showed that compiler.getClass().getClassloader() returns
java.net.FactoryURLClassLoader#39a5ae48
So, the CustomClassloader is not used by the Compiler instance. How can I get the Compiler to use my CustomClassloader? Better solutions for solving the compiling issue are also welcome ofcourse :-).
There are some oddities about how the java standard compiler does lookups and it doesn't always resolve out of the running class path correctly. Anyway, it does that resolution using the JavaFileManager.list call.
It will call it at least 4 times in the process of trying to look up your base class. Override a ForwardingJavaFileManager and pass that into getTask and have it lookup the resource and return it.
Alternately, you could use the Janino in-momeory compiler library which sets up a fake in memory file system ( no compiling to disk ) and still uses the plaform compiler and sorts out all this classpath nonsense for you.

GoogleApiAvailability.getErrorDialog() can't find string resource

I have this code:
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
String msg = getString(R.string.common_google_play_services_update_text);
Log.e(TAG, msg);
Dialog errDlg = googleAPI.getErrorDialog(MyActivity.this, result, 1111, listener);
When this runs, the String common_google_play_services_update_text is correctly written to LogCat, but getErrorDialog() throws this Exception:
java.lang.NoSuchFieldError: No static field
common_google_play_services_update_text of type I in class
Lcom/google/android/gms/R$string; or its superclasses (declaration of
'com.google.android.gms.R$string' appears in
/data/app/com.mygame-1/base.apk)
How can I fix this?
The error NoSuchFieldError means that the class doesn't have a field of a specified name. It is thrown if an application tries to access or modify a specified field of an object, and that object no longer has that field. Normally, this error is caught by the compiler and can only occur at run time if the definition of a class has incompatibly changed.
Also, maybe you've got old code that is referencing a field that no longer exists in the recompiled class files. You may check it here.
The solution is to clean out all the class files and compile everything from fresh.
Update: If you still get the same error after recompiling everything, then you're probably compiling against one version of an external library and using another at runtime.
What you need to do now is first identify the class that is causing the problem (it looks like you have done this already) and then run your application with the -verbose:class command line option. It will dump a lot of class loading information on your standard out and you'll be able to find out where the problematic class is exactly loaded from.
Hope this helps!

Scala trouble accessing Java methods

So, I have something written in Java, and I want to extend it in Scala... The issue I'm running into is that Scala isn't seeing methods I need.
Here is how it's set up:
Player extends Mob, and Mob extends Entity.
I need to access a method in Player that isn't defined in Mob or Entity, but Scala doesn't think it exists even though Java does.
It can see methods defined by Mob and Entity just fine. Also, all the methods I'm talking about are non-static.
So, am I doing something wrong, or is this a limitation imposed by Scala?
Edit --
Here is the relevant code:
package test
import rsca.gs.model.Player
object Test {
def handle(p:Player): Unit = {
p.getActionSender().sendTeleBubble(0, 0, false);
}
}
Player class:
package rsca.gs.model;
// imports
public final class Player extends Mob {
// Implemented methods (not going to post them, as there are quite a few)
// Relevant code
private MiscPacketBuilder actionSender;
public MiscPacketBuilder getActionSender() {
return actionSender;
}
}
Error:
value getActionSender is not a member of rsca.gs.model.Player
I never encountered such problems, and you probably checked your configuration and everything else twice, so I would guess this is some Eclipse related build issue. You should try to build from the command line in order to see whether Scala or Eclipse is the problem.
Is it possible for you to run a test against the class just to see if you got the right one?
p.getClass.getMethods
... and if possible (may run into NPE) in order to find the source:
p.getClass.getProtectionDomain.getCodeSource.getLocation.getPath
When compiling the Scala class, do something like this:
scalac *.scala *.java
This way, Scala will look a the Java code to see what is available. If, however, the Java code is already compiled and provided as a jar file, just add it to the classpath used when compiling the Scala code.

Problem in using org.apache.ddlutils.DdlUtilsException

I'm trying to use the org.apache.ddlutils package for reading database metadata.
I've written the following method:
public static void readMetaData(DataSource dataSource) throws DdlUtilsException{
final Platform platform = PlatformFactory.createNewPlatformInstance(dataSource);
}
But the statement throws DdlUtilsException gives the following error:
No exception of type DdlUtilsException can be thrown; an exception type must be a subclass of Throwable
I simply do not understand the reason behind this error because the API at http://db.apache.org/ddlutils/api/org/apache/ddlutils/DdlUtilsException.html clearly states the following:
java.lang.Object
extended by java.lang.Throwable
extended by java.lang.Exception
extended by java.lang.RuntimeException
extended by org.apache.commons.lang.exception.NestableRuntimeException
extended by org.apache.ddlutils.DdlUtilsException
Please advice.
My guess is that you've got another class called DdlUtilsException somewhere - possibly in the top-level package, given that the compiler isn't mentioning a full package name. If you're using Eclipse or something similar, try to navigate to the class declaration.
EDIT: Okay, judging by your comment, you aren't including the various dependencies. Make sure you've downloaded DdlUtils-1.0-bin.zip, and the dependencies are all in the lib directory. It's not immediately clear to me whether you need all of them, but you might as well use them all to start with, and then remove what you don't need.
It looks like that other class 'org.apache.commons.lang.exception.NestableRuntimeException' is located in commons-lang. Download and add that jar and it should work. Check the docs for DDL Utils and see what else it depends on.

Categories

Resources