Android Error: java.lang.NoClassDefFoundError

转载:http://www.tuicool.com/articles/IVBVn2

原文  http://deepinmind.iteye.com/blog/2078286

当在静态初始化块中出现了异常的时候,JVM会抛出 java.lang.ExceptionInInitializerError异常。如果你了解Java中的静态变量,你会知道它们是在类加载的时候进行 初始化的。如果在这个静态变量初始化的过程中出现了异常,那么就会抛出 java.lang.ExceptionInInitializerError异常。任何异常都可能会引发这种情况,比如 说,java.lang.ArrayIndexOutOfBound或者java.lang.NullPointerException。Java开发人 员通常会被这个错误弄晕,他觉得自己并没有定义任何的静态初始化块,为什么还会抛出ExceptionInInitializerError异常;事实 上,Java默认会将静态变量的初始化放在一个默认的静态初始化块中,然后按它们在源文件中声明的顺序来进行初始化。比如说变量ABC声明在第一行,在第 二行中使用到了,而在第三行的时候才初始化,那么第二行的代码会抛出一个NullPointerException异常,这个异常会被封装到一个 ExceptionInInitializerError异常中,如果这段代码在主线程中执行了,你会看到控制台或者日志文件中出现这样的错误信息: "Exception in thread "main" java.lang.ExceptionInInitializerError"。在一个拥有大量日志文件的大型系统中,这样的错误很容易被忽略,而程序 员会得到一个java.lang.NoClassDefFoundError异常。不幸的是只有当别人使用到了这个类的时候才会出现这个错误,因为 ExceptionInInitializerError导致了这个类无法加载。由于类加载失败了,因此JVM会抛出 NoClassDefFoundError。有的时候这会误导Java开发人员,他们会检查类路径,PATH,以及java.library.path看 是不是缺少了这个类,却又发现不了任何问题,这让他们很困惑。如果你在分析NoClassDefFoundError的原因,你最好看下你的日志文件中有 没有ExceptionInInitializerError,然后再考虑要不要检查classpath。本文中我们将看到一段代码,它会在静态初始化过 程中引发异常从而导致 "Exception in thread "main" java.lang.ExceptionInInitializerError"。在稍后的部分,我们将会看到如何去解决这个问题。
Exception in thread "main" java.lang.ExceptionInInitializerError的原因

正如别的错误或者异常一样,当你看见这行信息,你知道这是出现ExceptionInInitializerError异常了,这个异常是由于类加载过程
中静态块初始化过程失败所导致的。由于它出现在负责启动程序的主线程中,因此你最好从主类中开始分析,这里说的主类是指你在命令行参数中指定的那个,或者
说是你声明了public static void main(String
args[])方法的那个类。如果你仔细地看一下完整的堆栈跟踪信息,你其实什么也不用做,因为JVM已经把类名给打印出来了,这就是引发
ExceptionInInitializerError的类。ExceptionInInitializerError是LinkageError的子
类,这意味着这个异常会导致你的类无法加载到JVM的内存中。现在我们来看一下这个示例程序,它在执行的时候会抛出下面的异常:

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.rangeCheck(ArrayList.java:635)
        at java.util.ArrayList.get(ArrayList.java:411)
        at StaticInitiazerDemo.<clinit>(StaticInitiazerDemo.java:15)

看一下栈跟踪信息,你知道真正的异常是java.lang.IndexOutOfBoundsException,它在 StaticInitiazerDemo的第二行被抛出来了。这是由于你调用了ArrayList的get()方法并传入了位置0,而这个 ArrayList的大小也是0(Index: 0, Size: 0)。看到这条信息后你知道当我们想从列表中取出第一张CreditCard时,这个列表是空的。

import java.util.ArrayList;
import java.util.List;

/**
 * Java Program to understand and solve ExceptionInitializerError, which comes
 * When static initializer blocks throws unchecked exception during class loading
 * and initialization.
 *
 * @author Javin Paul
 */

public class StaticInitializerDemo{

