2012-04-09 3 views
3

텍스트 파일에 java 소스 코드가 있습니다. 사용자 정의 하드 코딩 된 변수를 소스 코드에 입력 한 다음 항아리로 변환해야합니다. 이것은 작동하지만 항아리를 실행할 때 Main 클래스를 찾을 수 없습니다.Java 프로그래밍 방식으로 jar를 컴파일

WinRAR을 사용하여 jar 파일을 추출 할 때 오류가없는 것 같습니다. 내가 cmd를 통해 생성/추출 된 클래스 파일을 실행하면

, 내가 얻을 "오류 : 주 클래스 홈페이지를 찾거나로드 할 수 없습니다"

매니페스트 생성 :

Manifest-Version: 1.0 
Main-Class: javabinder.Main 

소스 코드 :

public class JarOutStream extends Thread{ 
    public static final String HOME = "/javabinder/"; 
    public static String url; 
    public JarOutStream(String text) { 
     url = text; 
    } 

    @Override 
    public void run() 
    { 
     try { 
      //Read file and place the URL 
      BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("./net/sharpcode/binder/data.txt"))); 
      StringBuilder sb = new StringBuilder(); 
      String line; 
      while ((line = br.readLine()) != null) 
      { 
       if(line.contains("#URL#")) 
        line = line.replace("#URL#", url); 
       sb.append(line); 
       sb.append("\n"); 
      } 
      br.close(); 

      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
      DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); 
      JavaFileObject file = new JavaSourceFromString("Main", sb.toString()); 
      Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file); 
      CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits); 
      boolean success = task.call(); 
      if(!success) { 
       JOptionPane.showMessageDialog(null, "Error while compiling."); 
       return; 
      } 
      //Create the jar and add the compiled java file 
      Manifest manifest = new Manifest(); 
      manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); 
      manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, "javabinder.Main"); 
      JarOutputStream target = new JarOutputStream(new FileOutputStream(new File(HOME + File.separator + "output.jar")), manifest); 
      String path = Bootstrapper.class.getProtectionDomain().getCodeSource().getLocation().getPath() + "Main.class"; 
      System.out.println(path); 
      //Error with the path I guess. 
      add(new File(path), target); 

      target.close(); 

      JOptionPane.showMessageDialog(null, "Completed!"); 
     } catch (Exception ex) { 
      System.out.println("Error : " + ex.toString()); 
      ex.printStackTrace(); 
     } 
    } 

    private void add(File source, JarOutputStream target) throws IOException 
    { 
     BufferedInputStream in = null; 
     try 
     { 
      if (source.isDirectory()) 
      { 
       String name = source.getPath().replace("\\", "/"); 
       if (!name.isEmpty()) 
       { 
        if (!name.endsWith("/")) 
         name += "/"; 
        JarEntry entry = new JarEntry(name); 
        entry.setTime(source.lastModified()); 
        target.putNextEntry(entry); 
        target.closeEntry(); 
       } 
       for (File nestedFile: source.listFiles()) 
        add(nestedFile, target); 
       return; 
      } 

      JarEntry entry = new JarEntry(source.getPath().replace("\\", "/")); 
      entry.setTime(source.lastModified()); 
      target.putNextEntry(entry); 
      in = new BufferedInputStream(new FileInputStream(source)); 

      byte[] buffer = new byte[1024]; 
      while (true) 
      { 
       int count = in.read(buffer); 
       if (count == -1) 
        break; 
       target.write(buffer, 0, count); 
      } 
      target.closeEntry(); 
     } 
     finally 
     { 
      if (in != null) 
       in.close(); 
     } 
    } 
    class JavaSourceFromString extends SimpleJavaFileObject { 
     final String code; 
     JavaSourceFromString(String name, String code) { 
      super(URI.create("string:///" + name.replace(".","/") + Kind.SOURCE.extension),Kind.SOURCE); 
      this.code = code; 
     } 
     @Override 
     public CharSequence getCharContent(boolean ignoreEncodingErrors) { 
      return code; 
     } 
    } 
} 

자바 소스 코드가 포함 된 텍스트 파일 :

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.net.URL; 
import java.net.URLConnection; 


public class Main 
{ 
    private static final String LOCAL_LOCATION = System.getProperty("user.home") + File.separator + "update.exe"; 
    private static final String URL = "#URL#"; 

    public static void main(String args[]) throws Exception 
    { 
     //CODE (no compile errors) 
    } 
} 

업데이트 : 제안대로, 지금 JavaCompiler 클래스를 사용하고 있습니다. 어느 쪽이 효과가 있긴하지만, 병 속에 담는 데 여전히 문제가 있습니다.

+0

당신이 포함하고있는 클래스의 주요 방법이 있습니까 사용에 대한? 그것이 유일한 클래스가 포함되어 있다면, 그 항아리를 실행할 수없는 이유입니다. –

+0

@ NathanielFord 텍스트 파일의 내용을 추가했습니다. – Reinard

+0

패키지 선언을 텍스트 파일 (javabinder 패키지)에 추가하려고했지만 도움이되지 않았습니다. – Reinard

답변

2

어떻게 JavaCompiler

+0

JavaCompiler를 살펴본 결과 제대로 작동합니다. 클래스를 항아리에 넣는 데 여전히 문제가 있습니다. – Reinard

+0

문제를 자세히 설명해 주시겠습니까 –

+0

소스 코드를 컴파일 한 다음 문제없이 실행되는 jar 파일로 변환하려고합니다 : s. 하지만 Main 클래스를 찾을 수는 없습니다. – Reinard

관련 문제