在用 Ant 编译的文件中找不到主类 [英] Cannot find Main Class in File Compiled With Ant

查看:24
本文介绍了在用 Ant 编译的文件中找不到主类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Eclipse 中编译并运行我的程序,一切正常,但是当我用 Ant 打包并运行它时,出现此错误:

I compile and run my program in Eclipse and everything works fine, but when I package it with Ant and run it, I get this error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/supercsv/io/ICsvB
eanReader
Caused by: java.lang.ClassNotFoundException: org.supercsv.io.ICsvBeanReader
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: jab.jm.main.Test. Program will exit.

请注意,这是一个运行时错误,而不是 Ant 的编译器错误.

Note that this is a runtime error and not a compiler error with Ant.

我过去用 0 个问题构建了这个项目,现在 当我将第二个包添加到我的 lib 文件夹时它突然对我起作用?

I've built this project in the past with 0 issues and now it suddenly acts up on me when I add a second package to my lib folder?

这是供参考的构建文件:

Here's the build file for reference:

<?xml version="1.0" ?>

<project name="ServerJar" default="dist" basedir=".">
 <description>
  Builds client files into .jar
 </description>
 <!-- [build variables] -->
 <property name="src" location="src" />
 <property name="build" location="build" />
 <property name="dist" location="dist" />
 <property name="lib" location="lib" />
 <!-- [path to packages] -->
 <path id="master-classpath">
     <fileset dir="${lib}">
         <include name="*.jar"/>
     </fileset>
 </path>


 <target name="init">
  <!-- makes time stamp to be used in jar name -->
  <tstamp />
  <!-- creates build directory structure -->
  <mkdir dir="${build}" />
 </target>

 <target name="compile" depends="init" description="Compiles the source">
  <!-- compiles the java code from ${src} into ${build} -->
  <!-- <javac srcdir="${src}" destdir="${build}" /> -->
  <javac destdir= "${build}">
      <src path="${src}"/>
      <classpath refid="master-classpath"/>
  </javac>
 </target>

 <target name="dist" depends="compile" description="Generates distributable">
  <!-- creates the distribution directory -->
  <mkdir dir="${dist}/lib" />

  <!-- puts everything in ${build} into the jar file -->
  <jar jarfile="${dist}/lib/CC-${DSTAMP}.jar" basedir="${build}">
   <manifest>
    <attribute name="Main-Class" value="jab.jm.main.Test" />
   </manifest>
  </jar>

  <!-- makes a jar file for quick test execution -->
  <jar jarfile="${dist}/lib/CC.jar" basedir="${build}">
   <manifest>
    <attribute name="Main-Class" value="jab.jm.main.Test" />
   </manifest>
  </jar>
 </target>

 <target name="clean" description="Cleans up the extra build files">
  <!-- deletes the ${build} and ${dist} directories -->
  <delete dir="${build}" />
  <delete dir="${dist}" />
 </target>
</project>

预先感谢您的帮助!

以下是我的主类的构造(这不是实际文件,但这是我基于的文件).Java 程序的构造非常奇怪,可能会给 Ant 带来一些问题.关于如何重建这个的任何建议?尝试将其分成多个部分时,我遇到了一堆错误.我以前从未见过这样的结构(是的,我了解它是如何工作的(编译时也是如此),但 Ant 可能不喜欢它).

Here's what the construction for my main class looks like (this is not the actual file, but this is what I based mine on). The construction is very odd for a java program and might be giving Ant some issues. Any recommendations on how to reconstruct this? I got a bunch of errors when trying to separate this into multiple parts. I've just never seen a construction like this before (yes, I understand HOW it works (and it does when compiled), but Ant might not like it).

import java.io.FileReader;
import java.io.IOException;

import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.ParseDate;
import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.constraint.StrMinMax;
import org.supercsv.cellprocessor.constraint.Unique;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;

