Gentlemen,
 thank you very much for the poking and prodding: it pointed me in the
right direction. I solved the problem by modifying the code I wrote to fetch
the class bytes: instead of doing a URL.openStream() I changed it to do a
URL.openConnection() then disabled the use of the URLConnection cache (
URLConnection.setUseCaches(false)). Now when I do a stop all the handles are
gone and I can do a complete clean and rebuild without encountering any file
locking issues.

For what its worth it might be meaningful to put that behavior into the
webapp class loader when antiJARLocking is enabled.

 Femi.

On 5/23/06, Black Buddha <[EMAIL PROTECTED]> wrote:

Tried it: and antiResourceLocking as well (both set to true).
Its very curious: antiResourceLocking does what it seems like it should
do: extracts all referenced resource files into
work\Catalina\localhost\test\loader\org\blah\blah\blah....

However, antiJARLocking doesn't seem to do anything explicit. I took an
extended trip through the Tomcat source for the webapp class loader 
(http://svn.apache.org/repos/asf/tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java)
to see what antiJARLocking does, and basically it does this:

if (antiJARLocking) {

                ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
                try {
                    String repository = entry.codeBase.toString();
                    if ((repository.endsWith
(".jar"))
                            && (!(name.endsWith(".class")))) {
                        // Copy binary content to the work directory if not 
present
                        File resourceFile = new File(loaderDir, name);

                        url = getURI(resourceFile);
                    }
                } catch (Exception e) {
                    // Ignore
                }
            }


Which basically copies any resources with URLs that don't end with .class
to the work directory, but doesn't appear to do the same for .class files.
This sounds like what antiResourceLocking should do, but there are no
references to antiResourceLocking in that class, so I'm kind of at a loss
there (anyone know where to look for the effects of the antiResourceLocking
flag?)

I'm thinking what I'll do is subclass the loader and force it to copy the
WEB-INF/lib jars to a separate location and go from there, that way I can
discard them without losing sleep. I spotted a netbeans bug 
(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5100046)
that seems to obliquely suffer from the same issue, so that may be the
answer.

Femi.


On 5/23/06, Filip Hanik - Dev Lists <[EMAIL PROTECTED]> wrote:
>
> http://tomcat.apache.org/tomcat-5.5-doc/config/context.html
>
> look for "antiJARLocking"
>
> is that what you are after?
> Filip
>
>
> Black Buddha wrote:
> > Actually, I looked at that and its a little odder than that. I use the
> > Eclipse compiler, and when its locating import dependencies it uses a
> > chunk
> > of code like this to retrieve the bytes for a specific class:
> >
> > InputStream is;
> > try{
> >  String resourceName = className.replace('.', '/') + ".class";
> >        URL u = classLoader.getResource(resourceName);
> >        if(u != null){
> >        is = u.openStream();
> >        byte[] classBytes;
> >        byte[] buf = new byte[8192];
> >        ByteArrayOutputStream baos = new
> > ByteArrayOutputStream(buf.length);
> >        int count;
> >        while ((count = is.read(buf, 0, buf.length)) > 0) {
> >            baos.write(buf, 0, count);
> >        }
> >        baos.flush();
> >        byte[] classBytes = baos.toByteArray();
> >        char[] fileName = className.toCharArray();
> >        ClassFileReader classFileReader = new
> ClassFileReader(classBytes,
> > fileName, true);
> >        return new NameEnvironmentAnswer(classFileReader, null);
> >        }
> >    } finally {
> >        if (is != null) {
> >        try { is.close(); }catch (IOException exc) {}   // Ignore
> >        }
> >    }
> >
> > This call works just fine when I start up Tomcat the first time.
> However
> > when I stop the webapp and attempt to recompile the jar file with the
> > actual
> > class being loaded above within it I get an exception when Ant tries
> to
> > replace the file. Then when I restart the webapp, I get a
> > FileNotFoundException, even though I KNOW the jar file is present and
> > I know
> > the class is within it. I've tried the System.gc() call, but still no
> > love.
> >
> > Anyone know some way of forcing Tomcat to let go of the reference to
> the
> > webapp class loader so I can GC it and have it let go of the handle to
> > the
> > jar file? Alternatively, a cleaner way of fetching the class bytes
> > without
> > opening a stream into the jar file?
> >
> > Thanks,
> >
> > Femi.
> >
> > On 5/23/06, Peter Crowther <[EMAIL PROTECTED]> wrote:
> >>
> >> > From: Filip Hanik - Dev Lists [mailto: [EMAIL PROTECTED]
> >> > interesting, are you saying that the handle is not closed
> >> > when you call stream.close()?
> >>
> >> There's some noise on this at:
> >>
> >>
> http://forum.java.sun.com/thread.jspa?threadID=609458&messageID=3355532
> >>
> >> Still haven't found the entry in the bug database though.  Sorry,
> Filip.
> >>
> >>                 - Peter
> >>
> >> ---------------------------------------------------------------------
> >> To start a new topic, e-mail: users@tomcat.apache.org
> >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >
> >
> ------------------------------------------------------------------------
> >
> > No virus found in this incoming message.
> > Checked by AVG Free Edition.
> > Version: 7.1.392 / Virus Database: 268.7.0/345 - Release Date:
> 5/22/2006
> >
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>

Reply via email to