Czy w Javie jest możliwa kompilacja i uruchamianie kodu w locie? Jeżeli tak, to w jaki sposób?
Poniższy przykład w C# wyjaśni o co chodzi, chodzi o to, czy w Javie można zrobić to samo.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.IO;
namespace DynaTest
{
public interface ITest
{
string GetMessage();
}
class Program
{
static void Main(string[] args)
{
// Tworzenie kody C#
StringBuilder CsCode = new StringBuilder();
CsCode.Append("namespace DynaTest\r\n");
CsCode.Append("{\r\n");
CsCode.Append(" public class Test : ITest\r\n");
CsCode.Append(" {\r\n");
CsCode.Append(" public string GetMessage()\r\n");
CsCode.Append(" {\r\n");
CsCode.Append(" return \"Hello World!\";\r\n");
CsCode.Append(" }\r\n");
CsCode.Append(" }\r\n");
CsCode.Append("}\r\n");
// Tworzenie obiektu kompilatora i ustawianie parametrow
CodeDomProvider CodeProvider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters CompileParams = new CompilerParameters();
CompileParams.GenerateInMemory = true;
CompileParams.ReferencedAssemblies.Add("DynaTest.exe");
// Kompilacja kodu
CompilerResults CompiledObject = CodeProvider.CompileAssemblyFromSource(CompileParams, CsCode.ToString());
// Tworzenie informacji o ewentualnych bledach
if (CompiledObject.Errors.HasErrors)
{
StringBuilder ErrorsMsg = new StringBuilder();
for (int x = 0; x < CompiledObject.Errors.Count; x++)
{
if (!CompiledObject.Errors[x].IsWarning)
{
int ErrLn = CompiledObject.Errors[x].Line;
int ErrCol = CompiledObject.Errors[x].Column;
string ErrMsg = CompiledObject.Errors[x].ErrorText.Replace("'", "''");
ErrorsMsg.Append("Ln ").Append(ErrLn.ToString());
ErrorsMsg.Append(",Col ").Append(ErrCol.ToString());
ErrorsMsg.Append(": ");
ErrorsMsg.Append(ErrMsg).Append("\r\n");
}
}
throw new Exception(ErrorsMsg.ToString());
}
// Tworzenie obiektu klasy utworzonej na podstawie skompilowanego kodu
Assembly CompiledCode = CompiledObject.CompiledAssembly;
ITest Testobject = (ITest)CompiledCode.CreateInstance("DynaTest.Test");
// Test dzialania
Console.Clear();
Console.WriteLine(Testobject.GetMessage());
Console.ReadLine();
}
}
}