Bug 53800 - Infinte loop cause by FileDirContext in a CDI/Weld project when using Eclipse's "Server modules without publishing"
Summary: Infinte loop cause by FileDirContext in a CDI/Weld project when using Eclipse...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Catalina (show other bugs)
Version: trunk
Hardware: All All
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-08-30 06:19 UTC by Kevin Wooten
Modified: 2012-10-04 16:36 UTC (History)
0 users



Attachments
Patch for FileDirContext.java (695 bytes, patch)
2012-08-30 06:19 UTC, Kevin Wooten
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Kevin Wooten 2012-08-30 06:19:19 UTC
Created attachment 29302 [details]
Patch for FileDirContext.java

Weld's TomcatListener is using the recurse method recited below. In the case I am encountering the DirContext that Tomcat provides is a FileDirContext.

The discovery code used by Weld encounters what appears to be a bug in FileDirContext where FileDirContexts for child directories are created with the current FileDirContext's path. This causes an infinite loop while it searches the root directory over and over.

Assuming the class discovery code Weld is using is correct, I tracked down the problem to a specific line in FileDirContext.java.  Fixing this line to set the path of the new child FileDirContext to the matching child directory fixes the issue I am encountering. With this change the project appears to still pass all the unit tests ran with "ant test". I have attached the patch to this issue.


Here is Weld's recurse function which I am assuming is correct...

protected static void recurse(DirContext context, Set<String> classes, Set<URL> urls, String prefix) throws Exception {
    if (prefix.length() > 0)
        prefix += ".";

    NamingEnumeration ne = context.listBindings("");
    while (ne.hasMoreElements()) {
        Binding next = (Binding) ne.nextElement();
        String name = prefix + next.getName();
        if (name.endsWith(".class")) {
            classes.add(name.substring(0, name.length() - 6));
            continue;
        }

        Object nextObject = next.getObject();
        if (nextObject instanceof DirContext) {
            recurse((DirContext) nextObject, classes, urls, name);
        }
    }
}
Comment 1 Konstantin Kolinko 2012-08-30 06:57:32 UTC
Fixed in 7.0 with r1378819 and will be in 7.0.30.
Proposed for 6.0.


> Here is Weld's recurse function which I am assuming is correct...

It would be a lot better if they used Servlet API (ServletContext.getResourcePaths(..)) for their task.
Well, I do not know all circumstances.
Comment 2 Mark Thomas 2012-10-04 16:36:33 UTC
Fixed in 6.0.x and will be included in 6.0.36