Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set an embedded Groovy scripts classpath?

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?

like image 479
Jason Maskell Avatar asked Dec 29 '25 07:12

Jason Maskell


1 Answers

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 );
like image 195
James Davies Avatar answered Jan 01 '26 04:01

James Davies



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!