Relates :
|
|
Relates :
|
|
Relates :
|
javax.annotation.processing.Filer has two methods: createResource() and getResource(). The spec for getResource() and createResource() states that IllegalArgumentException is thrown if relativeName is not relative, IOException is thrown if the file cannot be created/opened. On the top of Filer interface description there is a spec excerpt: ==== A relative name is a non-null, non-empty sequence of path segments separated by '/'; '.' and '..' are invalid path segments. A valid relative name must match the "path-rootless" rule of RFC 3986, section 3.3. ==== So the following relative names are invalid: "/boo", "goo/../hoo", "./ioo", "". And the filer should throw IllegalArgumentException if it uses the relative names above when creating or getting resources. As a variant the filer may throw IOException when getResource is trying to open nonexistent file. However, getting or creating resource with invalid relative names causes to throwing neither IllegalArgumentException nor IOException. # javac -cp . -processor tmp.InvalidRelativeNameProcessor java.lang.Object You may reproduce the behavior using following processor class (you need to uncomment either writer, or reader, or output stream, or inputstream block of code marked as 1, 2, 3, and 4). Also you may substitute StandardLocation.SOURCE_OUTPUT to StandardLocation.CLASS_OUTPUT and run it once more. package tmp; import java.io.InputStream; import java.io.Reader; import java.io.Writer; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.Filer; import javax.lang.model.element.TypeElement; import javax.lang.model.element.Element; import javax.lang.model.SourceVersion; import java.util.Set; import java.util.HashSet; import java.io.IOException; import java.io.OutputStream; import javax.tools.JavaFileManager; import javax.tools.StandardLocation; public class InvalidRelativeNameProcessor extends AbstractProcessor { String[] invalidRelativeNames = { "/boo", "goo/../hoo", "./ioo", "" }; public Set<String> getSupportedAnnotationTypes() { return new HashSet<String>() {{add("*");}}; } public SourceVersion getSupportedSourceVersion() { return SourceVersion.RELEASE_6; } public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { boolean passed = true; if(roundEnv.processingOver()) { Filer filer = processingEnv.getFiler(); for (String relative: invalidRelativeNames) { try { // Writer writer = filer.createResource( // 1 // StandardLocation.SOURCE_OUTPUT, "", relative).openWriter(); // 1 // writer.close(); // 1 // Reader reader = filer.createResource( // 2 // StandardLocation.SOURCE_OUTPUT, "", relative).openReader(true); // 2 // reader.close(); // 2 // OutputStream out = filer.createResource( // 3 // StandardLocation.SOURCE_OUTPUT, "", relative).openOutputStream(); // 3 // out.close(); // 3 // InputStream in = filer.createResource( // 4 // StandardLocation.SOURCE_OUTPUT, "", relative).openInputStream(); // 4 // in.close(); // 4 System.out.println("relative path: " + relative); } catch (IllegalArgumentException expected) { } catch (IOException expected) { } catch (Exception e) { passed = false; System.out.println("relative path: " + relative + ", thrown: " + e); } } } return true; } } As a result of running these tests relative names "goo/../hoo" and "./ioo" doesn't cause to throwing either IllegalArgumentException, or IOException. When we are trying to write a resource there are no exception thrown at all. When we are trying to get resource then unexpected java.lang.IllegalStateException is thrown. I suppose it is unexpected behavior.
|