class ReadingObjects {
    static final CellProcessor[] userProcessors = new CellProcessor[] {
        new Unique(new StrMinMax(5, 20)),
        new StrMinMax(8, 35),
        new ParseDate("dd/MM/yyyy"),
        new Optional(new ParseInt()),
        null
    };

    public static void main(String[] args) throws Exception {
        ICsvBeanReader inFile = new CsvBeanReader(new FileReader("foo.csv"), CsvPreference.EXCEL_PREFERENCE);
        try {
          final String[] header = inFile.getCSVHeader(true);
          UserBean user;
          while( (user = inFile.read(UserBean.class, header, userProcessors)) != null) {
            System.out.println(user.getZip());
          }
        } finally {
          inFile.close();
        }
   }
}

public class UserBean {
    String username, password, town;
    Date date;
    int zip;

    public Date getDate() {
        return date;
    }
    public String getPassword() {
        return password;
    }
    public String getTown() {
        return town;
    }
    public String getUsername() {
        return username;
    }
    public int getZip() {
        return zip;
    }
    public void setDate(final Date date) {
        this.date = date;
    }
    public void setPassword(final String password) {
        this.password = password;
    }

    public void setTown(final String town) {
        this.town = town;
    }
    public void setUsername(final String username) {
        this.username = username;
    }
    public void setZip(final int zip) {
        this.zip = zip;
    }
}

注意该类的名称实际上是 UserBean 并且它包含一个名为 ReadingObjects 的非公共类,其中包含 main 方法.

Notice how the class's name is actually UserBean and it contains a non-public class named ReadingObjects within it that holds the main method.

推荐答案

看起来您的运行时类路径缺少包含 org.supercsv.io.ICsvBeanReader 类的 jar.

Looks like your runtime classpath is missing the jar containing the class org.supercsv.io.ICsvBeanReader.

问题 是在调用可执行 jar 时不能从命令行设置类路径.您必须在清单中进行如下设置:

The gotcha is that you cannot set the classpath from the command-line when calling an executable jar. You have to set it within the manifest as follows:

<target name="dist" depends="compile" description="Generates distributable">
    <!-- creates the distribution directory -->
    <mkdir dir="${dist}/lib" />

    <!-- Remove manifest. This jar will end up on the classpath of CC.jar -->
    <jar jarfile="${dist}/lib/CC-${DSTAMP}.jar" basedir="${build}"/>

    <!-- Fancy task that takes the pain out creating properly formatted manifest value -->
    <manifestclasspath property="mf.classpath" jarfile="${dist}/lib/CC.jar">
        <classpath>
            <fileset dir="${dist}/lib" includes="*.jar"/>
        </classpath><!--end tag-->
    </manifestclasspath>

    <!-- This is the executable jar -->
    <jar jarfile="${dist}/lib/CC.jar" basedir="${build}">
        <manifest>
            <attribute name="Main-Class" value="jab.jm.main.Test"/>
            <attribute name="Class-Path" value="${mf.classpath}"/> 
        </manifest>
    </jar>

</target>

此方法将允许您按如下方式运行 jar:

This approach will allow you to run the jar as follows:

java -jar CC.jar

如果没有额外的清单条目,您必须按如下方式运行 jar:

Without the extra manifest entry you have to run the jar as follows:

java -cp CC.jar:CC-DSTAMPVALUE.jar jab.jm.main.Test

注意

只有 CC.jar 是可执行的并且需要特殊的清单.使用此模式意味着将来放置在 lib 目录中的其他 jar 将自动包含在运行时类路径中.(对于像 log4j 这样的开源依赖很有用)

Note

Only the CC.jar is executable and needs the special manifest. Using this pattern means future additional jars, placed into the lib directory, will be automatically included in the run-time classpath. (Useful for open source dependencies like log4j)

显然,在运行 CC.jar 时,如果 jar 文件不存在,您将收到类似的错误:-)

Obviously, when running the CC.jar you'll get a similar error if the jar files are not present :-)

这篇关于在用 Ant 编译的文件中找不到主类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