ClassNotFoundException: Основной класс в файле JAR через сборку ANT - PullRequest
1 голос
/ 30 сентября 2011

В основном я пытаюсь запустить файл JAR, который я создал, используя ANT buildfile. Программа должна использовать внешний JAR для правильной компиляции. Я включил его в путь к классу манифеста JAR. При запуске он выплевывает трассировку стека, давая мне знать, что он не может найти основной класс.

Трассировка стека выглядит следующим образом:

        [java] java.lang.NoClassDefFoundError: $edu/gatech/oad/antlab/pkg1/AntLabMain
    [java] Caused by: java.lang.ClassNotFoundException: $edu.gatech.oad.antlab.pkg1.AntLabMain
    [java]  at java.net.URLClassLoader$1.run(Unknown Source)
    [java]  at java.security.AccessController.doPrivileged(Native Method)
    [java]  at java.net.URLClassLoader.findClass(Unknown Source)
    [java]  at java.lang.ClassLoader.loadClass(Unknown Source)
    [java]  at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    [java]  at java.lang.ClassLoader.loadClass(Unknown Source)
    [java] Could not find the main class: $edu.gatech.oad.antlab.pkg1.AntLabMain. Program will exit.
    [java] Exception in thread "main" 
    [java] Java Result: 1

Но когда я проверяю файл jar в папке \ edu \ gatech \ oad \ antlab \ pkg1, AntLabMain.class находится там. Странно.

Я включу исходный код XML ниже, если честно, я не уверен, что является причиной проблемы. Мое лучшее предположение - это что-то не так с тем, как я архивирую файлы, но я занимался этим часами без конца.

<project name="My Buildfile" default="all" basedir=".">
<target name="init" depends="prepare" description="Initialize and set up properties">
    <property name="src.dir" location="./src/" />
    <property name="build.dir" location="build" />
    <property name="library.dir" location="lib" />
    <property name="apidoc.dir" location="apidoc" />
</target>

<target name="prepare" description="Making required directories">
    <mkdir dir="build" />
    <mkdir dir="apidoc" />
</target>

<target name="compile" depends="init" description="Compiling necessary files">
    <javac destdir="${build.dir}" includeantruntime="first">
        <src path="${src.dir}" />
        <classpath>
            <pathelement path="${build.dir}" />
            <fileset dir="${library.dir}" includes="**/*.jar" />
        </classpath>
    </javac>
</target>

<target name="javadoc" depends="init" description="Generating useful javadocs">
    <javadoc sourcepath="${src.dir}" access="public" destdir="${apidoc.dir}">
        <fileset dir="${src.dir}">
            <include name="**/*.java" />
        </fileset>
        <classpath>
            <fileset dir="${library.dir}" includes="**/*.jar" />
         </classpath>
    </javadoc>
</target>

<target name="jar" depends="compile" description="JARing files for distribution">
    <jar destfile="${build.dir}/AntLabRun_Test.jar" basedir="${build.dir}" excludes="**/*.jar">
        <manifest>
            <attribute name="Main-Class" value="edu.gatech.oad.antlab.pkg1.AntLabMain" />
            <attribute name="Class-Path" value="${library.dir}\resources.jar" />
        </manifest>
    </jar>
</target>

<target name="run" depends="jar" description="Now running the program">
    <java jar="${build.dir}/AntLabRun_Test.jar" fork="true">
        <classpath>
            <fileset dir="${library.dir}" includes="**/*.jar" />        
        </classpath>
    </java>
</target>

<target name="all" depends="run" description="Doing EVERYTHING!">
</target>

<target name="clean" depends="init" description="Cleaning Directories">
    <delete dir="${build.dir}" />
    <delete dir="${apidoc.dir}" />
</target>

Наконец, я включу манифест, который поставляется вместе с JAR

Это мой первый удар по сборочным файлам Ant, поэтому я не очень разбираюсь в них. Надеюсь, я предоставил достаточно информации, чтобы начать игру.

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.6.0_21-b07 (Sun Microsystems Inc.)
Main-Class: edu.gatech.oad.antlab.pkg1.AntLabMain
Class-Path: C:\Users\Mike Sandt\workspace\M4\lib/resources.jar

Ответы [ 4 ]

1 голос
/ 30 сентября 2011

Оказывается, ответ был прост.Мне нужно было отредактировать мою цель инициализации, чтобы установить свойства в качестве значений, а не местоположений.

т.е.

<target name="init" depends="prepare" description="Initialize and set up properties">
    <property name="src.dir" location="./src/" />
    <property name="build.dir" value="build" />
    <property name="library.dir" value="lib" />
    <property name="apidoc.dir" value="apidoc" />
</target>

Спасибо всем за ваши ответы.

1 голос
/ 30 сентября 2011

Глядя на ваш файл манифеста, кажется, что у атрибута Main-Class есть дополнительный $ перед именем класса.Попробуйте удалить его, перекомпилировать jar и выполнить его снова.

Кроме того, если вы планируете запускать jar на других компьютерах, вы можете подумать об изменении атрибута Class-Path в файле манифеста на относительный путь..

0 голосов
/ 30 сентября 2011

Другие уже отметили проблему $ в имени класса.

Вопрос, есть ли в вашем классе AntLabMain статические инициализаторы, которые запускаются при загрузке класса? Если это так, и если один из этих инициализаторов завершится ошибкой, JVM сообщит, что класс AntLabMain не найден, поскольку он не смог его загрузить. Это действительно неправильная ошибка, но то, что вы увидите.

Так что, если у вас есть инициализация статики в классе, то убедитесь, что все это работает правильно.

0 голосов
/ 30 сентября 2011

В качестве крайней меры вы можете извлечь resources.jar в папку вашей сборки (вместо включения его в путь к классам) и сгенерировать файл jar снова (с файлами, извлеченными из resources.jar, включенными в него).

...