|
View:
New views
12 Messages
—
Rating Filter:
Alert me
|
|
|
Method created via ExpandoMetaClass is not recognizedHi all,
I'm trying to implement Java interface with Groovy as follows: //MyGroovyClassImpl.groovy class MyGroovyClassImpl implements MyJavaInterface { MyGroovyClassImpl() { MyGroovyClassImpl.metaClass.getNext = {-> println 'This is next command.';} } } Then I call above class from Java as follows: //Java code to access MyGroovyClassImpl.groovy GroovyClassLoader gcl = new GroovyClassLoader(); Class cls = gcl.parseClass(new File(<path to MyGroovyClassImpl.groovy>)); Object obj = cls.newInstance(); MyJavaInterface myInterface = MyJavaInterface.class.cast(obj); Binding binding = new Binding(); binding.setVariable("myInterface",myInterface); GroovyShell gs = new GroovyShell(binding); gs.evaluate("myInterface.next"); The last line produces the following exception: groovy.lang.MissingPropertyException: No such property: next for class: ScriptExecutionContext at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:479) at Script1.run(Script1.groovy) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:543) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:518) ... I've added ExpandoMetaClass.enableGlobally(), but the problem persists. Any help would be greatly appreciated. Regards, Setya |
|
|
Re: Method created via ExpandoMetaClass is not recognizedSetya schrieb:
> Hi all, > > I'm trying to implement Java interface with Groovy as follows: > > //MyGroovyClassImpl.groovy > class MyGroovyClassImpl implements MyJavaInterface > { > MyGroovyClassImpl() > { > MyGroovyClassImpl.metaClass.getNext = {-> println 'This is next > command.';} > } > } please try: > //MyGroovyClassImpl.groovy > class MyGroovyClassImpl implements MyJavaInterface > { > MyGroovyClassImpl() > { > MyGroovyClassImpl.metaClass.getNext = {-> println 'This is next command.';} > this.metaClass = null > } > } because at the point you add the method the class has already a per instance meta class, but you call will only affect global meta classes... also... do you really want to do that each time? how about > //MyGroovyClassImpl.groovy > class MyGroovyClassImpl implements MyJavaInterface { > static { > this.metaClass.getNext = {-> println 'This is next command.';}{ > } > } then it will be executed only once and I think the hack with this.metaClass = null is also not needed any more. > The last line produces the following exception: > groovy.lang.MissingPropertyException: No such property: next for class: > ScriptExecutionContext > at > org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50) > at > org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:479) > at Script1.run(Script1.groovy) > at groovy.lang.GroovyShell.evaluate(GroovyShell.java:543) > at groovy.lang.GroovyShell.evaluate(GroovyShell.java:518) > ... > > I've added ExpandoMetaClass.enableGlobally(), but the problem persists. you did, hmm.. so maybe I am wrong then... unless... is it the first thing you do? bye blackdrag -- Jochen "blackdrag" Theodorou The Groovy Project Tech Lead (http://groovy.codehaus.org) http://blackdragsview.blogspot.com/ http://www.g2one.com/ --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Method created via ExpandoMetaClass is not recognizedHi blackdrag,
Thanks for quick response. I've tried your suggestions, but none of them works. Regarding ExpandoMetaClass.enableGlobally(), If I put it in MyGroovyClassImpl.groovy than the GroovyClassLoader won't parse the file as instance of MyJavaInterface. If I add it when evaluating the script, it doesn't take effect. But If I put those scripts in 1 file it works as expected as follows: class MyGroovyClassImpl { MyGroovyClassImpl() { MyGroovyClassImpl.metaClass.getNext = {->println 'This is next command.';}; } } ExpandoMetaClass.enableGlobally(); def context = new MyGroovyClassImpl(); context.next; Regards, Setya |
|
|
Re: Method created via ExpandoMetaClass is not recognizedI am also trying to learn Groovy and I tried this thing and for me both the things worked -
1) setting this.metaClass = null in the MyGroovyClassImpl constructor in MyGroovyClassImpl.groovy 2) setting MyGroovyClassImpl.metaClass.getNext in a static block so that it happens only once. Can you please take out a few moments and explain the effect "this.metaClass = null" internally has? Does setting it null make the instance use the global metaclass that has been affected by setting "MyGroovyClassImpl.metaClass.getNext"? Regards, Roshan On Fri, Aug 22, 2008 at 9:59 PM, Setya <jsetya@...> wrote:
|
|
|
Re: Method created via ExpandoMetaClass is not recognizedHi,
> > I am also trying to learn Groovy and I tried this thing and for me both > the > things worked - > > 1) setting this.metaClass = null in the MyGroovyClassImpl constructor in > MyGroovyClassImpl.groovy > > 2) setting MyGroovyClassImpl.metaClass.getNext in a static block so that > it > happens only once. > > Can you please take out a few moments and explain the effect > "this.metaClass > = null" internally has? Does setting it null make the instance use the > global metaclass that has been affected by setting > "MyGroovyClassImpl.metaClass.getNext"? Does your class implement a Java (not Groovy) interface ? and you invoke the script exactly the way I did it from Java (not Groovy) ? Regards, Setya |
|
|
Re: Method created via ExpandoMetaClass is not recognizedYes. I have defined a Java interface whose implementation is a Groovy class and then I am invoking this impl groovy class again from a Java class using GroovyShell/GroovyClassLoader - I set it up exactly as you mentioned in your first mail. I am attaching the code files that worked for me.
It is just that even after seeing it work, I did not understand the meaning of "this.metaClass = null". Does setting it to null make it re-assign its own per instance metaClass using the newly modified global EMC? rgds, Roshan On Sat, Aug 23, 2008 at 12:01 AM, Setya <jsetya@...> wrote:
--------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Method created via ExpandoMetaClass is not recognizedSetya schrieb:
> Hi blackdrag, > > Thanks for quick response. > > I've tried your suggestions, but none of them works. does not? hmm... should have.. do you use 1.5.6? > Regarding ExpandoMetaClass.enableGlobally(), If I put it in > MyGroovyClassImpl.groovy than the GroovyClassLoader won't parse the file as > instance of MyJavaInterface. If I add it when evaluating the script, it > doesn't take effect. > > But If I put those scripts in 1 file it works as expected as follows: > > class MyGroovyClassImpl > { > MyGroovyClassImpl() > { > MyGroovyClassImpl.metaClass.getNext = {->println 'This is next > command.';}; > } > } > ExpandoMetaClass.enableGlobally(); > def context = new MyGroovyClassImpl(); > context.next; ok, imagine you need to call a method or set a field/property on a class in Groovy. To accomplish this, Groovy needs a MetaClass. Now, this happens not only for code you see, but also for code you do not see... for example to set fields in the constructor This means when the first line of your code is executed in the constructor you already need a MetaClass. Therefor you can not affect the current meta class with ExpandoMetaClass.enableGlobally(); in the constrcutor, beause the point where this would affect the meta class is already passed. bye blackdrag --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Method created via ExpandoMetaClass is not recognizedRoshan Dawrani schrieb:
> I am also trying to learn Groovy and I tried this thing and for me both > the things worked - so they do work... strange > 1) setting this.metaClass = null in the MyGroovyClassImpl constructor in > MyGroovyClassImpl.groovy well... null is an invalid meta class. But we ned one and the global meta class is used to set the per instance meta class. That means if the global meta class is changed and the current meta class of the object is "delegted", then the global meta class becomes the new current meta class. > 2) setting MyGroovyClassImpl.metaClass.getNext in a static block so that > it happens only once. this works, because at this point the meta class for the class is not yet set.. since there is no instance yet. So if you change the global meta class and then make an instance, then you get the global metaclass as current meta class for the current instance. so it is two different effects bye blackdrag --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Method created via ExpandoMetaClass is not recognizedThe bit that - the per-instance meta class is already set by the time we are in the constructor - was a little clear. I was not sure what effect was setting it to null having after modifying the metaclass (adding getNextI() to it). Does making it null make groovy set it again and this time using the just-modified meta-class?
rgds, Roshan On Sat, Aug 23, 2008 at 7:46 PM, Jochen Theodorou <blackdrag@...> wrote: Setya schrieb: |
|
|
Re: Method created via ExpandoMetaClass is not recognizedOk, I understand it better now. Thanks for explaining. Please ignore my last mail. I think our last mails cross each other on the way.
rgds, Roshan On Sat, Aug 23, 2008 at 7:53 PM, Roshan Dawrani <roshandawrani@...> wrote:
|
|
|
Re: Method created via ExpandoMetaClass is not recognizedHi,
One thing that I forgot to mention is that if I tried your suggestions in Eclipse using plain JUnit Test, it worked as expected, but when I run it on JUnit Plug-in Test it didn't. Is this a known issue when adding method/property via ExpandoMetaClass in Eclipse Equinox envronment ? Regards, Setya |
|
|
Re: Method created via ExpandoMetaClass is not recognizedRoshan Dawrani schrieb:
> The bit that - the per-instance meta class is already set by the time we > are in the constructor - was a little clear. I was not sure what effect > was setting it to null having after modifying the metaclass (adding > getNextI() to it). Does making it null make groovy set it again and this > time using the just-modified meta-class? yes byeblackdrag -- Jochen "blackdrag" Theodorou The Groovy Project Tech Lead (http://groovy.codehaus.org) http://blackdragsview.blogspot.com/ http://www.g2one.com/ --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
| Free embeddable forum powered by Nabble | Forum Help |