Java 如何使用Ant创建捆绑的可运行jar
我看了一下,但它并没有真正解决我的问题,所以我想我应该发布一个新的 我需要使用Ant创建一个可运行的jar(只需双击即可运行)。我有下面的java代码和build.xml文件,它可以很好地编译代码并创建一个jar文件,但是当我试图通过双击运行jar时,会收到一条消息:“找不到主类:HttpController.java。” 我怀疑我的问题与加载外部Java 如何使用Ant创建捆绑的可运行jar,java,ant,jar,Java,Ant,Jar,我看了一下,但它并没有真正解决我的问题,所以我想我应该发布一个新的 我需要使用Ant创建一个可运行的jar(只需双击即可运行)。我有下面的java代码和build.xml文件,它可以很好地编译代码并创建一个jar文件,但是当我试图通过双击运行jar时,会收到一条消息:“找不到主类:HttpController.java。” 我怀疑我的问题与加载外部apachehttp.jar有关,因为我已经成功地为一个完全相同的项目构建和运行了一个jar,只是它没有引用任何外部jar 这是我的密码: HttpC
apachehttp.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>
EDITbuild.xml已根据Mike的回答更新。这个问题仍然没有解决。根据Danation的回答,还发布了清单文件的内容。看看您的清单文件,很可能是其中的一个问题。我只在清单文件不正确时才看到这个错误 只是猜测,但我认为它试图运行一个“.java”文件作为它的主类,这是行不通的 请参阅oracle教程: 如果这没有任何帮助,请在原始问题中发布清单文件的内容以及.jar文件的目录结构。Snip 我已经修改了build.xml文件,将库正确地包含在jar文件和清单类路径中。我假设您的“ApacheHTTP.jar”文件是ApacheCore的包装器,其中包含几个其他用于apache客户端的jar文件,等等 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>
您的
类路径
条目错误,您必须单独指定每个jar文件,不能指定包含.jar文件的目录(仅包含.Class文件的目录)
这在中有记录,在中有很好的解释
如果您有两个库名FirstLib.jar
和SeconLib.jar
您的类路径条目应该如下所示:
Class-Path: lib/FirstLib.jar lib/SecondLib.jar
<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>
编辑:在build.xml中,如下所示:
Class-Path: lib/FirstLib.jar lib/SecondLib.jar
<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>
这是制作可执行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文件,而且它比您所拥有的更简单:-)
jar标记下的清单标记中的所有数据将成为一个自动生成的清单文件,其中包含给定的数据。我知道清单文件有问题,但是我需要知道如何重新配置build.xml,以便ant正确地生成它。@ewok:在最初的问题中发布清单文件的内容以及.jar文件的目录结构。一旦发现问题,您就应该更好地了解build.xml中的问题所在。我必须更改一些内容(没有
${dist}
属性,我认为您的意思是${jar.dir}
),但是构建仍然返回相同的错误。请还包括jar文件的目录布局。我想知道rt是否因为您的类在默认包中而感到不安。我将HttpController.java
移动到pack
包(src/pack),并调整build.xml文件以反映这一点,但同样的错误也会发生。如果将其移动到包中,则需要将文件放入子目录中。您还需要更改源代码,但我假设您已经这样做了。请在您有时间的时候发布jar文件的目录结构。当您从命令行运行它时,您得到的确切消息是什么?@see@jayan不需要任何外部工具就可以做到这一点吗?通过使用Ant编写我自己的build.xml文件来实现ie?关于使用eclipse等创建可运行JAR,本文中有一些问题/答案。我更喜欢一个jar,因为它创建一个可运行的文件。连接到ant需要10分钟。那么为什么不试试看结果呢?类路径
获取文件名列表。不是目录。@jayan使用eclipse导出到可执行jar不是我要做的。我需要使用Ant生成一个可执行的jar。最终目标是能够分发源代码,并允许用户通过在命令行上执行ant
,然后双击生成的jar文件来执行代码。此外,我更希望不必安装Ant本身以外的外部工具。我只需要知道如何使用Ant就可以做到这一点,我已经编辑了build.xml文件来反映这一点,但是我仍然不断地得到无主类错误。不管出于什么原因,它不承认我定义的主类。你的主类真的没有包吗?因为这是Main类:HttpController
定义的。我将更新上面的代码。最初它没有包,但我添加了一个包,仍然遇到相同的问题