views:

894

answers:

2

I am trying to extend an Eclipse code builder (for generating DTOs from Hibernate VOs) - and it uses Groovy for its template system.

The code it uses to create the groovy Script is a little weird (not what I see in the Groovy docs) but it works, mostly:

GroovyShell shell = new GroovyShell();
script = shell.parse(source);

Then, later:

Binding binding = (bindings == null ? new Binding() : new Binding(bindings));
Script scriptInstance = InvokerHelper.createScript(script.getClass(), binding);
scriptInstance.setProperty("out", out);
scriptInstance.run();
out.flush();

Now, this works just fine, until it hits a reference to an object that is not directly in the project. In the script, it iterates through the properties of the Class that it is processing - when it does this, Groovy looks at all of the methods and when it can't find a Class definition for one of the method parameters, it craps out. In this case, it's dying when it finds any references to Hibernate, but I'm sure it will crap out with a lot more. It doesn't need to do anything to them, but it can't live without knowing what they are apparently.

Script doesn't appear to have a classloader that I can supply any classpath info, so I tried providing it to the GroovyShell - no difference.

What's the proper way to fix this so that the Groovy interpreter can find my projects referenced Jars?

+2  A: 

I had this exact problem and solved it by creating my own URLClassLoader, and using reflection to call a protected method to add a new path to the ClassPath

// Specify the path you want to add
URL url = new URL("file://path/to/classes/here");

// Create a new class loader as a child of the default system class loader
ClassLoader loader = new URLClassLoader(System.getClass().getClassLoader()); 

// Get the AddURL method and call it
Method method = URLClassLoader.class.getDeclaredMethod("addURL",new Class[]{URL.class});
method.setAccessible(true);
method.invoke(loader,new Object[]{ url });

GroovyShell shell = new GroovyShell( loader );
Zoomzoom83
A: 

I'm having the same problem trying to automate Gant scripts running. The solution I found is:

  1. copy gant-starter.conf (or groovy-starter.conf if it's just groovy) from $GROOVY_HOME/conf to your own dir;

  2. add "load [directory]" or "load [jar]" there, as described in javadocs to org.codehaus.groovy.tools.LoaderConfiguration, found in Groovy source distribution;

  3. before starting groovy set groovy.starter.conf.override system property to the name of that file, like -Dgroovy.starter.conf.override=[filename]

sereda