Re: Deadlock issue
Jacopo Cappellato <[email protected]>
| Newsgroups | gmane.comp.web.freemarker.user |
|---|---|
| Message-ID | <[email protected]> |
On Apr 19, 2012, at 10:02 PM, Daniel Dekany wrote:
> Thursday, April 19, 2012, 9:25:19 PM, Jacopo Cappellato wrote:
>
>> Hi Daniel,
>>
>> with this mail I will try to answer some of the interesting points you mentioned:
>>
>> On Apr 19, 2012, at 11:45 AM, Daniel Dekany wrote:
>>
>>> Then maybe you share the same
>>> freemarker.jar file (same full-path) for multiple applications, and
>>> are also using the deprecated default shared (static) ObjectWrapper
>>> instance (or some other ObjectWrapper instance which is somehow shared
>>> between applications).
>>
>> Yes, I can confirm that in OFBiz we only use the static instance of
>> ObjectWrapper (i.e. BeansWrapper.getDefaultInstance()); we never use "new BeansWrapper()" in OFBiz.
>> So from what I understand now is that in the VM where OFBiz runs we
>> have *one* object wrapper that is shared by all threads and applications.
>> I can also confirm that in OFBiz we have *one* freemarker.jar file
>> only that is used by the framework code to render templates (defined
>> in the several OFBiz applications).
>>
>>> If two applications has the same classes from
>>> non-shared defining class-loaders (usually, from jar files from
>>> different directories), and you pass instances of those classes to the
>>> templates, FreeMarker will constantly believe that the classes were
>>> reloaded, because it gets classes of the same name which aren't
>>> equivalent objects. Each application needs to have its own
>>> ObjectWrapper in this case (see Configuration.setObjectWrapper), which
>>> is how it's normally done regardless of this issue anyway.
>>>
>>> Let's try a few things instead of just trying to run into a dead-lock:
>>>
>>> When FreeMarker detects a class change, it logs on info-level that
>>> "Detected a reloaded class [com.example.SomeClass]". For which classes
>>> does this happening? Do you understand why are those classes
>>> (apparently) changing?
>>
>> Some examples of the messages that I see:
>>
>> Detected a reloaded class [CompanyInfo$_run_closure1]. Clearing BeansWrapper caches.
>> Detected a reloaded class [CompanyInfo$_run_closure2]. Clearing BeansWrapper caches.
>> Detected a reloaded class [Breadcrumbs$_run_closure2]. Clearing BeansWrapper caches.
>> Detected a reloaded class [ContactUs$_run_closure1]. Clearing BeansWrapper caches.
>> Detected a reloaded class [ShoppingCartReadHelper$_run_closure1]. Clearing BeansWrapper caches.
>> Detected a reloaded class [ShoppingCartReadHelper$_run_closure2]. Clearing BeansWrapper caches.
>> Detected a reloaded class [ShoppingCartReadHelper$_run_closure3]. Clearing BeansWrapper caches.
>> Detected a reloaded class [ShoppingCartReadHelper$_run_closure4]. Clearing BeansWrapper caches.
>> ...
>>
>> At the moment they don't mke much sense to me; but I am still investigating into this.
>
> Do you have CompanyInfo and ShoppingCartReadHelper classes in multiple
> webapps, which are coming from the private class-loader of those
> webapps? That would explain this.
>
> Or... since these classes are written in Groovy (right?), maybe, just
> maybe, some special class-loader is used for Groovy scripts, like one
> class-loader per thread, or one class-loader per request, or something
> strange like that.
Yes they are the data preparation scripts for the templates and are all Groovy scripts; an example of an OFBiz screen declaration is the following:
<screen name="MicroCart">
<section>
<actions>
<script location="component://somecomponent/webapp/somecomponent/WEB-INF/actions/ShoppingCartReadHelper.groovy"/>
</actions>
<widgets>
<platform-specific><html><html-template location="component://somecomponent/webapp/somecomponent/cart/MicroCart.ftl"/></html></platform-specific>
</widgets>
</section>
</screen>
And the same groovy scripts or ftl templates are reused by different screen definitions in different webapplications.
>
>>> Also, what ObjectWrapper is in use can be checked while the template
>>> is running with
>>> freemarker.core.Environment.getCurrentEnvironment().getConfiguration().getObjectWrapper().
>>> Write a TempalteMethodModel that returns that, print it the result
>>> into the template, and then you will see if its the same *instance* in
>>> multiple applications.
>>
>> Yes, as I mentioned above I am pretty sure that we use *one*
>> instance only (the static instance).
>> So, if I understand the problem, the deadlock occurs because the following two conditions are met:
>> a) OFBiz is using *one* instance of BeansWrapper and *one* (?)
>> instance of ClassBasedModelFactory for all the applications
>
> (The ClassBasedModelFactory instances are fields in the BeansWrapper
> instance, so yes, one.)
>
>> b) the frequent clearing of caches because they are reloaded (or
>> Freemarker thinks they are); the reason for this is still unknown (I will have to research more)
>
> c) a bug in FreeMarker that can cause dead-lock when the cache is
> cleared... But of course, you should prevent those cache
> clearings regardless. They meant to occur only during development.
Yep, got it.
Daniel, you are really helping me a lot.
Kind regards,
Jacopo
>
>> Kind regards,
>>
>> Jacopo
>
> --
> Best regards,
> Daniel Dekany
>
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2