Ответ 1
Использование @Grab
делает код неустойчивым, по крайней мере, с 01/26/2011.
У меня есть это в начале класса:
@Grab(group = 'org.ccil.cowan.tagsoup', module = 'tagsoup', version = '1.2')
class MyClass{...
Я пытаюсь unit test этот класс, но всякий раз, когда я пытаюсь запустить тесты JUnit 4, я получаю эту ошибку:
Caused by: java.lang.RuntimeException: No suitable ClassLoader found for grab
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:102)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:190)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:198)
at groovy.grape.GrapeIvy.chooseClassLoader(GrapeIvy.groovy:163)
at groovy.grape.GrapeIvy$chooseClassLoader.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
at groovy.grape.GrapeIvy.grab(GrapeIvy.groovy:227)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:225)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:153)
at groovy.grape.GrapeIvy.grab(GrapeIvy.groovy:216)
at groovy.grape.Grape.grab(Grape.java:131)
at groovy.grape.Grape$grab.callStatic(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:165)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:173)
at ammoscanner.AmmoScanner.<clinit>(AmmoScanner.groovy)
... 30 more
Любые идеи? Я использую groovy 1.7.5
Использование @Grab
делает код неустойчивым, по крайней мере, с 01/26/2011.
Рассматривая исходный код, это исключение генерируется всякий раз, когда указанное имя класса ClassLoader (или его суперклассы) не groovy.lang.GroovyClassLoader
или org.codehaus.groovy.tools.RootLoader
. то есть целевой класс-загрузчик должен быть экземпляром вышеупомянутых классов (бит-ограничение IMHO).
В настоящее время я не знаю, как настроить определенный загрузчик классов с помощью аннотаций @Grape
/@Grab
/@GrabConfig
. Наиболее близким было бы использовать @GrabConfig(systemClassLoader=true)
и обеспечить, чтобы Systemloader был экземпляром одного из вышеперечисленных классов ClassLoader.
Если кто-нибудь знает, сообщите мне (и я обновлю этот ответ).
Следующий код программно загрузит ваш Grapes и загрузит их в поставляемый GroovyClassLoader (правда, не совсем то, что вы хотите).
def loadGrapes(){
ClassLoader classLoader = new groovy.lang.GroovyClassLoader()
Map[] grapez = [[group : 'org.ccil.cowan.tagsoup', module : 'tagsoup', version : '1.2']]
Grape.grab(classLoader: classLoader, grapez)
println "Class: " + classLoader.loadClass('org.ccil.cowan.tagsoup.jaxp.SAXParserImpl')
}
Я предполагаю, что вы пробовали добавить
@GrabConfig(systemClassLoader=true)
так:
@Grapes([
@Grab(group = 'org.ccil.cowan.tagsoup', module = 'tagsoup', version = '1.2'),
@GrabConfig( systemClassLoader=true )
])
class MyClass{...
Если вы не используете systemClassLoader = true, то кажется, что ваша среда IDE не кодирует код с помощью компилятора groovy, вы можете проверить это с помощью простого класса groovy, который выводит имя класса своего загрузчика классов. Я бы предположил, что он пытается скомпилировать классы groovy и запустить их с загрузчиком классов
См. также этот ответ на общую ошибку во время преобразования: для захвата не найдено подходящего ClassLoader. Кроме того, это сообщение в блоге объясняет больше о запуске предварительно скомпилированных классов groovy с загрузчиком классов.
Добавьте сайт обновления моментального снимка плагина для Kepler.
Это, похоже, решает проблему "..no подходящего класса". К сожалению, мне все равно пришлось добавить виноградное репо в classpath для проекта после этого.