groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alain Stalder <astal...@span.ch>
Subject Grape and loading classes that extend java.lang.Exception from compiled Groovy bytecode
Date Mon, 27 Feb 2017 09:51:54 GMT
Maybe someone can point me in the right direction regarding the 
following issue with Grape...

Issue in code (in words further below):

--
import org.codehaus.groovy.control.CompilerConfiguration

def demoScriptText = """\
@Grab('org.apache.commons:commons-email:1.3.3')
import org.apache.commons.mail.*

try {
   new SimpleEmail().send()
} catch (EmailException e) {
   // expected
   return true
}
return false
"""

// setup/clean target directory for script class
File targetDir = new File('demo-target')
if (!targetDir.exists()) {
   assert targetDir.mkdir()
}
File classFile = new File(targetDir, 'Demo.class')
if (classFile.exists()) {
   assert classFile.delete()
}

// parse+run script with first GroovyClassLoader
def config = new CompilerConfiguration()
config.setTargetDirectory(targetDir)
def loader1 = new 
GroovyClassLoader(Thread.currentThread().contextClassLoader, config)
def script1 = loader1.parseClass(demoScriptText, 
'Demo.groovy').newInstance()
assert script1.run()

// load compiled script class with second GroovyClassLoader
def loader2 = new GroovyClassLoader()
loader2.addClasspath(targetDir.path)
try {
   def script2 = loader2.loadClass('Demo').newInstance()
   assert false
} catch (NoClassDefFoundError e) {
   println 'Failed as expected:'
   println()
   println e
   println()
   println e.stackTrace
}
--

Issue in words:

- Compile a script that uses Grape to load a dependency and use a class
   that extends java.lang.Exception from that dependency in the script.
- Loading and running that script with the GroovyClassLoader that compiled
   it, works fine.
- Then try to load the class from its class file (bytecode) with a new
    GroovyClassLoader; this fails with a NoClassDefFoundError.
- (Apparently has nothing specifically to do with commons-email, same effect
   with Commons httpclient and an Exception class declared there.)

The strange thing about this is that in the example above, EmailException is
not found, but SimpleEmail - which is in the same grabbed JAR - is found!
In fact, if I change the catch in the script to "catch (Exception e)", I can
load and run the script from its class file without any problems.

Question:

Any ideas what could cause this, or where to look closer or maybe how to
circumvent this by compiling the class differently?

(My concrete use case is with Grengine, where I do not compile to a class
in the file system, but to cached bytecode.)

Alain

--

Here is the output I get (Groovy 2.4.8, JDK 1.8.0_121, Mac):

Failed as expected:

java.lang.NoClassDefFoundError: org/apache/commons/mail/EmailException

[java.lang.Class.forName0(Native Method), 
java.lang.Class.forName(Class.java:348), 
org.codehaus.groovy.runtime.callsite.CallSiteArray$1.run(CallSiteArray.java:68), 
org.codehaus.groovy.runtime.callsite.CallSiteArray$1.run(CallSiteArray.java:65), 
java.security.AccessController.doPrivileged(Native Method), 
org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallStaticSite(CallSiteArray.java:65),

org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:162),

org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48), 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113), 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117), 
demo.run(demo.groovy:37), 
groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263), 
groovy.lang.GroovyShell.run(GroovyShell.java:518), 
groovy.lang.GroovyShell.run(GroovyShell.java:497), 
groovy.lang.GroovyShell.run(GroovyShell.java:170), 
groovy.lang.GroovyShell$run$1.call(Unknown Source), 
groovy.ui.Console$_runScriptImpl_closure16.doCall(Console.groovy:1005), 
groovy.ui.Console$_runScriptImpl_closure16.doCall(Console.groovy), 
sun.reflect.GeneratedMethodAccessor296.invoke(Unknown Source), 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), 
java.lang.reflect.Method.invoke(Method.java:498), 
org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93), 
groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325), 
org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294),

groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027), 
groovy.lang.Closure.call(Closure.java:414), 
groovy.lang.Closure.call(Closure.java:408), 
groovy.lang.Closure.run(Closure.java:495), 
java.lang.Thread.run(Thread.java:745)]


Mime
View raw message