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)]

Reply via email to