Ales Justin wrote:
> I finally have the cause:
>
> Deploy
> ------
> 1. Structure scanning creates tempX for the nested war
> (ZipEntryContext-A)
>
> 2. During deployment JEEDeployedObject calls getResource, which opens
> a vfs URL
>
> 3. The vfs registry cache lookup fails because ZipEntryContext-A is a
> nested resource, thus the original deployment is rescanned.
>
> 4. ZipEntryContext-B is created in the same file context as A (the
> deploy dir), therefore *tempX is reused* (see initEntries:539)
Why exactly is ZEC-B created?
It should be only one, as that's the point of having a cache.
It looks like nested zip entries are never registered in the cache (see
mountZipStream) in ZipEntryContext.
> Undeploy
> --------
> 5. tempX is removed
>
> 6. ZipEntyContext-A is cleaned, and it's container is reset
>
> Redeploy
> --------
> 7. During structure scanning ZipEntryContext-B is retrieved (which
> still refers to tempX)is opened *BOOM*
>
> So the fundamental problem is that we reuse temps for entities which
> have different lifecycles. We also always purge temps based on the
> source location, so even if we keep them separate, the first tempinfo
> cleanup will remove them all.
If it was only a single instance, as the cache presumes,
there should be no problem, as the entity is reset no cleanup.
That would definitely be more efficient, but what if the cache evicts
the entry (lru etc)?
What if we fix the caching and also prevent reuse? That way the worse
case scenario is you end up with an extra temp, and the tempinfo cleanup
code already removes the handler on the extra instance?
OK, there might still be a problem if someone kept a ref on the
nested
.war,
but I would consider that his problem and a bad impl practice,
as I don't see how else can we properly cleanup temps.
That would also mean making sure that the deployment code never holds on
to a ref during redeploy.
I can think of two potential ways to solve this, although both would
exceed the timeline we need to get this fixed by (last week :)
1. We could cleanup just the calling handler's temp, and refcount the
temp (although this would require that people call cleanup on virtual
file entries)
2. We could make VirtualFile refs rediscover themselves after they are
cleaned
Well, I am exhausted, so I am going to crash. I just committed the
JBVFS-108 changes. In case you have trouble reproducing on Windows, it
's easy to find if you modify ZipEntryContext.getChild to check if the
child's temp is still registered and dump an error if it is not.
--
Jason T. Greene
JBoss, a division of Red Hat