groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From MG <>
Subject Re: new MOP under Java9 module system findings
Date Sun, 01 Apr 2018 17:58:29 GMT
Hi Jochen,

I just thought about some post by another project I read some time back 
(alas I can no longer remember which project exactly) which used Groovy 
as its scripting language, but switched to a lesser, more restrictive 
scripting option, because they needed to make the scripting more secure, 
which, according to the post, could not be done using Groovy "because of 
all the reflection Groovy uses". So I was wondering if changes at a 
fundamental level in Groovy seem unavoidable, if it would make sense to 
also keep the security aspect in mind ?

Of course you cannot be everything to everyone, even if Groovy comes 
close, but if e.g. reflection usage inside a Groovy script could be 
prohibited (afair that was one of the problems the post cited) within 
the new, Java 9 module approach, that could conceivably make sense...

Very vague, I know, but maybe just as a general "Denkanstoß" / food for 

On 01.04.2018 18:33, Jochen Theodorou wrote:
> Hi all,
> yesterday I was playing around with java modules and tried to 
> implement some pseudo mops based on what we have and I'd like to share 
> my impressions. Please do not wonder that I only mention method 
> invocation, I only played around with that.
> missingMethod seems to be easy to do, also builders based on 
> missingMethod instead of invokeMethod will do in the form we have now. 
> I managed to do that with a mini meta class, that uses reflection to 
> inspect the class (no setAccessible).
> The bad part here is that the actual invocation will have to be using 
> MethodHandles, which requires us to create them of course, which is 
> not good for performance if we have to unreflect the methods. But a 
> new meta class system could take care of that at the price of 
> increasing the meta class creation time. But I think these problems 
> can be solved.
> In my mini mop I was able to call private methods without helper 
> methods and also from inner classes. But when I mention private 
> methods I do mean methods we would have access to in Java as well. 
> This is done by the class doing the call providing a Lookup object, 
> which allows me to make calls on behalf of the caller class. Which 
> means I can *not* call private methods from arbitrary classes. This 
> means you will no longer be able to write unit tests in Groovy, able 
> to tests private methods from Java classes... unless we preprocess the 
> classes and make a lookup object available. For Groovy classes we 
> could provide such a mechanism by default, but frankly I would not do 
> that, because that lookup object means you can access all the 
> internals of the class without restrictions and that without any 
> security manager.
> The problem child in our current mop here is invokeMethod. 
> methodMissing is at the end of the mop and while it does not matter 
> there to loose the caller context we can keep them as is. But 
> invokeMethod tends to be more in between there is a potential problem. 
> As long as invokeMethod is for the current class, there is no trouble, 
> but calling into a another class from invokeMethod means to use the 
> context of the class invokeMethod is in and loosing the original 
> context. Especially that logic to just call to meta class in 
> invokeMethod is a problem.
> Example:
> class LogProxy {
>   def orig
>   def invokeMethod(String name, Object args) {
>     println "called method $name"
>     orig."$name"(*args)
>   }
> }
> class Foo {
>   def proxy = new LogProxy(orig:this)
>   private method(){}
>   def publicMethod() {
>     proxy.method()
>   }
> }
> This kind of code can work in Groovy, as long as we are not working on 
> a subclass of Foo. To make this work with modules where LogProxy is 
> from another module as Foo, I think the only way is to expose the 
> lookup object and use that for the creation of the handle. But that 
> means it has to be part of the call orig."$name"(*args) and of the 
> method signature of invokeMethod.
> In summary I think all the cases where our mop methods operate as 
> endpoints can be made work. But that means invokeMethod can no longer 
> work as entry point and actually becomes the same as methodMissing, 
> which begs the question if it should even exist. Similar cases can be 
> made for get(String) and others. For invokeMethod as entry point to 
> method invocation the signature would have to change to contain the 
> Lookup object at least, and a way to invoke a method using that lookup 
> object.
> bye Jochen

View raw message