IBM JDK一個詭異問題:java.lang.ClassFormatError

火星人 @ 2014-03-09 , reply:0


IBM JDK一個詭異問題:java.lang.ClassFormatError: JVMCFRE068 類名無效

這幾天碰到一個詭異的問題,在IBM JDK上二位數組中使用表達式時,出現http 500的錯誤.500是個內部錯誤,更web container有關,拿了客戶的日誌文件,發現異常如下,

<2009-7-23 上午05時01分47秒 CDT> <Error> <HTTP> <BEA-101017> <[weblogic.servlet.internal.WebAppServletContext@1aec462 - appName: 'test', name: 'test', context-path: '/test', spec-version: '2.5'] Root cause of ServletException. javax.servlet.ServletException: [HTTP:101249][weblogic.servlet.internal.WebAppServletContext@1aec462 - appName: 'test', name: 'test', context-path: '/test', spec-version: '2.5']: Servlet class jsp_servlet.__test for servlet /test.jsp could not be loaded because the requested class was not found in the classpath . java.lang.ClassFormatError: Illegal class name "[L[Ljava/lang/String;;" in class file jsp_servlet/__test.……

從具體的異常堆棧來看,應該是class載入時出現了問題,說是類名有問題,但同一context root下類名格式相同的其他page則可以訪問.如果去掉二位數組中的表達式,則可以解決這個問題.下面我們通過一個最簡單的例子來複現這個問題.

1:IBM JDK version

E:workspaceeclipse322src1030bin>java -version
java version "1.6.0"
Java(TM) SE Runtime Environment (build pwi3260sr2-20080818_01(SR2))
IBM J9 VM (build 2.4, J2RE 1.6.0 IBM J9 2.4 Windows XP x86-32 jvmwi3260-20080816
_22093 (JIT enabled, AOT enabled)
J9VM - 20080816_022093_lHdSMr
JIT - r9_20080721_1330ifx2
GC - 20080724_AA)
JCL - 20080808_02

2: __MatrixTest.java

1 package test.classload;
2
3 public class __MatrixTest {
4 public void initialize(){
5 String sResourcesPath = "";
6 String sCustomerScale = "123";
7 String sCustomerType = "123";
8 String teststr=((!sCustomerScale.equals("")&&sCustomerScale.substring(0,2).equals("02"))?"false":"true");
9 String sButtons[][] = {
10 {((!sCustomerScale.equals("")&&sCustomerScale.substring(0,2).equals("02"))?"false":"true"),
11 "","Button","新增","新增一條記錄","newRecord()",sResourcesPath},
12 //If above expression is replaced with 'teststr' like below, this issue could be solved.
13 //{teststr,"","Button","新增","新增一條記錄","newRecord()",sResourcesPath}
14 };
15 }
16 }
3: LoaderTest.java
1 package test.classload;
2
3 public class LoaderTest {
4
5 public static void main(String args[]){
6 try{
7 Class clazz = Class.forName("test.classload.__MatrixTest");
8 __MatrixTest test = (__MatrixTest)clazz.newInstance();
9
10 System.out.println("class is loaded");
11 }catch(Exception e){
12 e.printStackTrace();
13 }
14
15 }
16 }

4: 運行結果

這個程序在Sun JDK及BEA JRockit上運行的話,都沒有問題.而在IBM JDK1.6上運行的話,會出現如下的如下的異常,

E:workspaceeclipse322src1030bin>java test.classload.LoaderTest
Exception in thread "main" java.lang.ClassFormatError: JVMCFRE068 類名無效;類=test/classload/__MatrixTest,偏移量=0
at java.lang.ClassLoader.defineClassImpl(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:265)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:493)
at java.net.URLClassLoader.access$300(URLClassLoader.java:64)
at java.net.URLClassLoader$ClassFinder.run(URLClassLoader.java:892)
at java.security.AccessController.doPrivileged(AccessController.java:284
)
at java.net.URLClassLoader.findClass(URLClassLoader.java:414)
at java.lang.ClassLoader.loadClass(ClassLoader.java:643)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:300)
at java.lang.ClassLoader.loadClass(ClassLoader.java:609)
at java.lang.Class.forNameImpl(Native Method)
at java.lang.Class.forName(Class.java:136)
at test.classload.LoaderTest.main(LoaderTest.java:22)

這應該是JDK本身的問題,不知道二維數組中表達式怎麼會引發類名解析問題.目前我所知道的解決辦法只是把數組中的表達式挪到數組定義外面,就像__MaxtrixTest中所說的一樣.




[火星人 via ] IBM JDK一個詭異問題:java.lang.ClassFormatError已經有93次圍觀

http://www.coctec.com/docs/java/show-post-61171.html