Skip to content

Commit 35ca6b0

Browse files
committed
Fix annotation processing when running javac without -d <directory>
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 imagej/imagej-launcher#22. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 8e11e2e commit 35ca6b0

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/main/java/org/scijava/annotations/AnnotationProcessor.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
package org.scijava.annotations;
3333

3434
import java.io.ByteArrayOutputStream;
35+
import java.io.File;
3536
import java.io.FileNotFoundException;
37+
import java.io.FileOutputStream;
3638
import java.io.IOException;
3739
import java.io.InputStream;
3840
import java.io.OutputStream;
@@ -62,6 +64,7 @@
6264
import javax.lang.model.util.Elements;
6365
import javax.lang.model.util.Types;
6466
import javax.tools.Diagnostic.Kind;
67+
import javax.tools.FileObject;
6568
import javax.tools.StandardLocation;
6669

6770
import org.scijava.annotations.AbstractIndexWriter.StreamFactory;
@@ -234,10 +237,27 @@ public InputStream openInput(String annotationName) throws IOException {
234237
@Override
235238
public OutputStream openOutput(String annotationName) throws IOException {
236239
final List<Element> originating = originatingElements.get(annotationName);
237-
return filer.createResource(StandardLocation.CLASS_OUTPUT, "",
238-
Index.INDEX_PREFIX + annotationName,
239-
originating.toArray(new Element[originating.size()]))
240-
.openOutputStream();
240+
final String path = Index.INDEX_PREFIX + annotationName;
241+
final FileObject fileObject = filer.createResource(StandardLocation.CLASS_OUTPUT, "",
242+
path, originating.toArray(new Element[originating.size()]));
243+
244+
/*
245+
* Verify that the generated file is in the META-INF/json/ subdirectory;
246+
* Despite our asking for it explicitly, the DefaultFileManager will
247+
* strip out the directory if javac was called without an explicit
248+
* output directory (i.e. without <code>-d</code> option).
249+
*/
250+
final String uri = fileObject.toUri().toString();
251+
if (uri != null && uri.endsWith("/" + path)) {
252+
return fileObject.openOutputStream();
253+
}
254+
final String prefix = uri.substring(0, uri.length() - annotationName.length());
255+
final File file = new File(prefix + path);
256+
final File parent = file.getParentFile();
257+
if (parent != null && !parent.isDirectory() && !parent.mkdirs()) {
258+
throw new IOException("Could not create directory: " + parent);
259+
}
260+
return new FileOutputStream(file);
241261
}
242262

243263
@Override

0 commit comments

Comments
 (0)