来自使用其他库的库的ClassNotFoundException

时间:2014-04-30 20:22:34

标签: java

问题概述:我在CSVFile项目中有一个Utils类,它在内部使用openCSV的CSVReader来加载csv文件。

现在我创建了一个名为MyTester的新项目,并在其类路径中添加了Utils,目的是使用CSVFile来处理csv文件。

这是迄今为止的样子

MyTester
  src
    Tester.java

Utils
  src
    CSVFile.java
  lib
    opencsv.jar

实例化CSV文件并传入文件路径只需加载csv文件:

import au.com.bytecode.opencsv.CSVReader;

public class CSVFile {

    public CSVFile(String filename) {
       CSVReader reader = new CSVReader( ... );
       // read CSV file
    }
}

这很好用。

所以现在我想在一个单独的项目中加载一个csv文件。我使用CSVFile就是为了它的目的。

import CSVFile;

class Tester {
    public static void main(String[] args) {
       CSVFile reader = new CSVFile("test.csv");
    }
}

当我运行Tester时,我会在寻找ClassNotFoundException时获得CSVReader。 stacktrace的顶部指向CSVFile构造函数中的行,所以至少我的代码正在做我期望它做的事情。

我熟悉类路径相关的问题,我忘记添加一个必需的jar,所以当我将所需的jar添加到MyTester项目时,它会按预期工作。

但我不明白为什么我需要这样做。

如果我使用第三方库中定义的类或方法,我不应该对其实现有任何了解。但是在此示例中,我的Tester课程需要opencsv.jar,这对我来说没有意义。可能导致问题的原因是什么?

1 个答案:

答案 0 :(得分:1)

  

如果我使用第三方库中定义的类或方法,我不必知道它的实现。

使用第三方库编译代码时(在大多数情况下) - 如果我的项目A依赖于B.jar,这是由项目提供的,而该项目又具有依赖性在C.jar上,我通常不需要在我的类路径上使用C.jar来编译项目A.

在运行时,它是一个不同的故事。我的项目A中的一些代码第一次访问B.jar中的类中的方法时,JVM将从B.jar加载该类的字节码,初始化该类,然后继续执行相关方法。类似地,如果在从项目B执行方法的过程中,有一个方法调用C.jar中定义的类,JVM也会加载该字节码。因此,C.jar需要在运行时在您的类路径上,但不一定在编译时。

这就是Maven等工具如此受欢迎的原因 - 它们处理传递项目依赖关系,并根据项目依赖项的声明性描述自动为您设置类路径。