  private static final List<CreditCard> cards = new ArrayList<CreditCard>();
  private static CreditCard prefferdCard = cards.get(0); // 1st card is default
  public static boolean isVisa = "VISA".equalsIgnoreCase(prefferdCard.getNetwork());

  public static void main(String args[]) {

    makePayment(prefferdCard);

  }

  public static void makePayment(CreditCard cc) {
    if (isVisa) {
      //offer 5% discount
    }
    // deduct payment
  }

}

class CreditCard {

  private long card_number; //16 digit card number
  private int cvv; // 3 digit cvv number
  private int expiryMonth;
  private int expiryYear;
  private String bank;
  private String network;

  public CreditCard(long card_number, int cvv, int expiryMonth, int expiryYear, String bank, String network) {
    super();
    this.card_number = card_number;
    this.cvv = cvv;
    this.expiryMonth = expiryMonth;
    this.expiryYear = expiryYear;
    this.bank = bank;
    this.network = network;

  }

  /**
   * @return the card_number
   */
  public final long getCard_number() {
    return card_number;
  }
  /**
   * @return the cvv
   */
  public final int getCvv() {
    return cvv;
  }
  /**
   * @return the expiryMonth
   */
  public final int getExpiryMonth() {
    return expiryMonth;
  }
  /**
   * @return the expiryYear
   */
  public final int getExpiryYear() {
    return expiryYear;
  }
  /**
   * @return the bank
   */
  public final String getBank() {
    return bank;
  }
  /**
   * @return the network
   */
  public final String getNetwork() {
    return network;
  }
}

输出:

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.get(Unknown Source)
    at StaticInitializerDemo.<clinit>(StaticInitializerDemo.java:15)

这里是Java中所有Error类的类结构。你可以看到ExceptionInInitializerError是继承自LinkageError的。还 应当知道的是,像RuntimeException一样,Error也是未检查异常,编译器是不去检查有没有相应的异常处理代码的。
<img src=“http://t2.qpic.cn/mblogpic/ca5522151fdd6cb9d70c/2000”/>
如何解决Exception in thread "main" java.lang.ExceptionInInitializerError

需要记住以下几点:
1. "Exception in thread "main"
java.lang.ExceptionInInitializerError"意味着异常出现在主线程,并且是LinkageError的一个子类
java.lang.ExceptionInInitializerError,这是JVM类加载失败时才抛出的,原因是静态初始化代码中出现了诸如
IndexOutOfBoundsException或者NullPointerException这样的RuntimeException。
2.
记住JVM会将所有的静态变量的初始化按它们在源文件中的出现顺序放到一个静态初始化块中。因此,不要觉得没有看到静态初始块就认为不会出现这个异常。事
实上,你得确保静态变量的正确顺序,比如说,如果 一个变量初始化的时候用到了另一个变量,你得确保这个变量在前面已经初始化过了。
3.
如果别的代码想要使用这个类,则会抛出ExceptionInInitializerError异常,而它又会导致
ClassNotFoundException或者NoClassDefFoundError。为什么?因为这个类加载失败了,并没有加载到JVM的内存
中。因此如果你在解决类不存在之类的异常时,先看看你的日志文件中有没有这个异常。
4. 记住静态初始化代码块会抛出RuntimeException而不是已检查异常,而后者需要有对应的catch块来进行处理。
这就是关于Exception in thread "main"
java.lang.ExceptionInInitializerError的所有东西了。你已经了解到了如何去跟踪此类问题,并找出抛出这个异常的罪
魁祸首。需要谨记的是这个异常的一个副作用是NoClassDefFoundError,而Java程序抛出这个异常的位置可能会离
java.lang.ExceptionInInitializerError很远,这取决于你的客户端代码何时引用到这个类。因此,在查看类路径解决
NoClassDefFoundError异常之前,最好先看看日志有没有出现ExceptionInInitializerError。

时间: 2024-10-11 01:41:50

Android Error: java.lang.NoClassDefFoundError的相关文章

Error &quot;java.lang.NoClassDefFoundError:org/openxmlformats/schemas/spreadsheetml/x2006/main/CTExtensionList&quot; in SoapUI

