Как установить встроенный путь к классам Groovy-скриптов? - PullRequest
2 голосов
/ 07 апреля 2009

Я пытаюсь расширить компоновщик кода Eclipse (для создания DTO из Hibernate VO) - и он использует Groovy для своей системы шаблонов.

Код, который он использует для создания скрипта Groovy, немного странный (не то, что я вижу в документах Groovy), но в основном он работает:

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

Затем, позже:

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

Теперь, это работает просто отлично, пока не попадет на ссылку на объект, которого нет непосредственно в проекте. В сценарии он просматривает свойства класса, который он обрабатывает - когда он это делает, Groovy просматривает все методы и, когда ему не удается найти определение класса для одного из параметров метода, он обнуляется. В этом случае он умирает, когда находит какие-либо ссылки на Hibernate, но я уверен, что это принесет гораздо больше пользы. Ему ничего не нужно делать, но он не может жить, не зная, кем они являются.

Скрипт , по-видимому, не имеет загрузчика классов, чтобы я мог предоставить любую информацию о пути к классам, поэтому я попытался предоставить его в GroovyShell - без разницы.

Как правильно исправить это, чтобы интерпретатор Groovy мог найти мои проекты, на которые ссылаются Jars?

Ответы [ 3 ]

2 голосов
/ 25 сентября 2012

То же самое, что и @James, можно сделать без использования отражения, загрузив все jar-файлы из определенной папки:

URLClassLoader classLoader = new URLClassLoader( getExtraJarUrls(), getClass().getClassLoader() );
GroovyShell shell = new GroovyShell( classLoader, binding, compilerConfiguration );


private URL[] getExtraJarUrls() throws MalformedURLException
{
    logger.debug( "Loading extra jars from {}", EXTRA_JARS_DIR.getAbsolutePath() );
    URL[] result;
    File[] files = EXTRA_JARS_DIR.listFiles( new JarFilenameFilter() );
    if (files != null)
    {
        List<URL> urls = new ArrayList<URL>( files.length );
        for (File file : files)
        {
            urls.add( file.toURI().toURL() );
        }
        result = urls.toArray( new URL[urls.size()] );
    }
    else
    {
        result = new URL[0];
    }
    logger.debug( "Adding URLs to classloader: {}", Arrays.toString( result ) );
    return result;
}

private static class JarFilenameFilter implements FilenameFilter
{
    public boolean accept( File dir, String name )
    {
        return name.endsWith( ".jar" );
    }
}
2 голосов
/ 08 апреля 2009

У меня была именно эта проблема, и я решил ее, создав собственный URLClassLoader и используя отражение для вызова защищенного метода, чтобы добавить новый путь к 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 );
0 голосов
/ 16 апреля 2009

У меня такая же проблема, когда я пытаюсь автоматизировать запуск сценариев Ганта. Решение, которое я нашел:

  1. copy gant-starter.conf (или groovy-starter.conf, если это просто groovy) из $ GROOVY_HOME / conf в ваш собственный каталог;

  2. добавить «загрузить [каталог]» или "загрузить [банку]" там, как описано в Javadocs в org.codehaus.groovy.tools.LoaderConfiguration, найдено в исходном дистрибутиве Groovy;

  3. перед началом заводного набора система groovy.starter.conf.override свойство имени этого файла, лайк -Dgroovy.starter.conf.override = [имя файла]

...