Dear reader,
I am explaining a very good topic here on Java. You may be aware about this error
"java.lang.NoSuchMethodError" which comes while developing java applications.
The reason to write this tiny topic in my blog is because we have faced a major issue in production
because of this. We have deployed a Hotfix (a JAR) in production which has dependency on another jar.
The Hotfix was taken from a QA/Testing env where the Method Signature was different than production
(I have explained below) and since there were no compilation issues, we deployed the hotfix in
production which caused problem after deployment at runtime.
We noticed this after 1 day and you know: Shit happens as again Re-deploying in production for
same issue will cause a trust deficit between client and Developer organization and necessary
Approvals for production RESTART makes things worse...
Here is the below simple explanation of code failure:
I am writing two SIMPLE java classes, one is having main method calling other's method.
----------------------------------
//Topup.java
public class Topup {
public static void main(String[] args) {
Nokia nk=new Nokia(); //See this class below
System.out.println("Before");
nk.reverse();
System.out.println("After");
}
}
-----------------------------------
//Nokia.java (NOTE: Note the return type of reverse() method in below class)
public class Nokia {
public void reverse(){ //void return type
System.out.println("Nokia before, with Void return type.");
}
}
-----------------------------------
//Compile these two files, both are in the same directory
javac Nokia.java
javac Topup.java
//Now run the main file
java Topup
//Output:
Before
Nokia before, with Void return type.
After
--------------------------------------------------
Now change the Nokia.java like this (NOTE: Note the return type of reverse() method in below class):
public class Nokia {
public String reverse(){ //String return type
String ret="Old reverse";
System.out.println("Nokia before, with String return type");
return ret;
}
}
--------------------------------------------------
Now again compile only Nokia.java, so that Nokia.class gets replaced with new one.
Now run again Topup.java
[dmodi@nbodevapp1 Confusion]$ javac Nokia.java
[dmodi@nbodevapp1 Confusion]$ java Topup
Before
Exception in thread "Main Thread" java.lang.NoSuchMethodError: reverse
at Topup.main(Topup.java:5)
[dmodi@nbodevapp1 Confusion]$
!!!!!!!!!!!!!!You see exception here, please note there is no compilation issues,if you open this code
base in MyEclipse. As in java calling a method with any return type doesn't make any sense if you
don't require the returned value.
!!!!!!!!!!!!!!It means next time onwards if you do any hotfix, deployment into production,
make sure the Other supporting jars are not modified in TESTING env compare to Production,
else you will face the same big issue, what we have faced.
----------------------------------------------------
HOW to Confirm that the Hotfix Jar (Particular class or classes) are compiled with Other Method signatures
rather than expected:
For this, there is a command in JAVA: javap -verbose. Here is example:
In Previous case (Topup, compiled with void reverse() in Nokia.java)
============
[dmodi@nbodevapp1 Confusion]$ javap -verbose Topup
Compiled from "Topup.java"
public class Topup extends java.lang.Object
SourceFile: "Topup.java"
minor version: 0
major version: 49
Constant pool:
const #5 = String #23; // Before
const #6 = Method #24.#25; // java/io/PrintStream.println:(Ljava/lang/String;)V
const #7 = Method #2.#26; // Nokia.reverse:()V
const #8 = String #27; // After
const #12 = Asciz ()V;
const #26 = NameAndType #36:#12;// reverse:()V
const #27 = Asciz After;
17: invokevirtual #7; //Method Nokia.reverse:()V
23: ldc #8; //String After
25: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
28: return
========================In Modified case (Topup, compiled with String reverse() in Nokia.java)
[dmodi@nbodevapp1 Confusion]$ javap -verbose Topup
Compiled from "Topup.java"
public class Topup extends java.lang.Object
SourceFile: "Topup.java"
minor version: 0
major version: 49
const #5 = String #23; // Before
const #6 = Method #24.#25; // java/io/PrintStream.println:(Ljava/lang/String;)V
const #7 = Method #2.#26; // Nokia.reverse:()Ljava/lang/String;
const #8 = String #27; // After
const #26 = NameAndType #36:#37;// reverse:()Ljava/lang/String;
const #27 = Asciz After;
const #36 = Asciz reverse;
const #37 = Asciz ()Ljava/lang/String;;
11: ldc #5; //String Before
17: invokevirtual #7; //Method Nokia.reverse:()Ljava/lang/String;
24: ldc #8; //String After
29: return
============================================================
Please see the difference, you will notice JAVA says that Topup.java is compiled with what type of
method signatures (reverse()) in Nokia.java
========================================End=======================================
Friday, November 11, 2011
Error: "java.lang.NoSuchMethodError"
Subscribe to:
Post Comments (Atom)
nice topic
ReplyDelete