2012-03-26 49 views
7

我看着this question,但它並沒有真正解決我的問題,所以我想我會發佈一個新的。如何使用Ant創建一個捆綁的可運行jar包

我需要使用Ant創建一個可運行jar(只需通過雙擊可運行)。我有下面的java代碼和build.xml文件,編譯代碼就好了,並創建了一個jar文件,但是當我嘗試通過雙擊運行jar時,我收到一條消息:「找不到主類:HttpController。 java的「。

我懷疑我的問題與加載外部Apache Http.jar有關,因爲我已經成功構建並運行一個相同項目的jar,只是它沒有引用任何外部jar。

這裏是我的代碼:

HttpController.java:

package pack; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpHost; 
import org.apache.http.HttpMessage; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 

public class HttpController { 
     public static void main(String[] args) { 

     DefaultHttpClient client = new DefaultHttpClient(); 
     HttpHost httphost = new HttpHost("localhost", 80); 

     try { 

      HttpMessage req = new HttpGet("/test.html"); 
      HttpResponse resp = client.execute(httphost, (HttpGet) req); 
      HttpEntity entity = resp.getEntity(); 

      BufferedReader in = new BufferedReader(new InputStreamReader(
        entity.getContent())); 

      String line = null; 
      while ((line = in.readLine()) != null) { 
       System.out.println(line); 
      } 

     } catch (ClientProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      // shutdown the connection 
      client.getConnectionManager().shutdown(); 
     } 
    } 
} 

的build.xml:

<?xml version="1.0" encoding="ISO-8859-1"?> 
    <project name="Test" basedir="." default="jar"> 
    <property name="source.dir"  value="src"/> 
    <property name="lib.dir"  value="lib"/> 
    <property name="class.dir"  value="bin"/> 
    <property name="jar.dir"  value="dist"/> 
    <property name="main-class"  value="pack.HttpController"/> 

    <path id="libraries.path">  
     <fileset dir="${lib.dir}"> 
      <include name="*.jar"/> 
     </fileset> 
    </path> 

    <target name="clean" description="delete old files"> 
     <delete dir="${class.dir}"/> 
     <delete dir="${jar.dir}"/> 
    </target> 

    <target name="compile" description="build class files" depends="clean"> 
     <mkdir dir="${class.dir}"/> 
     <javac srcdir="${source.dir}" destdir="${class.dir}"> 
      <classpath refid="libraries.path"/> 
     </javac> 
    </target> 

    <target name="jar" depends="compile"> 
     <mkdir dir="${jar.dir}"/> 
     <mkdir dir="${jar.dir}/${lib.dir}"/> 
     <copy todir="${jar.dir}/${lib.dir}" flatten="true"> 
      <path refid="libraries.path"/> 
     </copy> 
     <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${class.dir}"> 
      <manifest> 
       <attribute name="Main-Class" value="${main-class}"/> 
       <attribute name="Class-Path" value="${jar.dir}/${lib.dir}/Apache HTTP.jar"/> 
      </manifest> 
     </jar> 
    </target> 

    <target name="run" depends="jar"> 
     <java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/> 
    </target> 
</project> 

MANIFEST.MF:

Manifest-Version: 1.0 
Ant-Version: Apache Ant 1.8.3 
Created-By: 1.6.0_31-b05 (Sun Microsystems Inc.) 
Main-Class: HttpController 
Class-Path: dist/lib 

編輯 build.xml已根據Mike的回答進行了更新。問題仍然沒有解決。根據Danation的回答,還張貼了清單文件的內容。

+0

@ see http://one-jar.sourceforge.net/index.php?page=build-tools&file=ant-example。 – Jayan 2012-03-26 16:49:42

+0

@jayan是否可以在沒有任何外部工具的情況下執行此操作?即只使用Ant並編寫我自己的build.xml文件? – ewok 2012-03-26 16:52:42

+0

