`
daimojingdeyu
  • 浏览: 275132 次
  • 性别: Icon_minigender_1
  • 来自: 山东
社区版块
存档分类
最新评论

代码实现对java程序打包

    博客分类:
  • Java
阅读更多
除了使用JDK自带的jar命令对生成的class文件进行打包,还可以在程序中使用java.util.jar包的类,来实现对class文件的打包。网上找到的代码,写得不错,这里记录一下。

========================================================
2009-12-12日更新,原来代码居然了一对括弧,大意啦
另增加了对Manifest文件的支持,在网上找了一下没有找到,找了一下API还真的找到了,一同更新一下,这样打包时就可以指定入口的主类了。

package test;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

/**
 * Provides utility services for jarring and unjarring files and directories.
 * Note that a given instance of JarHelper is not threadsafe with respect to
 * multiple jar operations.
 * 
 * @author Patrick Calahan <pcal@bea.com>
 */
public class JarHelper {

	// ========================================================================
	// Constants

	private static final int BUFFER_SIZE = 2156;

	private static String MAIN_CLASS;

	// ========================================================================
	// Variables

	private byte[] mBuffer = new byte[BUFFER_SIZE];
	private int mByteCount = 0;
	private boolean mVerbose = false;
	private String mDestJarName = "";

	// ========================================================================
	// Constructor

	/**
	 * Instantiates a new JarHelper.
	 */
	public JarHelper() {
	}

	// ========================================================================
	// Public methods

	/**
	 * Jars a given directory or single file into a JarOutputStream.
	 */
	public void jarDir(File dirOrFile2Jar, File destJar) throws IOException {

		if (dirOrFile2Jar == null || destJar == null)
			throw new IllegalArgumentException();

		mDestJarName = destJar.getCanonicalPath();
		FileOutputStream fout = new FileOutputStream(destJar);
		
		JarOutputStream jout;

		if (MAIN_CLASS != null)
		{
			Manifest manifest = new Manifest();
			Attributes attrs = manifest.getMainAttributes();
			attrs.putValue("Manifest-Version", "1.0");
			attrs.putValue("Class-Path", ".");
			attrs.putValue("Main-Class", MAIN_CLASS);
			/**
			 * Manifest-Version: 1.0
			 * Class-Path: .
			 * Main-Class: test.JarHelper
			 */
			jout = new JarOutputStream(fout, manifest);
		}
		else
		{
			jout = new JarOutputStream(fout);
		}
		// jout.setLevel(0);
		try {
			jarDir(dirOrFile2Jar, jout, null);
		} catch (IOException ioe) {
			throw ioe;
		} finally {
			jout.close();
			fout.close();
		}
	}

	/**
	 * Unjars a given jar file into a given directory.
	 */
	public void unjarDir(File jarFile, File destDir) throws IOException {
		BufferedOutputStream dest = null;
		FileInputStream fis = new FileInputStream(jarFile);
		unjar(fis, destDir);
	}

	/**
	 * Given an InputStream on a jar file, unjars the contents into the given
	 * directory.
	 */
	public void unjar(InputStream in, File destDir) throws IOException {
		BufferedOutputStream dest = null;
		JarInputStream jis = new JarInputStream(in);
		JarEntry entry;
		while ((entry = jis.getNextJarEntry()) != null) {
			if (entry.isDirectory()) {
				File dir = new File(destDir, entry.getName());
				dir.mkdir();
				if (entry.getTime() != -1)
					dir.setLastModified(entry.getTime());
				continue;
			}
			int count;
			byte data[] = new byte[BUFFER_SIZE];
			File destFile = new File(destDir, entry.getName());
			if (mVerbose)
				System.out.println("unjarring " + destFile + " from "
						+ entry.getName());
			FileOutputStream fos = new FileOutputStream(destFile);
			dest = new BufferedOutputStream(fos, BUFFER_SIZE);
			while ((count = jis.read(data, 0, BUFFER_SIZE)) != -1) {
				dest.write(data, 0, count);
			}
			dest.flush();
			dest.close();
			if (entry.getTime() != -1)
				destFile.setLastModified(entry.getTime());
		}
		jis.close();
	}

	public void setVerbose(boolean b) {
		mVerbose = b;
	}

	// ========================================================================
	// Private methods

	private static final char SEP = '/';

	/**
	 * Recursively jars up the given path under the given directory.
	 */
	private void jarDir(File dirOrFile2jar, JarOutputStream jos, String path)
			throws IOException {
		if (mVerbose)
			System.out.println("checking " + dirOrFile2jar);
		if (dirOrFile2jar.isDirectory()) {
			String[] dirList = dirOrFile2jar.list();
			String subPath = (path == null) ? "" : (path
					+ dirOrFile2jar.getName() + SEP);
			if (path != null) {
				JarEntry je = new JarEntry(subPath);
				je.setTime(dirOrFile2jar.lastModified());
				jos.putNextEntry(je);
				jos.flush();
				jos.closeEntry();
			}
			for (int i = 0; i < dirList.length; i++) {
				File f = new File(dirOrFile2jar, dirList[i]);
				jarDir(f, jos, subPath);
			}
		} else {
			if (dirOrFile2jar.getCanonicalPath().equals(mDestJarName)) {
				if (mVerbose)
					System.out.println("skipping " + dirOrFile2jar.getPath());
				return;
			}

			if (mVerbose)
				System.out.println("adding " + dirOrFile2jar.getPath());
			FileInputStream fis = new FileInputStream(dirOrFile2jar);
			try {
				JarEntry entry = new JarEntry(path + dirOrFile2jar.getName());
				entry.setTime(dirOrFile2jar.lastModified());
				jos.putNextEntry(entry);
				while ((mByteCount = fis.read(mBuffer)) != -1) {
					jos.write(mBuffer, 0, mByteCount);
					if (mVerbose)
						System.out.println("wrote " + mByteCount + " bytes");
				}
				jos.flush();
				jos.closeEntry();
			} catch (IOException ioe) {
				throw ioe;
			} finally {
				fis.close();
			}
		}
	}

	// for debugging
	public static void main(String[] args) throws IOException {
		if (args.length < 2) {
			System.err.println("Usage: JarHelper jarname.jar directory [MainClass]");
			return;
		}
		
		if (args.length == 3)
		{
			MAIN_CLASS = args[2];
		}

		JarHelper jarHelper = new JarHelper();
		jarHelper.mVerbose = true;

		File destJar = new File(args[0]);
		File dirOrFile2Jar = new File(args[1]);

		jarHelper.jarDir(dirOrFile2Jar, destJar);
	}
}



分享到:
评论
3 楼 daimojingdeyu 2012-02-14  
yaoandw 写道
拿去用了,thank you

2 楼 yaoandw 2012-02-14  
拿去用了,thank you
1 楼 llp20_2000 2008-11-14  
变量名:dirOrFile2Jar  .我以前也想写个,但是JAR视乎不能更新,每次向里面加entry的时候都要从头开始重新建立一个新jar,觉得还是用命令方便,就罢了,这个又让我想起了呵呵.谢谢博主 

相关推荐

    java程序打包方案

    ### Java程序打包方案详解 #### 一、引言 在Java开发过程中,为了方便地部署和执行Java应用程序,经常需要将编写的Java源代码或类文件打包成可执行的格式。尤其是在Windows环境下,为了让非技术人员也能轻松运行...

    Java 应用程序打包

    标题“Java应用程序打包”指的是将Java源代码编译成字节码(.class文件),然后通过特定的工具整合成一个或多个可执行文件或库的过程。这个过程通常包括JAR(Java Archive)文件的创建,这是Java中常用的打包方式。 ...

    java程序打包

    Java 程序打包 Java 程序打包是指将 Java 程序编译后的.class 文件和其他资源文件打包成一个 jar 文件,以便于分发和部署。下面是 Java 程序打包的详细步骤和知识点总结: 一、创建 manifest 文件 在 Java 程序...

    Java程序打包jar及exe所需文件

    1. **Java程序打包jar**: - **JAR(Java Archive)**:JAR文件是Java平台特有的归档格式,它允许将多个类文件和其他资源(如图像、声音等)打包到一个文件中。通过使用`jar`命令或者构建工具(如Maven、Gradle)...

    java 代码打包成exe

    2. **Exe4j 工具**:这是一个专门用于将 Java 应用程序打包成 EXE 文件的工具,通常需要获取软件和授权账号,可以通过网络进行下载。 #### 三、步骤详解 ##### 1. 将 Java 项目打包成可执行 JAR 文件 **目的**:...

    Java程序打包成exe执行文件工具

    这里提到的“Java程序打包成exe执行文件工具”是指将Java应用转换为可以直接在Windows操作系统上双击运行的exe格式的工具。主要涉及到的技术和步骤如下: 1. **Java程序打包成Jar包**: Java程序通常被打包成JAR...

    经典java小程序源代码合集

    Java程序由类(class)组成,每个类都定义了特定的数据结构和功能。在Java中,一切皆为对象,这意味着你可以将数据和操作数据的方法封装在一起。例如,一个简单的"Hello, World!"程序就是通过创建一个名为`Main`的类...

    java 程序打包成jar文件后 连接数据库出错(教程方法)

    在Java编程中,将程序打包成JAR文件是常见的部署方式,这使得代码可以作为一个独立的可执行单元进行分发。然而,在打包包含数据库连接的Java应用程序时,可能会遇到一些问题,尤其是涉及到像MySQL这样的外部数据库。...

    java程序打包工具 exe4j下载

    Java程序在运行时需要JVM(Java虚拟机)的支持,但在一些情况下,用户可能希望将Java应用程序打包成可执行的本地二进制文件,以便在没有安装JVM的机器上直接运行。`exe4j`就是这样一款强大的工具,它允许Java开发者...

    将java程序打包成服务

    总结来说,将Java程序打包成Windows服务是通过Java服务包装器实现的,这涉及到配置包装器的配置文件、处理可能出现的错误、服务的注册与管理以及异常和日志监控。这个过程需要对Java和Windows服务机制有深入理解,但...

    java程序打包工具

    Java程序打包工具是开发者在开发过程中必不可少的辅助工具,它们主要负责将源代码、资源文件、依赖库等组件整合成可执行的格式,以便于分发、部署和运行。在这个场景中,提到的"project-mjar-0.4"很可能是一个特定的...

    java程序打包exe

    Java程序打包成exe是将Java应用程序转换为Windows操作系统下的可执行文件(.exe)的过程,这样非Java环境的用户也能直接运行程序。这通常通过特定的工具实现,比如提到的exe4j。exe4j是一个专门用于Java应用程序打包...

    将Java代码打包为exe文件(绝对可行)

    3. **JNI (Java Native Interface)**:允许Java代码与其他语言编写的代码进行交互的一种机制,对于本文讨论的将Java程序打包成exe的过程至关重要。 #### 打包Java程序为EXE文件的方法 将Java程序转换为EXE文件主要...

    如何把一个java程序打包成exe文件.doc

    ### 如何将Java程序打包成EXE文件 在软件开发领域,尤其是对于Java开发者来说,将Java程序打包成EXE文件是一种常见的需求。这不仅可以让程序在没有安装Java运行环境(JRE)的计算机上运行,还能提高程序的安全性和...

    打包java程序为exe文件

    查看源码可以帮助理解Java程序在转换过程中需要考虑的事项,比如如何组织代码、如何处理资源文件等。 通过这两个工具,Java开发者可以轻松地将他们的应用程序分发给不熟悉Java环境的用户,提高程序的普及度和用户...

    JAVA程序打包成exe文件

    ### JAVA程序打包成EXE文件知识点详解 #### 一、背景与需求分析 在软件开发领域,特别是使用Java语言进行跨平台应用开发时,开发者常常会遇到如何将编写的Java程序打包成可以在不同操作系统上直接运行的应用程序的...

    JAVA代码打包工具

    Java代码打包工具是开发者在开发过程中经常会用到的一种实用软件,它可以帮助我们将编写好的Java程序集合成可执行的文件,方便部署和分发。这里我们主要讨论的是Java应用程序的打包过程,包括JAR(Java Archive)...

    JAVA程序打包完全功略

    在IT行业中,将Java程序打包成可执行的.exe文件对于那些不熟悉Java环境的用户来说是一种方便的解决方案。本文将深入探讨如何使用exe4j工具实现这一目标,从而让Java程序能在Windows环境下无需安装JRE就能运行。 ...

    Java应用程序打包成exe工具

    1. **为什么需要将Java程序打包成.exe**: - 用户友好:大多数Windows用户对.exe文件更熟悉,无需安装JRE即可运行。 - 环境独立性:打包成.exe可降低依赖性,避免因缺少JRE导致的运行问题。 - 部署简化:单个.exe...

    java程序打包成exe文件

    标题中的“java程序打包成exe文件”指的是将Java编写的程序转换为Windows操作系统下的可执行文件(.exe),这样非Java环境的用户也能直接运行,无需先安装Java运行环境(JRE)。这个过程通常借助第三方工具来实现,...

Global site tag (gtag.js) - Google Analytics