From 35ca6b0510cee6a185ac560ad4b690f87adbf68e Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 7 Oct 2014 17:40:50 +0200 Subject: [PATCH 1/2] Fix annotation processing when running javac without -d Samuel Inverso noticed, and Mark Hiner diagnosed, that compiling SciJava plugins using javac without specifying an output directory will write the annotation index into an incorrect location (instead of META-INF/json/ it is written into the top-level directory). This can be verified using a very simple example x1.java file: -- snip -- import org.scijava.plugin.Plugin; import org.scijava.plugin.SciJavaPlugin; @Plugin(type = SciJavaPlugin.class) public class x1 implements SciJavaPlugin { } -- snap -- The reason is that javac's DefaultFileManager will strip out any subdirectory in the path passed to the createResource() method unless an output directory is specified. Work around that by detecting the situation and creating the subdirectory explicitly. This fixes https://github.com/imagej/imagej-launcher/issues/22. Signed-off-by: Johannes Schindelin --- .../annotations/AnnotationProcessor.java | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/scijava/annotations/AnnotationProcessor.java b/src/main/java/org/scijava/annotations/AnnotationProcessor.java index 778d909fa..4a7cf4880 100644 --- a/src/main/java/org/scijava/annotations/AnnotationProcessor.java +++ b/src/main/java/org/scijava/annotations/AnnotationProcessor.java @@ -32,7 +32,9 @@ package org.scijava.annotations; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -62,6 +64,7 @@ import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic.Kind; +import javax.tools.FileObject; import javax.tools.StandardLocation; import org.scijava.annotations.AbstractIndexWriter.StreamFactory; @@ -234,10 +237,27 @@ public InputStream openInput(String annotationName) throws IOException { @Override public OutputStream openOutput(String annotationName) throws IOException { final List originating = originatingElements.get(annotationName); - return filer.createResource(StandardLocation.CLASS_OUTPUT, "", - Index.INDEX_PREFIX + annotationName, - originating.toArray(new Element[originating.size()])) - .openOutputStream(); + final String path = Index.INDEX_PREFIX + annotationName; + final FileObject fileObject = filer.createResource(StandardLocation.CLASS_OUTPUT, "", + path, originating.toArray(new Element[originating.size()])); + + /* + * Verify that the generated file is in the META-INF/json/ subdirectory; + * Despite our asking for it explicitly, the DefaultFileManager will + * strip out the directory if javac was called without an explicit + * output directory (i.e. without -d option). + */ + final String uri = fileObject.toUri().toString(); + if (uri != null && uri.endsWith("/" + path)) { + return fileObject.openOutputStream(); + } + final String prefix = uri.substring(0, uri.length() - annotationName.length()); + final File file = new File(prefix + path); + final File parent = file.getParentFile(); + if (parent != null && !parent.isDirectory() && !parent.mkdirs()) { + throw new IOException("Could not create directory: " + parent); + } + return new FileOutputStream(file); } @Override From c637b291f67406944f55a436a7c12c441a9ec4ee Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 7 Oct 2014 18:11:59 +0200 Subject: [PATCH 2/2] Let Eclipse clean up AnnotationProcessor's source code Signed-off-by: Johannes Schindelin --- .../annotations/AnnotationProcessor.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/scijava/annotations/AnnotationProcessor.java b/src/main/java/org/scijava/annotations/AnnotationProcessor.java index 4a7cf4880..fe0a5c26b 100644 --- a/src/main/java/org/scijava/annotations/AnnotationProcessor.java +++ b/src/main/java/org/scijava/annotations/AnnotationProcessor.java @@ -93,14 +93,14 @@ public boolean process(final Set elements, try { writer.write(writer); } - catch (IOException e) { + catch (final IOException e) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); e.printStackTrace(new PrintStream(out)); try { out.close(); processingEnv.getMessager().printMessage(Kind.ERROR, out.toString()); } - catch (IOException e2) { + catch (final IOException e2) { processingEnv.getMessager().printMessage(Kind.ERROR, e2.getMessage() + " while printing " + e.getMessage()); } @@ -155,8 +155,9 @@ public void add(final TypeElement element) { } @SuppressWarnings("unchecked") - private Map adapt(List mirrors, - TypeMirror annotationType) + private Map adapt( + final List mirrors, + final TypeMirror annotationType) { final Map result = new TreeMap(); for (final AnnotationMirror mirror : mirrors) { @@ -211,7 +212,8 @@ else if (o instanceof VariableElement) { } private AnnotationMirror getMirror(final TypeElement element) { - for (AnnotationMirror candidate : utils.getAllAnnotationMirrors(element)) + for (final AnnotationMirror candidate : utils + .getAllAnnotationMirrors(element)) { final Name binaryName = utils.getBinaryName((TypeElement) candidate.getAnnotationType() @@ -224,7 +226,9 @@ private AnnotationMirror getMirror(final TypeElement element) { } @Override - public InputStream openInput(String annotationName) throws IOException { + public InputStream openInput(final String annotationName) + throws IOException + { try { return filer.getResource(StandardLocation.CLASS_OUTPUT, "", Index.INDEX_PREFIX + annotationName).openInputStream(); @@ -235,11 +239,14 @@ public InputStream openInput(String annotationName) throws IOException { } @Override - public OutputStream openOutput(String annotationName) throws IOException { + public OutputStream openOutput(final String annotationName) + throws IOException + { final List originating = originatingElements.get(annotationName); final String path = Index.INDEX_PREFIX + annotationName; - final FileObject fileObject = filer.createResource(StandardLocation.CLASS_OUTPUT, "", - path, originating.toArray(new Element[originating.size()])); + final FileObject fileObject = + filer.createResource(StandardLocation.CLASS_OUTPUT, "", path, + originating.toArray(new Element[originating.size()])); /* * Verify that the generated file is in the META-INF/json/ subdirectory; @@ -251,7 +258,8 @@ public OutputStream openOutput(String annotationName) throws IOException { if (uri != null && uri.endsWith("/" + path)) { return fileObject.openOutputStream(); } - final String prefix = uri.substring(0, uri.length() - annotationName.length()); + final String prefix = + uri.substring(0, uri.length() - annotationName.length()); final File file = new File(prefix + path); final File parent = file.getParentFile(); if (parent != null && !parent.isDirectory() && !parent.mkdirs()) { @@ -261,7 +269,7 @@ public OutputStream openOutput(String annotationName) throws IOException { } @Override - public boolean isClassObsolete(String className) { + public boolean isClassObsolete(final String className) { return false; }