有關於使用eclipse創建可運行jar的問題/答案等。請參閱http://stackoverflow.com/questions/502960/eclipse-how-to-build-an-executable-jar-with-external-jar。我更喜歡一個jar文件,因爲它創建了一個可運行的文件。加入螞蟻應該花10分鐘。那麼爲什麼不試試看結果呢? – Jayan 2012-03-26 17:00:06

回答

0

看看你的清單文件,這很可能是一個問題。我只在清單文件不正確時纔看到該錯誤。

只是猜測,但我認爲它試圖運行一個「.java」文件,因爲它是主要的類,這是不會工作。

請參閱oracle教程:http://docs.oracle.com/javase/tutorial/deployment/jar/appman.html

如果這樣做完全沒有幫助,請在原始問題中發佈清單文件的內容以及.jar文件的目錄結構。

+0

我知道清單文件存在問題,但我需要知道如何重新配置​​build.xml,以便ant能夠正確生成它。 – ewok 2012-03-26 15:45:50

+1

@ewok:發佈清單文件的內容以及原始問題中.jar文件的目錄結構。一旦發現問題,您應該更好地瞭解build.xml中的問題。發佈了 – Danation 2012-03-26 15:49:05

+0

。我也根據Mike的回答 – ewok 2012-03-26 16:03:51

16

略...

我已經返工build.xml文件正確包括jar文件,並在清單類路徑中的庫。我假設你的「阿帕奇http.jar」文件是Apache核心的包裝,幷包含在它的其他幾個jar文件爲Apache客戶端等

的build.xml

<?xml version="1.0" encoding="ISO-8859-1"?> 
<project name="Test" basedir="." default="jar"> 
    <property name="source.dir"  value="src"/> 
    <property name="lib.dir"  value="lib"/> 
    <property name="class.dir"  value="bin"/> 
    <property name="jar.dir"  value="dist"/> 
    <property name="jar.file"  value="${jar.dir}/${ant.project.name}.jar"/> 
    <property name="main-class"  value="pack.HttpController"/> 

    <path id="libraries.path">  
     <fileset dir="${lib.dir}"> 
      <include name="*.jar"/> 
     </fileset> 
    </path> 

    <target name="clean" description="delete old files"> 
     <delete dir="${class.dir}"/> 
     <delete dir="${jar.dir}"/> 
    </target> 

    <target name="compile" description="build class files" depends="clean"> 
     <mkdir dir="${class.dir}"/> 
     <javac srcdir="${source.dir}" destdir="${class.dir}"> 
      <classpath refid="libraries.path"/> 
     </javac> 
    </target> 

    <target name="jar" depends="compile"> 
     <mkdir dir="${jar.dir}"/> 
     <mkdir dir="${class.dir}/${lib.dir}"/> 
     <copy todir="${class.dir}/${lib.dir}" flatten="true"> 
      <path refid="libraries.path"/> 
     </copy> 

     <manifestclasspath property="manifest.classpath" jarfile="${jar.file}"> 
      <classpath refid="libraries.path"/> 
     </manifestclasspath> 

     <jar destfile="${jar.file}" basedir="${class.dir}"> 
      <manifest> 
       <attribute name="Main-Class" value="${main-class}"/> 
       <attribute name="Class-Path" value="${manifest.classpath}"/> 
      </manifest> 
     </jar> 
    </target> 

    <target name="run" depends="jar"> 
     <java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/> 
    </target> 

</project> 
+0

更新了build.xml,我做了推薦的編輯。我不得不改變一些東西(沒有'$ {dist}'屬性,我認爲你的意思是'$ {jar.dir}'),但是構建仍然返回相同的錯誤。 – ewok 2012-03-26 16:01:42

+0

還請包括jar文件的目錄佈局。我想知道rt是否讓您的課程處於默認包中感到不安。 – Mike 2012-03-26 16:08:45

+0

