4 Replies Latest reply on May 13, 2014 7:01 PM by jameslivingston

    How to load a file in war file

    mustangxu

      Hi

       

      I am new to wildfly/jboss and was trying to migrate my apps from glassfish to wildfly. During the migration I met a problem related to file loading. I have a file under root package, foo.xml, which will be loaded in the app. My previous code looks like

      String path = Thread.currentThread().getContextClassLoader().getResource("foo.xml").getPath();
      
      otherLib.someMethod(path);
      

       

      It works well in GF, but in wildfly the value of "path" is "/content/xxx.war/WEB-INF/classes/foo.xml", which causes a java.io.FileNotFoundException. I have searched for this issue thru google, SOF, jboss community for a few days but so far get nothing valuable. Since "someMethod" is a method from other 3rd-party lib, it is not possible for me to change the signature to use a InputStream obj instead. So how to get the path properly in Wildfly?

        • 1. Re: How to load a file in war file
          jameslivingston

          Do you know exactly what format of path is the other library expecting, an absolute path? Calling URL.getPath() on what is returned from there is highly non-portable, and may break with other differences too (Windows UNC paths, any app server which uses jar: URLs etc).

           

          If if was relative to the root of the WAR, getServletContext().getRealPath("foo.xml") would work and be portable if it returns a non-null value. In AS7/EAP 6, getServletContext().getRealPath("foo.xml") will return a non-null but incorrect path, and WildFly correctly returns null.

           

          If the resource is in WEB-INF/classes and not a jar, getServletContext().getRealPath("WEB-INF/classes/foo.xml") works on AS7 and WildFly, however I'm not sure it is supposed to. From http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getRealPath%28java.lang.String%29 and the servlet spec, I think WEB-INF/ (and META-INF) prefixed paths should not resolve. The javadoc says that it should map paths that are available under the context path.

          • 2. Re: How to load a file in war file
            jameslivingston

            I just talked with Stuart on IRC, and he was of the opinion that null is probably correct but it's a bit vague. It seems Tomcat and glassfish return non-null, and WebLogic returns null, so different servers are not consistent. To avoid breaking applications, it will probably continue to return non-null values for WEB-INF/* resources

            • 3. Re: How to load a file in war file
              mustangxu

              Hi, James

               

              1. The library requires a absolute path

              2. The library is used inside a spring batch module, which means I cannot get servlet context

              • 4. Re: How to load a file in war file
                jameslivingston

                I don't believe there is a great way to do it. As well as a solution now, it would be worth filing a request to get alternative API added which accepts an InputStream or URL. The only portable way to do it would be to open a temporary file and dump the contents of getResourceAsStream() to it, then pass the path of the temporary file to it. You'd have to deal with cleanup however.

                 

                The first portability problem is that the file may not exist on disk at all, servers are allowed to server the content directly out of the compressed archive and many do, especially if it inside a jar. The second portability problem is that even if the file is on disk, there is no guarantee that getResource() will return a file: URL, and WildFly doesn't.

                 

                 

                I'm not sure what the best hacky way to get an absolute path to a file in a WAR's WEB-INF/classes without a ServletContext is.