javagroovyclassloadergroovyclassloader

GroovyClassLoading Mechanism


I'm really newbie to groovy scripting but following some tutorial I tried to dynamically load some groovy class within my java code using parseClass() method of GroovyClassLoader. I wrote some snippet and it worked fine for me. The problem is that I don't clearly understand what groovy engine is doing beyond my view and how those scripts are compiled?
Does a new class gets creted and loaded into jvm? Or does my application uses some cached sources?

Here is the class I'm trying to parse:

  private static class MyScript {

  @Override
  public String toString()
  {
     StringBuilder builder = new StringBuilder();
     builder.append("public class SomeClass\n");
     builder.append("{\n");
     builder.append("Some code...").append("\n");
     builder.append("}\n");
     return builder.toString();
  }

The I load it with build() as below:

private Class MyGroovyBuilder {
  private Script script = new Script();
  public String build() throws TemplateCompilationException
  //
  String groovyText = script.toString();
  //
  CompilerConfiguration config = new CompilerConfiguration();
  //
  byte[] bytes;
  try
  {
     bytes = groovyText.getBytes(config.getSourceEncoding());
  }
  catch (UnsupportedEncodingException e)
  {
     throw new TemplateCompilationException(e, groovyText);
  }
  //
  InputStream in = new ByteArrayInputStream(bytes);
  GroovyCodeSource gcs = new GroovyCodeSource(in, "SomeName", "/groovy/shell");
  GroovyClassLoader loader = new
  GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
  Class<?> scriptClass;
  try
  {
     scriptClass = loader.parseClass(gcs, false);
  }
  catch (CompilationFailedException e)
  {
     throw new GroovyCompilationException(e, "SomeName", groovyText);
  }
  catch (ClassFormatError e)
  {
     throw new GroovyCompilationException(e, "SomeName", groovyText);
  }
return scriptClass.getName();

}


Any clarification is greatelly appreciated.

BR.


Solution

  • After loading class it appears in your class loader, and can be accessed like any other class.

    There is a simple tutorial [here], that show how to load class from string.

    In simplest case, you can load class, and hold it's Class object, using it to create objects dynamically. For field access or method invokation you can rely on Groovy dynamic nature.

    There is no "cached source" or smth like that behind the scene and you can forget, from where your class is loaded. You can also cache classes, that are already compiled, and save them somewhere, as described [here]. It will drastically improve performance, if you need to load same class often.

    But it will be better, to dig down in topic, because dynamic class loading is advanced Java/Groovy technique, it's whole infrastructure of chained classloaders, so it's better to refer documentation about them.

    Links below may be helpful.

    http://javarevisited.blogspot.ru/2012/12/how-classloader-works-in-java.html

    How to use URLClassLoader to load a *.class file?