我在res/lib
文件夹中有一个第三方.jar
文件。ANT build.xml
看起来像这样:
<?xml version="1.0"?>
<project name="my.project" basedir="." default="build">
<property name="src.dir" value="src"/>
<property name="build.dir" value="build/classes"/>
<path id="master-classpath">
<fileset dir="res/lib">
<include name="*.jar"/>
</fileset>
<pathelement path="${build.dir}"/>
</path>
<target name="build">
<mkdir dir="${build.dir}"/>
<javac destdir="${build.dir}" optimize="true">
<src path="${src.dir}"/>
<classpath refid="master-classpath"/>
</javac>
</target>
</project>
.java
文件如下:
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;
public class IO {
public static void readCSVFile(File file) throws IOException {
FileReader in = new FileReader(file);
Iterable<CSVRecord> record = CSVFormat.DEFAULT.parse(in);
}
}
编译是好的,但我得到了一个运行时错误:java.lang.NoClassDefFoundError: org/apache/commons/csv/CSVFormat
。我认为类路径有问题,但对我来说似乎没有问题。
如果我使用java -cp path;. Main
,它正在运行。我试着写一个ANT脚本来运行它:
<target name="run">
<java classname="Main">
<classpath refid="master-classpath"/>
</java>
</target>
我在命令行中写ant run
,我得到BUILD SUCCESSFUL
,什么也没发生。
您的构建文件编译您的代码,并在类路径中包含第三方Jar,以便编译器能够定位您的代码所依赖的类(例如org.apache.commons.csv.CSVRecord
)。
java
运行主类时,JVM需要知道第三方类存在的位置。否则,类加载器将无法加载这些类。所以在你的例子中,你仍然应该像下面这样调用主类:
java -cp pathtoyourlib;. Main
换句话说,这是两个不同的"类路径"概念:一个类路径由编译器使用,以知道在每个要编译的类中找到每个引用的类的位置,而另一个类路径由JVM使用,以知道在动态调用类时在哪里加载类。
您声明编译正常,但是您没有显示如何运行java程序.....所以要清楚,ANT完成无误吗?这是从命令行运行java程序后编译的问题?
如果我是正确的,那么有两个问题:
- 你的java程序没有主类(需要从命令行运行)
- 当运行java程序时,程序所依赖的jar文件将包含在类路径中。
你的类没有(可见的)主方法
public static void main(String[] args){
IO.readCSVFile(File file)
}
在运行
文件时需要传递类路径java -cp yourclasspath