google / google/compile-testing

JavaFileObjects violates StandardJavaFileManager contract wrt toUri

Open
#72 0 comments 0 reactions 0 assignees View on GitHub
P3 type=defect
Dominant language
Java
Stars
722
Forks
129
Avg merge
11m
Merged PRs (30d)
4

Description

`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`](http://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html) 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:
>
> ``` java
> /**
> * 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).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.