Beispiel #1
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    static int Main (string [] args)
    {
      int returnCode = 0;

      try
      {
        ProcessArguments (args);

        ValidateArguments ();

        string workingDirectory = Path.Combine (Path.GetTempPath (), "app-java-builder", Guid.NewGuid ().ToString ());

        if (Directory.Exists (workingDirectory))
        {
          Directory.Delete (workingDirectory);
        }

        Directory.CreateDirectory (workingDirectory);

        // 
        // Run the javac tool to compile any specified files (and indirectory those referenced by source paths).
        // 

        HashSet<string> compilerFilesRead = new HashSet<string> ();

        HashSet<string> compilerFilesWritten = new HashSet<string> ();

        {
          int exitCode = -1;

          string executable = Path.Combine (s_jdkHomePath, "bin", "javac.exe");

          string arguments = string.Join (" ", s_compilerArguments.ToArray ());

#if true
          string sourcesFile = Path.Combine (workingDirectory, "sources.txt");

          using (StreamWriter writer = new StreamWriter (sourcesFile, false))
          {
            foreach (string file in s_compilerInputJavaFiles)
            {
              writer.WriteLine (file);
            }

            writer.Close ();
          }

          string fileArgs = arguments += " @" + sourcesFile;

          {
#else
          foreach (string file in s_compilerInputJavaFiles)
          {
            string fileArgs = arguments + " " + file;
#endif
            using (Process process = CreateSynchronousProcess (executable, fileArgs, string.Empty))
            {
              process.OutputDataReceived += (sender, e) =>
              {
                if (e.Data != null)
                {
                  ProcessJavacOutput (e.Data, ref compilerFilesRead, ref compilerFilesWritten);
                }
              };

              process.ErrorDataReceived += (sender, e) =>
              {
                if (e.Data != null)
                {
                  ProcessJavacOutput (e.Data, ref compilerFilesRead, ref compilerFilesWritten);
                }
              };

              if (process.Start ())
              {
                process.BeginOutputReadLine ();

                process.BeginErrorReadLine ();

                process.WaitForExit ();

                exitCode = process.ExitCode;
              }

              if (exitCode != 0)
              {
                throw new InvalidOperationException (process.StartInfo.FileName + " failed with exit code: " + exitCode);
              }
            }
          }

          // 
          // Export dependency files alongside any exported output.
          // 

          if (exitCode == 0)
          {
            foreach (string file in compilerFilesWritten)
            {
              using (StreamWriter writer = new StreamWriter (file + ".d", false, Encoding.Unicode))
              {
                writer.WriteLine (string.Format ("{0}: \\", ConvertPathWindowsToGccDependency (file)));

                foreach (string dependency in compilerFilesRead)
                {
                  writer.WriteLine (string.Format ("  {0} \\", ConvertPathWindowsToGccDependency (dependency)));
                }

                writer.Close ();
              }
            }
          }

#if true
          File.Delete (sourcesFile);
#endif
        }

        // 
        // Copy exported class files to a temporary directory to ensure packages are handled properly (and old classes are cleaned).
        // 

        {
          long failedParsedClassFiles = 0;

          foreach (string classFile in compilerFilesWritten) // Parallel.ForEach (compilerFilesWritten, classFile =>
          {
#if DEBUG
            Debug.WriteLine ("Processing: " + classFile);
#endif

            try
            {
              string classId = string.Empty;

              using (Stream stream = File.Open (classFile, FileMode.Open))
              {
                using (BinaryReader reader = new BinaryReader (stream))
                {
                  JavaClassParser.ClassFile processedClassFile = new JavaClassParser.ClassFile (reader);

                  JavaClassParser.ConstantClassInfo thisClassInfo = (JavaClassParser.ConstantClassInfo) processedClassFile.constant_pool [processedClassFile.this_class];

                  JavaClassParser.ConstantUtf8Info thisClassId = (JavaClassParser.ConstantUtf8Info) processedClassFile.constant_pool [thisClassInfo.name_index];

                  classId = Encoding.UTF8.GetString (thisClassId.bytes);

                  reader.Close ();
                }

                stream.Close ();
              }

              if (!string.IsNullOrWhiteSpace (classId))
              {
                string classPackage = classId.Substring (0, classId.LastIndexOf ('/'));

                string className = classId.Substring (classId.LastIndexOf ('/') + 1);

                string classPackageAsDir = Path.Combine (workingDirectory, classPackage);

                Directory.CreateDirectory (classPackageAsDir);

                string targetPath = string.Format ("{0}/{1}.class", classPackageAsDir, className);

                File.Copy (classFile, targetPath, true);
#if DEBUG
                Debug.WriteLine (string.Format ("Copied: '{0}' to '{1}'", classFile, targetPath));
#endif
              }
            }
            catch (Exception e)
            {
              LogException (e);

              Interlocked.Increment (ref failedParsedClassFiles);
            }
          }

          if (failedParsedClassFiles > 0)
          {
            throw new InvalidOperationException (string.Format ("Failed to parse {0} files.", failedParsedClassFiles));
          }
        }

        // 
        // Run the jar tool to package any compiled class files.
        // 

        HashSet<string> archiverFilesRead = new HashSet<string> ();

        HashSet<string> archiverFilesWritten = new HashSet<string> ();

        if (!string.IsNullOrEmpty (s_archiverOutputPath))
        {
          // 
          // c    create new archive
          // u    update an existing archive
          // f    specify archive file name
          // m    specify manifest file name
          // 0    store only; use no ZIP compression
          // 

          StringBuilder argumentsBuilder = new StringBuilder ();

          StringBuilder argumentsModeBuilder = new StringBuilder ();

          argumentsModeBuilder.Append ("c");

          argumentsModeBuilder.Append ("v");

          argumentsModeBuilder.Append ("f");

          argumentsBuilder.Append (s_archiverOutputPath + " ");

          if (!string.IsNullOrEmpty (s_archiverManifestPath))
          {
            argumentsModeBuilder.Append ("m");

            argumentsBuilder.Append (s_archiverManifestPath + " ");
          }

          argumentsModeBuilder.Append ("0");

          argumentsBuilder.Append ("-C " + QuotePathIfNeeded (workingDirectory) + " . ");

          string executable = Path.Combine (s_jdkHomePath, "bin", "jar.exe");

          string arguments = argumentsModeBuilder.ToString () + " " + argumentsBuilder.ToString ();

          string workingDir = string.Empty;

          int exitCode = -1;

          using (Process process = CreateSynchronousProcess (executable, arguments, workingDir))
          {
            process.OutputDataReceived += (sender, e) =>
            {
              if (e.Data != null)
              {
                ProcessJarOutput (e.Data, ref archiverFilesRead, ref archiverFilesWritten);
              }
            };

            process.ErrorDataReceived += (sender, e) =>
            {
              if (e.Data != null)
              {
                ProcessJarOutput (e.Data, ref archiverFilesRead, ref archiverFilesWritten);
              }
            };

            if (process.Start ())
            {
              process.BeginOutputReadLine ();

              process.BeginErrorReadLine ();

              process.WaitForExit ();

              exitCode = process.ExitCode;
            }

            if (exitCode != 0)
            {
              throw new InvalidOperationException (process.StartInfo.FileName + " failed with exit code: " + exitCode);
            }

            // 
            // Export dependency files alongside any exported output.
            // 

            if (exitCode == 0)
            {
              foreach (string file in compilerFilesWritten)
              {
                using (StreamWriter writer = new StreamWriter (file + ".d", false, Encoding.Unicode))
                {
                  writer.WriteLine (string.Format ("{0}: \\", ConvertPathWindowsToGccDependency (file)));

                  foreach (string dependency in compilerFilesRead)
                  {
                    writer.WriteLine (string.Format ("  {0} \\", ConvertPathWindowsToGccDependency (dependency)));
                  }

                  writer.Close ();
                }
              }
            }
          }
        }

        if (Directory.Exists (workingDirectory))
        {
          Directory.Delete (workingDirectory, true);
        }
      }
      catch (Exception e)
      {
        LogException (e);

        returnCode = -1;
      }

      return returnCode;
    }
Beispiel #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        static int Main(string [] args)
        {
            int returnCode = 0;

            try
            {
                ProcessArguments(args);

                ValidateArguments();

                string workingDirectory = Path.Combine(Path.GetTempPath(), "app-java-builder", Guid.NewGuid().ToString());

                if (Directory.Exists(workingDirectory))
                {
                    Directory.Delete(workingDirectory);
                }

                Directory.CreateDirectory(workingDirectory);

                //
                // Run the javac tool to compile any specified files (and indirectory those referenced by source paths).
                //

                HashSet <string> compilerFilesRead = new HashSet <string> ();

                HashSet <string> compilerFilesWritten = new HashSet <string> ();

                {
                    int exitCode = -1;

                    string executable = Path.Combine(s_jdkHomePath, "bin", "javac.exe");

                    string arguments = string.Join(" ", s_compilerArguments.ToArray());

#if true
                    string sourcesFile = Path.Combine(workingDirectory, "sources.txt");

                    using (StreamWriter writer = new StreamWriter(sourcesFile, false))
                    {
                        foreach (string file in s_compilerInputJavaFiles)
                        {
                            writer.WriteLine(file);
                        }

                        writer.Close();
                    }

                    string fileArgs = arguments += " @" + sourcesFile;

                    {
#else
                    foreach (string file in s_compilerInputJavaFiles)
                    {
                        string fileArgs = arguments + " " + file;
#endif
                        using (Process process = CreateSynchronousProcess(executable, fileArgs, string.Empty))
                        {
                            process.OutputDataReceived += (sender, e) =>
                            {
                                if (e.Data != null)
                                {
                                    ProcessJavacOutput(e.Data, ref compilerFilesRead, ref compilerFilesWritten);
                                }
                            };

                            process.ErrorDataReceived += (sender, e) =>
                            {
                                if (e.Data != null)
                                {
                                    ProcessJavacOutput(e.Data, ref compilerFilesRead, ref compilerFilesWritten);
                                }
                            };

                            if (process.Start())
                            {
                                process.BeginOutputReadLine();

                                process.BeginErrorReadLine();

                                process.WaitForExit();

                                exitCode = process.ExitCode;
                            }

                            if (exitCode != 0)
                            {
                                throw new InvalidOperationException(process.StartInfo.FileName + " failed with exit code: " + exitCode);
                            }
                        }
                    }

                    //
                    // Export dependency files alongside any exported output.
                    //

                    if (exitCode == 0)
                    {
                        foreach (string file in compilerFilesWritten)
                        {
                            using (StreamWriter writer = new StreamWriter(file + ".d", false, Encoding.Unicode))
                            {
                                writer.WriteLine(string.Format("{0}: \\", ConvertPathWindowsToGccDependency(file)));

                                foreach (string dependency in compilerFilesRead)
                                {
                                    writer.WriteLine(string.Format("  {0} \\", ConvertPathWindowsToGccDependency(dependency)));
                                }

                                writer.Close();
                            }
                        }
                    }

#if true
                    File.Delete(sourcesFile);
#endif
                }

                //
                // Copy exported class files to a temporary directory to ensure packages are handled properly (and old classes are cleaned).
                //

                {
                    long failedParsedClassFiles = 0;

                    foreach (string classFile in compilerFilesWritten) // Parallel.ForEach (compilerFilesWritten, classFile =>
                    {
#if DEBUG
                        Debug.WriteLine("Processing: " + classFile);
#endif

                        try
                        {
                            string classId = string.Empty;

                            using (Stream stream = File.Open(classFile, FileMode.Open))
                            {
                                using (BinaryReader reader = new BinaryReader(stream))
                                {
                                    JavaClassParser.ClassFile processedClassFile = new JavaClassParser.ClassFile(reader);

                                    JavaClassParser.ConstantClassInfo thisClassInfo = (JavaClassParser.ConstantClassInfo)processedClassFile.constant_pool [processedClassFile.this_class];

                                    JavaClassParser.ConstantUtf8Info thisClassId = (JavaClassParser.ConstantUtf8Info)processedClassFile.constant_pool [thisClassInfo.name_index];

                                    classId = Encoding.UTF8.GetString(thisClassId.bytes);

                                    reader.Close();
                                }

                                stream.Close();
                            }

                            if (!string.IsNullOrWhiteSpace(classId))
                            {
                                string classPackage = classId.Substring(0, classId.LastIndexOf('/'));

                                string className = classId.Substring(classId.LastIndexOf('/') + 1);

                                string classPackageAsDir = Path.Combine(workingDirectory, classPackage);

                                Directory.CreateDirectory(classPackageAsDir);

                                string targetPath = string.Format("{0}/{1}.class", classPackageAsDir, className);

                                File.Copy(classFile, targetPath, true);
#if DEBUG
                                Debug.WriteLine(string.Format("Copied: '{0}' to '{1}'", classFile, targetPath));
#endif
                            }
                        }
                        catch (Exception e)
                        {
                            LogException(e);

                            Interlocked.Increment(ref failedParsedClassFiles);
                        }
                    }

                    if (failedParsedClassFiles > 0)
                    {
                        throw new InvalidOperationException(string.Format("Failed to parse {0} files.", failedParsedClassFiles));
                    }
                }

                //
                // Run the jar tool to package any compiled class files.
                //

                HashSet <string> archiverFilesRead = new HashSet <string> ();

                HashSet <string> archiverFilesWritten = new HashSet <string> ();

                if (!string.IsNullOrEmpty(s_archiverOutputPath))
                {
                    //
                    // c    create new archive
                    // u    update an existing archive
                    // f    specify archive file name
                    // m    specify manifest file name
                    // 0    store only; use no ZIP compression
                    //

                    StringBuilder argumentsBuilder = new StringBuilder();

                    StringBuilder argumentsModeBuilder = new StringBuilder();

                    argumentsModeBuilder.Append("c");

                    argumentsModeBuilder.Append("v");

                    argumentsModeBuilder.Append("f");

                    argumentsBuilder.Append(s_archiverOutputPath + " ");

                    if (!string.IsNullOrEmpty(s_archiverManifestPath))
                    {
                        argumentsModeBuilder.Append("m");

                        argumentsBuilder.Append(s_archiverManifestPath + " ");
                    }

                    argumentsModeBuilder.Append("0");

                    argumentsBuilder.Append("-C " + QuotePathIfNeeded(workingDirectory) + " . ");

                    string executable = Path.Combine(s_jdkHomePath, "bin", "jar.exe");

                    string arguments = argumentsModeBuilder.ToString() + " " + argumentsBuilder.ToString();

                    string workingDir = string.Empty;

                    int exitCode = -1;

                    using (Process process = CreateSynchronousProcess(executable, arguments, workingDir))
                    {
                        process.OutputDataReceived += (sender, e) =>
                        {
                            if (e.Data != null)
                            {
                                ProcessJarOutput(e.Data, ref archiverFilesRead, ref archiverFilesWritten);
                            }
                        };

                        process.ErrorDataReceived += (sender, e) =>
                        {
                            if (e.Data != null)
                            {
                                ProcessJarOutput(e.Data, ref archiverFilesRead, ref archiverFilesWritten);
                            }
                        };

                        if (process.Start())
                        {
                            process.BeginOutputReadLine();

                            process.BeginErrorReadLine();

                            process.WaitForExit();

                            exitCode = process.ExitCode;
                        }

                        if (exitCode != 0)
                        {
                            throw new InvalidOperationException(process.StartInfo.FileName + " failed with exit code: " + exitCode);
                        }

                        //
                        // Export dependency files alongside any exported output.
                        //

                        if (exitCode == 0)
                        {
                            foreach (string file in compilerFilesWritten)
                            {
                                using (StreamWriter writer = new StreamWriter(file + ".d", false, Encoding.Unicode))
                                {
                                    writer.WriteLine(string.Format("{0}: \\", ConvertPathWindowsToGccDependency(file)));

                                    foreach (string dependency in compilerFilesRead)
                                    {
                                        writer.WriteLine(string.Format("  {0} \\", ConvertPathWindowsToGccDependency(dependency)));
                                    }

                                    writer.Close();
                                }
                            }
                        }
                    }
                }

                if (Directory.Exists(workingDirectory))
                {
                    Directory.Delete(workingDirectory, true);
                }
            }
            catch (Exception e)
            {
                LogException(e);

                returnCode = -1;
            }

            return(returnCode);
        }