Announcement Announcement Module
Collapse
No announcement yet.
Can WebApplicationContext load files from WEB-INF/lib/*.jar? classpath*: doesn't work Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can WebApplicationContext load files from WEB-INF/lib/*.jar? classpath*: doesn't work

    Hi,

    I was wondering if WebApplicationContext can load resources (ie, applicationContext xml files) from inside jar files deployed in web application (under WEB-INF/lib directory)? I guess the answer is "application server specific" (because of ClassLoaders?..), but I was wondering if there is any override that can be made?..

    My current web.xml looks like this:
    Code:
    <web-app>
    
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
          /WEB-INF/applicationContext-*.xml,
          classpath*:applicationContext-*.xml,
          classpath*:cihi/**/applicationContext.xml,
          classpath*:cihi/**/applicationContext-*.xml
        </param-value>
      </context-param>
    
    ...
    </web-app>
    This loads correctly all applicationContext files identified there, both from WEB-INF directory as well as from webapp classpath (WEB-INF/classes). This config however can NOT find any applicationContext files once they are packaged in jar file and placed under WEB-INF/lib.

    My AS is OC4J 10.1.2.0.2, standalone version. I'm using Spring 1.2.6. Any ideas/suggestions?..

    Thanks.

    Vlad

  • #2
    not again!

    try specifying the files explicitely, as classloaders do not like "*" in the path

    Comment


    • #3
      classpath* while powerful is restricted by the classloader.getResource() implementation. Some application servers behave correctly, others don't. To maximize the reuse across various platform, as Injecteer suggested, try to use a pattern as exact as possible without wildcard matching.
      If you still depend on the classpath* for your environment then try using it with the WARs unpacked.

      Comment


      • #4
        ... it doesn't seems like 100% ClassLoader issue...

        For the record:

        - the problem seems to be in a _webapplication_ class loader itself, ie, Tomcat loads resource from lib/jar files no problem, while OC4J - does not
        - Java 1.4.2 system class loader has no problem loading resource by the path specified from the jar files
        - the problem for JVM system classloader present only paths which _root starts_ with 'asteriks', ie: "classpath*:**/myres.xml" - in this case the classloader behaves as described in the docs
        - a simple way to test whether your classloader hierarhy will support loaded resources from WEB-INF/lib JAR files or not is to check if you'll get an empty enumeration for the call: yourClassLoader.getResources("mypackage"), providing the jar file contains 'mypackage/**' directory hierarhy
        - some debugging shows that the problem with OC4J seems to be that webapp classloader doesn't pass the request to the system classloader on one hand, and doesn't do proper traversing of JAR file on another hand

        So, I believe normally there shouldn't be a problem loading resources from WEB-INF/lib jar files, but smth in OC4J prevents it.

        That's why I actually wonder if it's worthwhile for Spring to have its own 'failover' ClassLoader to load resources, which would be a bit more 'cross platform' and doesn't rely that heavily on the underlying ClassLoader hierarhies...

        Thanks for your advices - the exact path does work, though, again, from what I saw during debugging, the 'patterned' path should have worked as well...

        Comment


        • #5
          ClassLoaders are powerful but also dangerous. Inside a container is not even always an option - for example OC4j doesn't allow a custom classloader to be used to load your webapp.
          You might want to check the oc4j forums - the internal classloader has a lot of features and forbidding getResources() might be one of them - probably you have to enable/activate it through some sort of configuration parameter.
          Note that in this case, Spring still respects the contract - i.e. it calls the appropriate methods on the classloader who decides if it finds the resources or not.

          Comment


          • #6
            How about putting this little tidbit in the documentation somewhere, such as right after "4.7.2. The classpath*: prefix"

            These little gotchas are the worst kind of showstopper because to anyone who hasn't been bitten by it yet, there appears to be no reason whatsoever why it shouldn't work.

            I spent almost a week trying to figure out why the loader context could find my resources when deployed through jetty, but not through tomcat.

            Comment


            • #7
              I've raised a JIRA issue here - I'll try to address it in the upcoming feature:
              http://opensource.atlassian.com/proj...rowse/SPR-2339

              Comment

              Working...
              X