简体   繁体   中英

How can I use wrapped Groovy shell inside the groovy script?

I have a Java app through which I'm executing a Groovy Script, the problem occurs when my Script again has code to use the groovy shell to execute the Inner script.

something like this

import com.xx.WrappedGroovyShell
import java.lang.*
 
def scriptString = """
def test(str) {
   str.toLowerCase() // This doesn't work as GString can't seem to be treated as a String
}
"""
 
try {
    
def script =  WrappedGroovyShell.getInstance().getScript("Test1", scriptString)
def script2 =  new GroovyShell().parse(scriptString) 

def example = 1
  def gstring = "OUR VALUE IS ${example}";
       println script instanceof GroovyObject // Statement returning false
       println script.test(gstring) // This throws an exception groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.runtime.GStringImpl.toLowerCase() is applicable for argument types: () values: []

       println script2 instanceof GroovyObject // Statement returns true
       println script2.test(gstring) //this one works
        

    println "Success"
} catch (ex) {
    println ex
}
 
return 0

The getScript method in WrappedGroovyShell.java is as simple as

public Script getScript(String scriptName, String scriptBody){
  return new GroovyShell().parse(scriptBody);
}

I will be thankful if someone let me know why two different behavior.

new GroovyShell() creates a new groovy classloader with parent = GroovyShell.class.getClassLoader()

and if GString.class is unknown for parent classloader - then it will be loaded again.

two GString classes loaded by different classloaders are not equal that's why you could have unexpected exceptions like "method not found for parameter GString" or "can't cast GString to GString"


this code should work because it uses classloader of current groovy class

def scriptText='''
def test(str) {
   str.toLowerCase()
}
'''

def gs = new GroovyShell(this.getClass().getClassLoader())
def script = gs.parse(scriptText)

def arg = "GSTRING ${123}"
println script.test(arg)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM