title: Java programmatically compile jar
body: <p>I have java source code in a text file. There has to be entered some custom hard coded variables into the source code and then it has to be turned into a jar. This works but when I run the jar, the Main class can not be found. </p>
  
  <p>When I extract the jar file with WinRAR, I can't seem to find an error.</p>
  
  <p>When I run the generated/extracted class file via cmd, I get "Error: Could not find or load main class Main"</p>
  
  <p>generated manifest:</p>
  
  <pre><code>Manifest-Version: 1.0
  Main-Class: javabinder.Main
  </code></pre>
  
  <p>Source code:</p>
  
  <pre><code>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&lt;JavaFileObject&gt; diagnostics = new DiagnosticCollector&lt;JavaFileObject&gt;();
              JavaFileObject file = new JavaSourceFromString("Main", sb.toString());
              Iterable&lt;? extends JavaFileObject&gt; 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;
          }
      }
  }
  </code></pre>
  
  <p>The text file containing the java source code:</p>
  
  <pre><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)
      }
  }
  </code></pre>
  
  <hr>
  
  <p>Update: As suggested, I'm now using the JavaCompiler class. Which works, but I'm still having issues with putting it in a jar.</p>