You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by Venkat Sadasivam <ve...@gmail.com> on 2016/11/16 15:27:48 UTC

Groovy and Serialization

Hello:

We are using Groovy in the web application and some classes loaded via
Groovy script get serialized and added into HttpSession object. In
clustered environment when other Tomcat server try to deserialize we get
ClassNotFoundException.

I tried something like below code in a simple Java.

ScriptEngineManager factory = new ScriptEngineManager(Serialization.class
.getClassLoader());

ScriptEngine engine = factory.getEngineByName("Groovy");

String groovyScript = IOUtils.toString(Serialization.class
.getResourceAsStream("/blah.groovy"), Charset.defaultCharset());

Class<?> myClass = (Class<?>) engine.eval(groovyScript); // this line loads
org.venkat.Blah class

GroovyObject myObj = (GroovyObject) myClass.newInstance();

Serialization.class.getClassLoader().loadClass("org.venkat.Blah"); // this
like shows class not found exception


Is there any way to load Groovy script classes into parent classloader?


Thanks,

Venkat

Re: Groovy and Serialization

Posted by Venkat Sadasivam <ve...@gmail.com>.
I solved the issue using cglib proxy class. See my example here.
https://github.com/venkatsalem/Groovy-Serialization/tree/master/app/src/main/java




On Wed, Nov 16, 2016 at 6:35 PM, Jochen Theodorou <bl...@gmx.org> wrote:

> On 16.11.2016 18:30, Venkat Sadasivam wrote:
>
>> Hi Jochen
>>
>> When using Tomcat server and putting the Groovy object into HttpSession
>> I do not have control over to choose the child classloader for
>> deserialization hence I thought if I could load into the parent then the
>> default web app class loader will be able to find the class and
>> deserialize them.
>>
>
> It would be interesting to know which class loaders are used for
> deserialization, because only then we know which one we do have to
> "influence". But in general you cannot just load a class into a parent
> class loader. The method to define a class is protected. You could maybe
> add something to the search path of that loader if it is an URLClassLoader.
>
> Then the problem is the Java script engine. It can load scripts, but what
> classloader is used for doing so and if that results in the actual
> formation of a class depends on the script engine implementation. The
> Groovy script engine will usually spawn its own class loader for that, a
> GroovyClassLoader here. It has to, because it has normally no control over
> the other loaders.
>
> I find it unlikely that this class loader will be what is used here.
>
> The context class loader could help maybe if you could set it before
> deserialization. But probably no solution...
>
> No I think the script engine is not working well for this at all
>
> bye Jochen
>

Re: Groovy and Serialization

Posted by Jochen Theodorou <bl...@gmx.org>.
On 16.11.2016 18:30, Venkat Sadasivam wrote:
> Hi Jochen
>
> When using Tomcat server and putting the Groovy object into HttpSession
> I do not have control over to choose the child classloader for
> deserialization hence I thought if I could load into the parent then the
> default web app class loader will be able to find the class and
> deserialize them.

It would be interesting to know which class loaders are used for 
deserialization, because only then we know which one we do have to 
"influence". But in general you cannot just load a class into a parent 
class loader. The method to define a class is protected. You could maybe 
add something to the search path of that loader if it is an URLClassLoader.

Then the problem is the Java script engine. It can load scripts, but 
what classloader is used for doing so and if that results in the actual 
formation of a class depends on the script engine implementation. The 
Groovy script engine will usually spawn its own class loader for that, a 
GroovyClassLoader here. It has to, because it has normally no control 
over the other loaders.

I find it unlikely that this class loader will be what is used here.

The context class loader could help maybe if you could set it before 
deserialization. But probably no solution...

No I think the script engine is not working well for this at all

bye Jochen

Re: Groovy and Serialization

Posted by Venkat Sadasivam <ve...@gmail.com>.
Hi Jochen

When using Tomcat server and putting the Groovy object into HttpSession I
do not have control over to choose the child classloader for
deserialization hence I thought if I could load into the parent then the
default web app class loader will be able to find the class and deserialize
them.



On Wed, Nov 16, 2016 at 10:43 AM, Jochen Theodorou <bl...@gmx.org>
wrote:

>
>
> On 16.11.2016 16:27, Venkat Sadasivam wrote:
>
>> Hello:
>>
>> We are using Groovy in the web application and some classes loaded via
>> Groovy script get serialized and added into HttpSession object. In
>> clustered environment when other Tomcat server try to deserialize we get
>> ClassNotFoundException.
>>
>> I tried something like below code in a simple Java.
>>
>> ScriptEngineManager factory = new ScriptEngineManager(Serializat
>> ion.class.getClassLoader());
>>
>> ScriptEngine engine = factory.getEngineByName("Groovy");
>>
>> String groovyScript = IOUtils.toString(Serialization
>> .class.getResourceAsStream("/blah.groovy"), Charset.defaultCharset());
>>
>> Class<?> myClass = (Class<?>) engine.eval(groovyScript); // this line
>> loads org.venkat.Blah class
>>
>> GroovyObject myObj = (GroovyObject) myClass.newInstance();
>>
>> Serialization.class.getClassLoader().loadClass("org.venkat.Blah"); //
>> this like shows class not found exception
>>
>
> Is there any way to load Groovy script classes into parent classloader?
>>
>
> you do not need a parent, you need the right child. Children of
> ClassLaoders are always supposed to ask their parents first, before serving
> a loadClass call themselves.
>
> So I assume that:
> myClass.getClassLoader().laodClass("org.venkat.Blah")
> would work.
>
> Is that right?
>
>
> bye Jochen
>

Re: Groovy and Serialization

Posted by Jochen Theodorou <bl...@gmx.org>.

On 16.11.2016 16:27, Venkat Sadasivam wrote:
> Hello:
>
> We are using Groovy in the web application and some classes loaded via
> Groovy script get serialized and added into HttpSession object. In
> clustered environment when other Tomcat server try to deserialize we get
> ClassNotFoundException.
>
> I tried something like below code in a simple Java.
>
> ScriptEngineManager factory = new ScriptEngineManager(Serialization.class.getClassLoader());
>
> ScriptEngine engine = factory.getEngineByName("Groovy");
>
> String groovyScript = IOUtils.toString(Serialization.class.getResourceAsStream("/blah.groovy"), Charset.defaultCharset());
>
> Class<?> myClass = (Class<?>) engine.eval(groovyScript); // this line loads org.venkat.Blah class
>
> GroovyObject myObj = (GroovyObject) myClass.newInstance();
>
> Serialization.class.getClassLoader().loadClass("org.venkat.Blah"); // this like shows class not found exception

> Is there any way to load Groovy script classes into parent classloader?

you do not need a parent, you need the right child. Children of 
ClassLaoders are always supposed to ask their parents first, before 
serving a loadClass call themselves.

So I assume that:
myClass.getClassLoader().laodClass("org.venkat.Blah")
would work.

Is that right?


bye Jochen