2010-01-07 5 views
4

런타임에 실행 가능한 jar 파일을 만들 수있는 Java 응용 프로그램을 작성하고 싶습니다. 내가하고 싶은 "안녕하세요 세상"은 Java 앱 X를 작성하여 실행할 때 실행 가능한 jar Y를 생성합니다. 실행하면 jar를 실행하면 hello world (또는 Y가 실행될 때까지는 알 수없는 다른 문자열)가 인쇄됩니다.런타임에 실행 가능한 jar 생성

어떻게하면됩니까?

답변

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을 사용하면 실행 가능한 jar를 쉽게 생성 할 수 있습니다.

처음부터 직접 롤업하려면 프로세스 API를 통해 javac을 호출 한 후 ZipOutStream을 사용하여 컴파일 된 파일을 압축하여 소스를 컴파일해야합니다.

어쩌면 당신은 더 나은 답변

환호

0

1 단계를 얻을 도움이 될이 일을하려는 이유에 대해 좀 더 많은 정보 : 수동으로 명령 줄을 사용하여 작업을 수행하는 방법을 알아낼. 2 단계 : Java 내에서 프로그램을 호출하여이를 자동화하십시오.

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

1 단계를 위해 나는 개미를 사용하는 것이 좋습니다 것입니다 - IDE를 항상 오토메이션이 없습니다. 따라서 Java에서 모든 파일을 작성하거나 프로젝트의 일부로 개미 구성을 리소스로 포함하십시오.

+0

하지만 이것보다 더 잘 할 수 있습니다. Java 컴파일 및 JAR 파일 작성 단계는 현재 JVM 내에서 수행 될 수 있습니다. –

+0

그게 내가 원하는 것입니다. JRE를 설치하는 것 외에는 새로운 프로세스를 생성하거나 호스트 시스템의 환경에 의존하고 싶지 않습니다.예를 들어 링크가 있습니까, 스티븐? –

1

Lee의 답을 자세히 설명하려면 소스를 먼저 컴파일해야합니다. 프로세스를 사용하거나 tools.jar의 코드를 explained here으로 직접 사용할 수 있습니다. 그런 다음 MANIFEST.MF 파일을 작성하고 언급 한대로 ZipOutputStream을 사용하여 모두 넣으십시오.

관련 문제