2010-01-07 6 views
4

Я хотел бы написать приложение Java, которое может создавать исполняемые банки во время выполнения. «Привет мир» того, что я хочу сделать, это написать приложение Java X, которое при запуске генерирует исполняемый jar Y, который при запуске печатает мир привет (или, возможно, другую строку, неизвестную до тех пор, пока не будет запущен Y).генерировать исполняемый банку во время выполнения

Как это сделать?

ответ

5

Другие ответы требуют запуска нового процесса, это метод, который этого не делает. Вот 3 определения классов, которые создают сценарий приветствия, описанный в вопросе.

Когда вы запускаете 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(); 
    } 
} 
2

Вам нужно написать его в простой старой Java? Я бы использовал Gradle (Groovy основанный инструмент построения). У вас может быть пользовательская задача для записи исходных файлов для Y (Groovy упрощает запись шаблонных файлов). Gradle упрощает создание исполняемого банку.

Если вы действительно хотите свернуть с нуля, вам нужно будет использовать ZipOutStream, чтобы заархивировать скомпилированные файлы после вызова javac через Process API для компиляции источника.

Может быть, немного больше информации о том, почему вы хотите сделать это помогло бы получить лучшие ответы

ура

Lee

0

Шаг 1: выяснить, как это сделать вручную с помощью командной строки. Шаг 2: автоматизировать это, вызывая программу из Java.

http://devdaily.com/java/edu/pj/pj010016/

На шаге 1, я предложил бы использовать муравей - Иды не всегда автоматизированы. Таким образом, либо выпишите все файлы с Java, либо некоторые из конфигураций муравьев, включенных в качестве ресурсов в проект.

+0

Но вы можете сделать лучше, чем это. Как сборку компиляции Java, так и шаги создания JAR-файла можно выполнить в рамках текущей JVM. –

+0

Вот что я надеялся. Я не хочу запускать новый процесс или зависеть от среды хост-машины, кроме того, что установлен JRE.У вас есть ссылка на пример, Стивен? –

1

Чтобы подробно описать ответ Ли, сначала необходимо скомпилировать источник. Вы можете использовать Process или использовать код от tools.jar непосредственно как explained here. Затем выпишите файл MANIFEST.MF и поместите все это вместе, используя ZipOutputStream, как уже упоминалось.

Смежные вопросы