After upgrade readyAPI 1.9 to the higher version, pop up error "java.lang.NoClassDefFoundError:org/openxmlformats/schemas/spreadsheetml/x2006/main/CTExtensionList". solution: replace "poi-ooxml-schemas-3.12.jar" with "ooxml-schema

Hadoop build error java.lang.NoClassDefFoundError: org/sonatype/aether/graph/DependencyFilter

When running the command: + mvn site site:stage -DskipTests -DskipTest -DskipITs you get an error: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-site-plugin:3.0:site (default-site) on project hadoop-main: Execution default-site of goa

(转)Android工程出现 java.lang.NoClassDefFoundError错误解决方法

在Eclipse中,导入Android工程,工程没有报错,运行时,出现 java.lang.NoClassDefFoundError类没有找到的错误.从问题上可以看出是导入包出错的原因.遂百度加谷歌. 问题出在:ADT高版本的原因 把引入的第三方包放在Referenced Libraries中,ADT升级到17后就出现了Android Dependencies,所以如果程序中引入的第三方包没有在Android Dependencies中时,就会报文章开头的错. 解决方法: 先移除之前的Refer

很急!!! java.lang.NoClassDefFoundError: com.android.volley.toolbox.Volley

============问题描述============ 日志文件如下,不知道是什么原因报如下错误 08-01 16:33:35.001: E/AndroidRuntime(31240): FATAL EXCEPTION: main 08-01 16:33:35.001: E/AndroidRuntime(31240): Process: cn.phonecms.main, PID: 31240 08-01 16:33:35.001: E/AndroidRuntime(31240): java.

Android java.lang.NoClassDefFoundError的错误

在开发过程中,遇到一个这样的问题:java.lang.NoClassDefFoundError: android.support.v4.util.SparseArrayCompat,这个问题很奇怪,JAR包也有了,编译也通过了.但就是运行时出现类找不到的问题.NoClassDefFoundError这种错误一般就是对应的类,没有被包含在对应的APK里面.是不是对应的android-support-v4.jar并没有打包到apk中?抱着试一试的态度,打开工程属性设置界面: 把前面的勾选中,再cle

Eclipse中使用recyclerview时出现Caused by: java.lang.NoClassDefFoundError: android.support.v7.recyclerview.R$styleable

转自: http://blog.csdn.net/chenleicpp/article/details/46848785 程序崩溃,错误提示: Caused by: java.lang.NoClassDefFoundError: android.support.v7.recyclerview.R$styleable 原因: 在eclipse中使用RecyclerView,编译没有问题,但是运行时候会出现如下错误,百思不得其解,又说v4包与v7包版本不一致,有说没有导入v7-compat包的,经反

Android 编程下 java.lang.NoClassDefFoundError: cn.jpush.android.api.JPushInterface 报错

使用了极光推送的 jar 包项目在从 SVN 中检出后,假设不又一次对 jar 包和 Bulid Path 进行配置就会抛出 java.lang.NoClassDefFoundError: cn.jpush.android.api.JPushInterface 的错误,进行例如以下操作就可以消除这样的错误: 删除 libs 目录下的 jpush-sdk-release1.3.8.jar(极光推送的 jar 包),又一次在 libs 目录中增加  jpush-sdk-release1.3.8.ja

Android程序 依赖库引用Gson 报java.lang.NoClassDefFoundError: com/google/gson/Gson 解决方法

Android 程序所依赖一个Library程序B , B 程序中用到格式化json串,转换成标准json串的要求 public static String jsonFormatter(String uglyJSONString) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); JsonParser jp = new JsonParser(); JsonElement je = jp.parse(uglyJSONStri

【转】Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解决办法)

原文网址:http://www.blogjava.net/anchor110/articles/355699.html 1.在工程下新建lib文件夹,将需要的第三方包拷贝进来.2.将引用的第三方包,添加进工作的build path.3.(关键的一步)将lib设为源文件夹.如果不设置,则程序编译可以通过,但运行的时候,会报: java.lang.NoClassDefFoundError # re: Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundErro