My code is giving an error below;
Exception in thread "main" java.lang.NoSuchMethodError:
com/myApp/Client.cypherCBC(Ljava/lang/String;)Ljava/lang/String;
But it's working fine in an another local environment. My code so far is below;
try {
System.out.println("Encrypted CBC passwd : "
+ Client.cypherCBC("CypherThePassword"));
} catch (Exception e) {
e.printStackTrace();
}
This is due to a run-time JAR or class mismatch. the "Client" class which was there at the time you compile your application has a static method "cypherCBC" which gets String parameter, but at run-time class loader has loaded the "Client" class which doesn't have that kind of method (same name with same signature).
if you can debug the application at runtime, put a break-point at the line which exception was thrown, then try to evaluate following expression,
Client.class.getResource("Client.class")
, then you can find where the class has been leaded from, then you can decompile and try to troubleshoot the issue.
I got the same error while running a web application in Weblogic.
The reason for this error is there are two versions of classes are in the environment.To fix this you have to figure out which .class is using at the run time.
I used following to identify which class is loaded at run time.
-verbose:class
There is a duplicate class on your classpath.
So, That is why JVM is getting confused that which one needs to pick because both classes have a same method with a different signature that you are trying to call.
Related
I have a Java jar file, which is not executable(does not have a main method).
However I would like to invoke a particular class and its methods from my node.js application. I am currently using the below:
var child = require('child_process').spawn(
'java', ['-cp', "abc.jar", com.abc.ABCClass]
);
How now can I invoke the method in the ABCClass with appropriate arguments?
I currently get an exception such as below:
A JNI error has occurred, please check your installation and try again
Exception in thread "main"
Error: java.lang.NoClassDefFoundError:
org/apache/kafka/clients/consumer/KafkaConsumer
Thanks in advance. I am looking for a solution to call the method in that class.
I'm running drools project with Java. The line KnowledgeBase kbase = readKnowledgeBase(); gives the exception below:
java.lang.NoSuchMethodError: org.drools.util.CompositeClassLoader.clone()Lorg/drools/util/CompositeClassLoader;
at org.drools.compiler.PackageBuilderConfiguration.getClassLoader(PackageBuilderConfiguration.java:322)
at org.drools.rule.builder.dialect.java.JavaDialectConfiguration.setCompiler(JavaDialectConfiguration.java:91)
at org.drools.rule.builder.dialect.java.JavaDialectConfiguration.init(JavaDialectConfiguration.java:54)
at org.drools.compiler.PackageBuilderConfiguration.addDialect(PackageBuilderConfiguration.java:273)
at org.drools.compiler.PackageBuilderConfiguration.buildDialectConfigurationMap(PackageBuilderConfiguration.java:262)
at org.drools.compiler.PackageBuilderConfiguration.init(PackageBuilderConfiguration.java:175)
at org.drools.compiler.PackageBuilderConfiguration.<init>(PackageBuilderConfiguration.java:153)
at org.drools.compiler.PackageBuilder.<init>(PackageBuilder.java:254)
at org.drools.compiler.PackageBuilder.<init>(PackageBuilder.java:182)
at org.drools.builder.impl.KnowledgeBuilderFactoryServiceImpl.newKnowledgeBuilder(KnowledgeBuilderFactoryServiceImpl.java:34)
at org.drools.builder.KnowledgeBuilderFactory.newKnowledgeBuilder(KnowledgeBuilderFactory.java:47)
at com.sample.TestExample.readKnowledgeBase(TestExample.java:36)
at com.sample.TestExample.ProductClassHolder(TestExample.java:56)
at com.sample.TestExample.main(TestExample.java:30)
I had the same issue and struggled with it for a while. In my case the issue was due to the conflict of libraries drools-api.jar v5.1.1 and knowledge-api-5.4.0.Final.jar at runtime. Both of these libraries have class org.drools.util.CompositeClassLoader but the one in drools-api.jar doesn't have the clone() method and this was getting loaded at runtime. I removed drools-api.jar and now it is working fine and rules are also getting executed.
Summary: Loading a jar from a running Java program causes a NoClassDefFoundError caused by a ClassNotFoundException caused by inter-class dependencies (e.g. import statements). How can I get around it?
The problem in more detail:
I am attempting to programmatically load a jar file -- let's call it "Server" -- into the Java Virtual Machine through my own Java program -- let's call it "ServerAPI" -- and use extension and some other tricks to modify the behavior of and interact with Server. ServerAPI depends on Server, but if Server is not present, ServerAPI still has to be able to run and download Server from a website.
To avoid errors caused by ServerAPI loading without satisfying its dependencies from Server, I have made a launcher -- let's call it "Launcher" -- that is intended to download Server and set up ServerAPI as necessary, then load Server and ServerAPI, then run ServerAPI.
However, when I attempt to load jars from Launcher, I get errors caused because the ClassLoaders are unable to resolve the other classes in the file that the class it's loading depends on. In short, if I try to load Class A, it will throw an error if A imports B because I haven't loaded B yet. However, if B also imports A, I'm stuck because I can't figure out how to load two classes at once or how to load a class without the JVM running its validation.
Why all the restrictions have led me to this problem:
I am attempting to modify and add to the behavior of Server, but for complicated legal reasons, I cannot modify the program directly, so I have created ServerAPI that depends on and can tweak the behavior of Server from the outside.
However, for more complicated legal reasons, Server and ServerAPI cannot simply be downloaded together. Launcher (see above) has to be downloaded with ServerAPI, then Launcher needs to download Server. Finally, ServerAPI can be run using Server as a dependency. That's why this problem is so complex.
This problem will also apply to a later part of the project, which will involve a plugin-based API interface that needs to be able to load and unload plugins from jar files while running.
Research I have already done on this problem:
I have read through and failed to be helped by:
this question, which only addresses the issue of a single method and does not address inter-class dependency errors;
this question, which will not work because I cannot shut down and restart the program every time a jar is loaded or unloaded (mainly for the plugin part I briefly mentioned);
this question, which only works for situations where the dependencies are present when the program starts;
this question, which has the same problem as #2;
this question, which has the same problem as #3;
this article, from which I learned about the hidden loadClass(String, boolean) method, but trying with true and false values did not help;
this question, which has the same problem as #1;
and more. Nothing has worked.
//EDIT:
Attempts I have made so far:
I have tried using URLClassLoaders to load the jar using the JarEntries from the JarFile similar to this question. I tried this both by using and calling a URLClassLoader's loadClass(String) method and by making a class that extends URLClassLoader so that I could utilize loadClass(String, boolean resolve) to try to force the ClassLoader to resolve all the classes it loads. Both ways, I got this same error:
I couldn't find the class in the JarEntry!
entry name="org/apache/logging/log4j/core/appender/db/jpa/converter/ContextMapAttributeConverter.class"
class name="org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter"
java.lang.NoClassDefFoundError: javax/persistence/AttributeConverter
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at Corundum.launcher.CorundumClassLoader.load(CorundumClassLoader.java:52)
at Corundum.launcher.CorundumLauncher.main(CorundumLauncher.java:47)
Caused by: java.lang.ClassNotFoundException: javax.persistence.AttributeConverter
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 12 more
//END EDIT
//EDIT 2:
Here is a sample of the code that I used to load a class while trying to resolve it. This was inside a class that I made that extends URLClassLoader. On the line beginning with Class<?> clazz = loadClass(, I have tried using true and false as the boolean argument; both attempts resulted in the same error above.
public boolean load(ClassLoadAction class_action, FinishLoadAction end_action) {
// establish the jar associated with this ClassLoader as a JarFile
JarFile jar;
try {
jar = new JarFile(jar_path);
} catch (IOException exception) {
System.out.println("There was a problem loading the " + jar_path + "!");
exception.printStackTrace();
return false;
}
// load each class in the JarFile through its JarEntries
Enumeration<JarEntry> entries = jar.entries();
if (entries.hasMoreElements())
for (JarEntry entry = entries.nextElement(); entries.hasMoreElements(); entry = entries.nextElement())
if (!entry.isDirectory() && entry.getName().endsWith(".class"))
try {
/* this "true" in the line below is the whole reason this class is necessary; it makes the URLClassLoader this class extends "resolve" the class,
* meaning it also loads all the classes this class refers to */
Class<?> clazz = loadClass(entry.getName().substring(0, entry.getName().length() - 6).replaceAll("/", "."), true);
class_action.onClassLoad(this, jar, clazz, end_action);
} catch (ClassNotFoundException | NoClassDefFoundError exception) {
try {
close();
} catch (IOException exception2) {
System.out.println("There was a problem closing the URLClassLoader after the following " + exception2.getClass().getSimpleName() + "!");
exception.printStackTrace();
}
try {
jar.close();
} catch (IOException exception2) {
System.out.println("There was a problem closing the JarFile after the following ClassNotFoundException!");
exception.printStackTrace();
}
System.out.println("I couldn't find the class in the JarEntry!\nentry name=\"" + entry.getName() + "\"\nclass name=\""
+ entry.getName().substring(0, entry.getName().length() - 6).replaceAll("/", ".") + "\"");
exception.printStackTrace();
return false;
}
// once all the classes are loaded, close the ClassLoader and run the plugin's main class(es) load() method(s)
try {
jar.close();
} catch (IOException exception) {
System.out.println("I couldn't close the URLClassLoader used to load this jar file!\njar file=\"" + jar.getName() + "\"");
exception.printStackTrace();
return false;
}
end_action.onFinishLoad(this, null, class_action);
System.out.println("loaded " + jar_path);
// TODO TEST
try {
close();
} catch (IOException exception) {
System.out.println("I couldn't close the URLClassLoader used to load this jar file!\njar file=\"" + jar_path + "\"");
exception.printStackTrace();
return false;
}
return true;
}
//END EDIT 2
I realize that there must be a simple solution to this, but for the life of me I cannot seem to find it. Any help would make me eternally grateful. Thank you.
Embarassingly, I found that the answer was that the error message was telling the truth. javax.persistence.AttributeConverter, the class that the loader was claiming was not present, was not in the jar.
I fixed the issue by loading only the main class and the ClassLoader all references classes, essentially loading all the classes in the jar that are used in the program, which is all I need.
Now, I could have sworn that I checked for this before and found that class; I figure I must have actually checked the Apache open source repository for the class rather than the actual Server when I checked that. I can't remember.
In any case, AttributeConverter is missing. I don't know how or why they managed to compile a jar with missing dependencies, but I guess their main processes never use that part of the code, so it never threw errors.
I'm sorry to have wasted everyone's time...including my own. I have been stuck on this problem for a while now.
Moral of this story:
If you're trying to load an executable jar, don't bother loading all the classes in a jar unless you actually have to. Just load the main class; that will load everything the program needs to run.
//EDIT:
I have now started having the same error, but it does not appear until I attempt to call a method from a loaded class. The question is apparently still open. Please downvote and disregard this answer.
My DrJava was working fine, but now I keep getting the folowing error whenever I run anything:
Static Error: This class does not have a static void main method accepting String[].
So it will compile OK, but then it shoots out the error . This happens even though everything I test does indeed have a public static void main(String[] args) in it. It seems like a classpath/resources type of error. I appreciate any tips
EDIT: my class
public class Test{
public static void main(String[] args){
System.out.println(" hashmap ");
}
}
There's nothing wrong with the code, so the problem must be with the environment.
Check that you're actually executing that class. Find out where the class that's executed is specified and check it's correct
Check that you're compiling the class. Maybe the code you're looking at has not been compiled and you're trying to execute an old version that was compild before you coded a main()
Check your classpath. Is the compiled class accessible in the classpath of the java command
You don't need to reinstall java, nor is it a java version issue. It may be the way that your are running the program.
To check if it is a problem with your code, do the following:
Make a new folder and put Test.java in it.
Open up Command Line Or Terminal and change to that folder .
Type javac Test.java. Test.class should be in the folder now.
If you want, open up the class with a text editor. This is what I get:
˛∫æ2
<init>()VCodeLineNumberTablemain([Ljava/lang/String;)V
SourceFile Test.java hashmap Testjava/lang/Objectjava/lang/SystemoutLjava/io/PrintStream;java/io/PrintStreamprintln(Ljava/l ang/String;)V! *∑±
% ≤∂±
Back to the command line or terminal, type java Test.
If you get an error, which you shouldn't, I don't know what to say. It should produce the string " hashmap " on to the command line or terminal.
Why re-installing Dr. Java may not work is because you may be using the same working directory, causing same run settings to be used. Dr. Java may be running an external program, one without a main method.
I think that you should install the Eclipse IDE for Java. It is much easier to get around, it looks nicer, and it runs the file or project that you are looking at currently.
Sometimes this problem happens because may be mistake in saving file.you always your file using double quotes and with the .java extension which is main class means that class containing main method.
you should save your file by class name which is public .if there is two classes and both have main method then you should save your file by class name that is public and that class will be run.As like your compiler looking for main method in public static void main(String [] args) that is contract for jvm to run a programme
so it is not able to found that main method that is static and it looking for your Dr class.java
See this Example it have two main methods and practice these kinds of question.I also got this kind of problem in starting.
public class TestFirst
{
public static void main(String [] args){
System.out.println(" TestFirst ");
}
}
class Test{
public static void main(String [] args){
System.out.println(" hashmap ");
}
}
if you save pro-gramme by "TestFirst.java" then o/p will come TestFirst if you do some mistake in main method because we have saved our programme by TestFirst then you will get error like you got.
# 2nd mistake may be this
debian#debian:~/Geany_java$ javac Test1.java
debian#debian:~/Geany_java$ java Test1
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at Test1.main(Test1.java:11)
your classpath has not set properly See above Compiling successfully but running showing same kind of error you got.Which OS is using I can guide you properly.
Check that actually your file have the .java termination nor the .dj
There is nothing wrong with the code.
It is the executing environment which might have problem. Please share the details.
Check if program compiled correctly.
Check time-stamo of .class file.
Check permissions on folder/directory where class-files are getting generated.
Check if DrJAVA has appropriate permission on the directory.
Did you create a file, compiled it with out main?
Check class-path. Might be possible that previous class file is still being found by JDK in classpath.
Try compiling .java file from cmdLine instead of editor.
As others have mentioned, your code is fine. There must be a problem with your environment. I recently experienced a similar issue when investigating and answering this question.
Basically, in that question, the code Void.class instanceof Class resulted in a compiler error because a user-made Class.class existed in the classpath, so one Class (the Java built-in java.lang.Class) didn't match with the given Class (user-made).
Something similar may be at work here. It is possible that there is a user-made String.class in your classpath. Then in your main signature, String[] args would mean an array of your String, when Dr. Java must be looking for a main method taking an array of the Java built-in String, i.e. java.lang.String[]. If you have a custom String class in your classpath (or in your project?), then the Java compiler will choose it over the built-in String. If you were to compile and run your Test class from the command line, then you would get the runtime error: Exception in thread "main" java.lang.NoSuchMethodError: main.
Following #S0urceC0ded's suggestion, you may find this when looking at Test.class in a text editor:
main([LString;)V // A user-made String class
instead of what it's supposed to be:
main([Ljava/lang/String;)V // The built-in java.lang.String class
If so, remove your own String class (at least the .class file, but also the .java file so the .class file isn't re-created) from the classpath, and compile and run your Test class again.
Without a look at your environment, I can't tell for sure that this is the issue. But it can explain it.
If you are using Dr.Java as IDE, then you need to make sure that the main class containing 'public static void main' should be at the very top of your program. Otherwise Dr.Java throws this error during runtime.
I have a java program which is a compiler and executor for Jasper Reports and is called via shell script on our reports server.
I just fixed a bug caused by a missing dependancy, but it took me a while to figure out what was going wrong. Normally, problems caused by the compile process are captured, recorded to a log file and emailed to the relevant person. As this was a NoClassDefFoundError, it basically exited the program and failed in a silent manner from the users perspective.
Is there any way for me to capture errors like this one so that they can also be emailed away? I have the authority to modify the executing shell script.
Typically errors are not caught by application code and are thrown to JVM level where they are printed to STDERR. So, your way to track this error is to redirect STDERR to file:
java -cp YourMain 1>stdout.log 2>stderr.log
You can also put both STDOUT and STDERR together:
java -cp YourMain 1>&2 2>wholelog.log
There is a lot of reference about stream redirection in web. You can take a look there if my examples do not satisfy you. And it a depends on your OS.
Just can catch the error i.e.
try {
numericDefinition = new net.sf.cb2xml.def.BasicNumericDefinition(
binName, binarySizes, SynchronizeAt, usePositive, floatSynchronize, doubleSynchronize
);
} catch (NoClassDefFoundError e) {
System.out.println("Class Not Found: " + e.getMessage());
}
You do need to be very careful of your coding though, it is easy to get NoClassDefFoundError thrown at class initialisation time and not get into to the try .. catch block.
The NoClassDefFoundError will be thrown the first time a class is refereneced which could be when could when a class uses a class which uses a class which uses a class ... which uses a class that references a class that does not exist.
The following may fail with NoClassDefFoundError at class initialization because of the import.
import net.sf.cb2xml.def.BasicNumericDefinition; // could cause the NoClassDefFoundError
...........
try {
numericDefinition = new BasicNumericDefinition(
binName, binarySizes, SynchronizeAt, usePositive, floatSynchronize, doubleSynchronize
);
} catch (NoClassDefFoundError e) {
System.out.println("Class Not Found: " + e.getMessage());
}