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