我將'HttpController.java'移動到了'pack'軟件包(src/pack),並調整了build.xml文件以反映這一點,但同樣的錯誤發生。 – ewok 2012-03-26 16:16:29

4

Class-Path條目是錯誤的,你必須單獨指定每個jar文件,你不能指定一個帶有.jar文件的目錄(只有帶有.jar文件的目錄)。類文件)

這在JAR File specification記錄,並在Java tutorial

解釋相當不錯。如果你有兩個庫命名FirstLib.jarSeconLib.jar您的類路徑條目應該是這樣的:

Class-Path: lib/FirstLib.jar lib/SecondLib.jar 

編輯
在你的build.xml裏面看起來像這樣:

<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${class.dir}"> 
    <manifest> 
     <attribute name="Main-Class" value="${main-class}"/> 
     <attribute name="Class-Path" value="${lib.dir}/FirstLib.jar ${lib.dir}/SecondLib.jar"/> 
    </manifest> 
</jar> 
+0

我編輯了我的build.xml文件來反映這一點,但我仍然不斷收到無主類錯誤。無論什麼原因,它不認可我定義的主類 – ewok 2012-03-26 18:19:49

+0

你的主類是否真的沒有包?因爲這就是'Main-Class:HttpController'定義的內容。 – 2012-03-26 18:59:38

+0

我會更新上面的代碼。最初它沒有包裝,但我已經添加了一個包裝並仍然遇到同樣的問題 – ewok 2012-03-26 19:01:30

1

這更多的是一種通用的解決方案的製作可執行的JAR文件,但是這是我使用的代碼:我用這個結構,使許多不同的可執行的JAR文件

<?xml version="1.0" encoding="UTF-8"?> 

<!-- 
    Any words or attribute values which are capitalized and separated by 
    underscores are places where you add the data. 

    Example: PROJECT_NAME, enter your project name 
--> 

<project name="PROJECT_NAME" default="jar" basedir="."> 
    <!-- source code package --> 
    <property name="src" value="SOURCE_CODE_FOLDER"/> 

    <!-- classes folder (will be deleted) --> 
    <property name="cls" value="classes"/> 

    <!-- the directory of the jar file --> 
    <property name="jar.dir" value="JAR_FILE_DIRECTORY"/> 

    <!-- the jar file itself --> 
    <property name="jar.file" value="${jar.dir}/${ant.project.name}-launch.jar"/> 

    <!-- the fully qualified name of the main class --> 
    <property name="main" value="PATH.TO.MAIN_CLASS"/> 

    <!-- initialization --> 
    <target name="-init"> 

     <!-- the class folder* --> 
     <mkdir dir="${cls}"/> 

     <!-- the jar directory --> 
     <mkdir dir="${jar.dir}"/> 
    </target> 

    <!-- compiling of files --> 
    <target name="-post-init-comp" depends="-init"> 

     <!-- 
      turn all of the source java classes into class files 
      located in the directory we made* 
     --> 
     <javac srcdir="${src}" destdir="${cls}"/> 
    </target> 

    <!-- creation of the jar file --> 
    <target name="jar" depends="-post-init-comp"> 

     <!-- make the executable jar --> 
     <jar destfile="${jar.file}" basedir="${cls}"> 
      <manifest> 

       <attribute name="Manifest-Version" value="1.0"/> 
       <attribute name="Ant-Version" value="Apache Ant 1.8.3"/> 

       <attribute name="Main-Class" value="${main}"/> 

       <!-- 
        for some reason, this is needed for me in order 
        to have the jar function right 
       --> 
       <attribute name="Class-Path" value="${main}"/> 

       <!-- Any other mainfest data is added here --> 

      </manifest> 
     </jar> 

     <!-- remove the class folder --> 
     <delete dir="${cls}"/> 
    </target> 
</project> 

,再加上它是簡單比你所擁有的:-)

所有放在jar標籤下的清單標籤中的數據將成爲一個自動生成的具有給定數據的清單文件。

相關問題