我想編寫一個Java應用程序,它可以在運行時創建可執行jar。我想要做的事情的「hello world」是編寫一個Java應用程序X,它在運行時生成一個可執行的jar,當運行時打印出hello world(或者直到運行Y之後纔會知道另一個字符串)。在運行時生成可執行jar
我怎樣才能做到這一點?
我想編寫一個Java應用程序,它可以在運行時創建可執行jar。我想要做的事情的「hello world」是編寫一個Java應用程序X,它在運行時生成一個可執行的jar,當運行時打印出hello world(或者直到運行Y之後纔會知道另一個字符串)。在運行時生成可執行jar
我怎樣才能做到這一點?
其他的答案需要啓動一個新的進程,這是沒有的方法。這裏有3個類定義可以產生問題中描述的hello world場景。
當你運行XMain.main,它產生/tmp/y.jar。然後,當你在命令行中運行以下命令:
java -jar /tmp/y.jar cool
它打印:
Hello darling Y!
cool
例如/ YMain.java
package example;
import java.io.IOException;
import java.io.InputStream;
public class YMain {
public static void main(String[] args) throws IOException {
// Fetch and print message from X
InputStream fromx = YMain.class.getClassLoader().getResourceAsStream("fromx.txt");
System.out.println(new String(Util.toByteArray(fromx)));
// Print first command line argument
System.out.println(args[0]);
}
}
例如/ XMain.java
package example;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
public class XMain {
public static void main(String[] args) throws IOException {
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, YMain.class.getName());
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream("/tmp/y.jar"), manifest);
// Add the main class
addClass(YMain.class, jarOutputStream);
// Add the Util class; Y uses it to read our secret message
addClass(Util.class, jarOutputStream);
// Add a secret message
jarOutputStream.putNextEntry(new JarEntry("fromx.txt"));
jarOutputStream.write("Hello darling Y!".getBytes());
jarOutputStream.closeEntry();
jarOutputStream.close();
}
private static void addClass(Class c, JarOutputStream jarOutputStream) throws IOException
{
String path = c.getName().replace('.', '/') + ".class";
jarOutputStream.putNextEntry(new JarEntry(path));
jarOutputStream.write(Util.toByteArray(c.getClassLoader().getResourceAsStream(path)));
jarOutputStream.closeEntry();
}
}
例如/ Util.java
package example;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class Util {
public static byte[] toByteArray(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[0x1000];
while (true) {
int r = in.read(buf);
if (r == -1) {
break;
}
out.write(buf, 0, r);
}
return out.toByteArray();
}
}
第1步多一點信息:找出如何使用命令行手動去做。 步驟2:通過從Java內部調用程序來自動執行此操作。
http://devdaily.com/java/edu/pj/pj010016/
第1步我會建議使用螞蟻 - 集成開發環境並不總是自動化。因此,要麼從Java中寫出所有文件,要麼在項目中包含一些作爲資源的ant配置。
爲了詳細說明李的回答,您首先需要編譯源。您可以使用Process,也可以直接使用tools.jar
中的代碼作爲explained here。然後寫出一個MANIFEST.MF文件,並使用ZipOutputStream將它們放在一起,如前所述。
但是你可以做得比這更好。 Java編譯和JAR文件創建步驟都可以在當前的JVM中完成。 – 2010-01-07 03:44:59
這就是我所希望的。除了安裝JRE之外,我不想生成新進程或依賴主機環境。斯蒂芬,你有一個例子嗎? – 2010-01-07 23:28:46