Skip to content

JavaFileObjects violates StandardJavaFileManager contract wrt toUri #72

Open
@tbroyer

Description

@tbroyer

JavaFileObjects violates StandardJavaFileManager contract wrt toUri:

The URI returned from FileObject.toUri()

  • must be absolute (have a schema), and
  • must have a normalized path component which can be resolved without any process-specific context such as the current directory (file names must be absolute).

According to these rules, the following URIs, for example, are allowed:

  • file:///C:/Documents%20and%20Settings/UncleBob/BobsApp/Test.java
  • jar:///C:/Documents%20and%20Settings/UncleBob/lib/vendorA.jar!com/vendora/LibraryClass.class

Whereas these are not (reason in parentheses):

  • file:BobsApp/Test.java (the file name is relative and depend on the current directory)
  • jar:lib/vendorA.jar!com/vendora/LibraryClass.class (the first half of the path depends on the current directory, whereas the component after ! is legal)
  • Test.java (this URI depends on the current directory and does not have a schema)
  • jar:///C:/Documents%20and%20Settings/UncleBob/BobsApp/../lib/vendorA.jar!com/vendora/LibraryClass.class (the path is not normalized)

— Source: http://docs.oracle.com/javase/7/docs/api/javax/tools/StandardJavaFileManager.html

The javadoc for JavaCompiler gives an example of implementation for a string-based JavaFileObject:

For example, here is how to define a file object which represent source code stored in a string:

      /**
       * A file object used to represent source coming from a string.
       */
      public class JavaSourceFromString extends SimpleJavaFileObject {
          /**
           * The source code of this "file".
           */
          final String code;

          /**
           * Constructs a new JavaSourceFromString.
           * @param name the name of the compilation unit represented by this file object
           * @param code the source code for the compilation unit represented by this file object
           */
          JavaSourceFromString(String name, String code) {
              super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),
                    Kind.SOURCE);
              this.code = code;
          }

          @Override
          public CharSequence getCharContent(boolean ignoreEncodingErrors) {
              return code;
          }
      }

Note how they prefix the URI with "string:///" (it's otherwise equivalent to what JavaFileObjects.forSourceString does).

AFAICT, this is an issue only for forSourceString (and forSourceLines, which ultimately defer to forSourceString), and forResource when the resource is in a JAR (e.g. not if it's a file).

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3type=defectBug, not working as expected

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions