package com.goeswhere.tinyjar;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.jar.Pack200;
import java.util.jar.Pack200.Packer;
import java.util.zip.ZipEntry;

import lzma.streams.LzmaOutputStream;

public class Packager {
	public static void main(String[] args) throws FileNotFoundException, IOException {
		if (args.length != 1 || (args.length != 0 && (args[0].equals("--help") || args[0].equals("-h")))) {
			System.err.println("usage: jarfile");
			System.exit(1);
			return;
		}

		final File inFile = new File(args[0]);

		final Manifest mf = new Manifest();
		final JarOutputStream jos = new JarOutputStream(new FileOutputStream(inFile.getAbsolutePath() + ".jar"), mf);
		try {
			final InputStream boot = Packager.class.getResourceAsStream("/tinyjar-boot.jar");
			final JarInputStream jis = new JarInputStream(boot);
			ZipEntry en;
			while (null != (en = jis.getNextEntry())) {
				jos.putNextEntry(en);
				copy(jis, jos);
			}

			jos.putNextEntry(new ZipEntry("data"));

			final FileInputStream fis = new FileInputStream(inFile);
			try {
				final JarInputStream jarIn = new JarInputStream(fis);
				try {
					try {
						final LzmaOutputStream lzma = new LzmaOutputStream.Builder(jos).build();
						try {
							final Packer packer = Pack200.newPacker();
							packer.addPropertyChangeListener(new PropertyChangeListener() {
								public void propertyChange(PropertyChangeEvent evt) {
									if (!Packer.PROGRESS.equals(evt.getPropertyName()))
										return;
									final String val = String.valueOf(evt.getNewValue());
									System.err.printf("jar200: %3s%% complete..\n", val);

									if ("100".equals(val))
										System.err.println("Awaiting lzma completion...");
								}
							});
							packer.pack(jarIn, lzma);
						} finally {
							lzma.flush();
							lzma.close();
						}
					} finally {
					}
				} finally {
					jarIn.close();
				}
			} finally {
				fis.close();
			}
		} finally {
			jos.flush();
			jos.close();
		}

		System.out.println("Done.");
	}

	public static long copy(InputStream from, OutputStream to) throws IOException {
		byte[] buf = new byte[4096];
		long total = 0;
		while (true) {
			int r = from.read(buf);
			if (r == -1) {
				break;
			}
			to.write(buf, 0, r);
			total += r;
		}
		return total;
	}
}

@@ -307,32 +307,65 @@
 o.OutputStream;%0A
+import java.util.jar.Attributes;%0A
 import java.util
@@ -919,17 +919,16 @@
 gs%5B0%5D);%0A
-%0A
 %09%09final 
@@ -957,16 +957,212 @@
 fest();%0A
+%09%09%7B%0A%09%09%09final Attributes mainAttributes = mf.getMainAttributes();%0A%09%09%09mainAttributes.putValue(%22Manifest-Version%22, %221.0%22);%0A%09%09%09mainAttributes.putValue(%22Main-Class%22, %22com.goeswhere.tinyjar.Boot%22);%0A%09%09%7D%0A
 %09%09final 

Set main class attribute correctly