`
daimojingdeyu
  • 浏览: 272346 次
  • 性别: 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,觉得还是用命令方便,就罢了,这个又让我想起了呵呵.谢谢博主 

相关推荐

Global site tag (gtag.js) - Google Analytics