jersey
  1. jersey
  2. JERSEY-32

Some Web containers don't support context.getRealPath

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.0
    • Component/s: core
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: Sun

    • Issuezilla Id:
      32

      Description

      Some Web containers, like Weblogic, do not support ServletContext.getRealPath
      for deployed web applications, null values are returned. So the default
      configuration for scanning class files in /WEB-INF/classes and /WEB-INF/lib does
      not work.

      However, Servlet.getResource(), returns file-based URLs, at least for Weblogic,
      from which the resolved paths for /WEB-INF/classes and /WEB-INF/lib can be obtained.

      See the email here for more details:

      https://jersey.dev.java.net/servlets/ReadMsg?list=users&msgNo=508

      If the getRealPath("/WEB-INF/classes") returns null then try the
      getResource("/WEB-INF/classes) and if it returns a file-based URL then extract
      the path. Otherwise thrown an exception saying the the default servlet
      configuration cannot be supported.

        Activity

        Hide
        gdavison added a comment -

        It might be possible to fix this by using getResourcePaths instead. As long as
        the server implements a sensible URL scheme for the mapped paths, with folders
        ending in "/", it should be easy to iterate over the classpath.

        Consider the following resource:

        @Path("/context")
        public class ServletContextDumper {

        @GET
        public String dumpLocations(@Context
        ServletContext sc) throws MalformedURLException

        { StringBuilder sb = new StringBuilder(); // sb.append("classes\n"); String startPath = "/WEB-INF/classes"; iterate(sc, sb, startPath); sb.append("lib\n"); startPath = "/WEB-INF/lib"; iterate(sc, sb, startPath); // return sb.toString(); }

        private void iterate(ServletContext sc, StringBuilder sb,
        String startPath) throws MalformedURLException {
        Set<String> paths = sc.getResourcePaths(startPath);
        for (String path : paths) {
        sb.append(path);
        sb.append(" = ");
        sb.append(sc.getResource(path));
        sb.append("\n");

        //

        if (path.endsWith("/"))

        { iterate(sc, sb, path); }

        else {
        try {
        InputStream inputStream = sc.getResourceAsStream(path);
        try {
        if (path.endsWith(".class"))

        { sb.append("First few bytes as hex are are "); sb.append(Integer.toString(inputStream.read(), 16)); sb.append(Integer.toString(inputStream.read(), 16)); sb.append(Integer.toString(inputStream.read(), 16)); sb.append(Integer.toString(inputStream.read(), 16)); }

        else

        { sb.append("First few charaters are "); sb.append(Character.toString((char)inputStream.read())); sb.append(Character.toString((char)inputStream.read())); sb.append(Character.toString((char)inputStream.read())); sb.append(Character.toString((char)inputStream.read())); }

        sb.append(" \n");
        } finally

        { inputStream.close(); }

        } catch (IOException ioe)

        { ioe.printStackTrace(); }

        }
        }
        }

        public static class ExampleInnerClass {

        }
        }

        This will list all the classes in nested directories and any jar under the lib
        directory. Experimentation by Paul S shows this should work under glassfish.
        Need to be tested under JBoss etc.

        When run on weblogic the output for this application looks like:

        classes
        /WEB-INF/classes/project1/ = zip:C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/_wl_cls_gen.jar!/project1/
        /WEB-INF/classes/project1/ServletContextDumper.class = zip:C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/_wl_cls_gen.jar!/project1/ServletContextDumper.class
        First few bytes as hex are are cafebabe
        /WEB-INF/classes/project1/ServletContextDumper$ExampleInnerClass.class =
        zip:C:/Documents and Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/_wl_cls_gen.jar!/project1/ServletContextDumper$ExampleInnerClass.class
        First few bytes as hex are are cafebabe
        lib
        /WEB-INF/lib/jsr311-api-1.0.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jsr311-api-1.0.jar
        First few charaters are PK
        /WEB-INF/lib/jersey-server-1.0.3.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jersey-server-1.0.3.jar
        First few charaters are PK
        /WEB-INF/lib/jettison-1.0.1.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jettison-1.0.1.jar
        First few charaters are PK
        /WEB-INF/lib/_wl_cls_gen.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/_wl_cls_gen.jar
        First few charaters are PK
        /WEB-INF/lib/jackson-lgpl-0.9.4.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jackson-lgpl-0.9.4.jar
        First few charaters are PK
        /WEB-INF/lib/asm-3.1.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/asm-3.1.jar
        First few charaters are PK
        /WEB-INF/lib/jersey-json-1.0.3.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jersey-json-1.0.3.jar
        First few charaters are PK
        /WEB-INF/lib/jersey-client-1.0.3.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jersey-client-1.0.3.jar
        First few charaters are PK
        /WEB-INF/lib/jersey-core-1.0.3.jar = file:/C:/Documents and
        Settings/gdavison.EDC/Application
        Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jersey-core-1.0.3.jar
        First few charaters are PK

        Note that cafebabe and PK are the magic properties for .class files and
        .zip/.jar file respectively.

        Show
        gdavison added a comment - It might be possible to fix this by using getResourcePaths instead. As long as the server implements a sensible URL scheme for the mapped paths, with folders ending in "/", it should be easy to iterate over the classpath. Consider the following resource: @Path("/context") public class ServletContextDumper { @GET public String dumpLocations(@Context ServletContext sc) throws MalformedURLException { StringBuilder sb = new StringBuilder(); // sb.append("classes\n"); String startPath = "/WEB-INF/classes"; iterate(sc, sb, startPath); sb.append("lib\n"); startPath = "/WEB-INF/lib"; iterate(sc, sb, startPath); // return sb.toString(); } private void iterate(ServletContext sc, StringBuilder sb, String startPath) throws MalformedURLException { Set<String> paths = sc.getResourcePaths(startPath); for (String path : paths) { sb.append(path); sb.append(" = "); sb.append(sc.getResource(path)); sb.append("\n"); // if (path.endsWith("/")) { iterate(sc, sb, path); } else { try { InputStream inputStream = sc.getResourceAsStream(path); try { if (path.endsWith(".class")) { sb.append("First few bytes as hex are are "); sb.append(Integer.toString(inputStream.read(), 16)); sb.append(Integer.toString(inputStream.read(), 16)); sb.append(Integer.toString(inputStream.read(), 16)); sb.append(Integer.toString(inputStream.read(), 16)); } else { sb.append("First few charaters are "); sb.append(Character.toString((char)inputStream.read())); sb.append(Character.toString((char)inputStream.read())); sb.append(Character.toString((char)inputStream.read())); sb.append(Character.toString((char)inputStream.read())); } sb.append(" \n"); } finally { inputStream.close(); } } catch (IOException ioe) { ioe.printStackTrace(); } } } } public static class ExampleInnerClass { } } This will list all the classes in nested directories and any jar under the lib directory. Experimentation by Paul S shows this should work under glassfish. Need to be tested under JBoss etc. When run on weblogic the output for this application looks like: classes /WEB-INF/classes/project1/ = zip:C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/_wl_cls_gen.jar!/project1/ /WEB-INF/classes/project1/ServletContextDumper.class = zip:C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/_wl_cls_gen.jar!/project1/ServletContextDumper.class First few bytes as hex are are cafebabe /WEB-INF/classes/project1/ServletContextDumper$ExampleInnerClass.class = zip:C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/_wl_cls_gen.jar!/project1/ServletContextDumper$ExampleInnerClass.class First few bytes as hex are are cafebabe lib /WEB-INF/lib/jsr311-api-1.0.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jsr311-api-1.0.jar First few charaters are PK /WEB-INF/lib/jersey-server-1.0.3.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jersey-server-1.0.3.jar First few charaters are PK /WEB-INF/lib/jettison-1.0.1.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jettison-1.0.1.jar First few charaters are PK /WEB-INF/lib/_wl_cls_gen.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/_wl_cls_gen.jar First few charaters are PK /WEB-INF/lib/jackson-lgpl-0.9.4.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jackson-lgpl-0.9.4.jar First few charaters are PK /WEB-INF/lib/asm-3.1.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/asm-3.1.jar First few charaters are PK /WEB-INF/lib/jersey-json-1.0.3.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jersey-json-1.0.3.jar First few charaters are PK /WEB-INF/lib/jersey-client-1.0.3.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jersey-client-1.0.3.jar First few charaters are PK /WEB-INF/lib/jersey-core-1.0.3.jar = file:/C:/Documents and Settings/gdavison.EDC/Application Data/JDeveloper/system11.1.1.2.35.54.57/DefaultDomain/servers/DefaultServer/tmp/_WL_user/jersey/gsvl5q/war/WEB-INF/lib/jersey-core-1.0.3.jar First few charaters are PK Note that cafebabe and PK are the magic properties for .class files and .zip/.jar file respectively.
        Hide
        gdavison added a comment -

        Workaround for weblogic 10.X

        You can configure weblogic to return a non-null value for getRealPath with the
        following entry in WEB-INF/weblogic.xml

        <?xml version = '1.0' encoding = 'windows-1252'?>
        <weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app
        http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd"
        xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
        <container-descriptor>
        <show-archived-real-path-enabled>true</show-archived-real-path-enabled>
        </container-descriptor>
        </weblogic-web-app>

        See specificaly CR CR299135 in
        http://edocs.bea.com/wls/docs100/issues/known_resolved.html

        Show
        gdavison added a comment - Workaround for weblogic 10.X You can configure weblogic to return a non-null value for getRealPath with the following entry in WEB-INF/weblogic.xml <?xml version = '1.0' encoding = 'windows-1252'?> <weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd " xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app"> <container-descriptor> <show-archived-real-path-enabled>true</show-archived-real-path-enabled> </container-descriptor> </weblogic-web-app> See specificaly CR CR299135 in http://edocs.bea.com/wls/docs100/issues/known_resolved.html
        Hide
        sandoz added a comment -

        Fixed in the trunk.

        Show
        sandoz added a comment - Fixed in the trunk.
        Hide
        gdavison added a comment -

        Verified against Weblogic R11 PS1, problem no longer reproduces.

        Show
        gdavison added a comment - Verified against Weblogic R11 PS1, problem no longer reproduces.

          People

          • Assignee:
            jersey-issues
            Reporter:
            sandoz
          • Votes:
            7 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: