diff --git a/core/src/main/java/org/jboss/jandex/Index.java b/core/src/main/java/org/jboss/jandex/Index.java
index 3c4fc75c..b652e15e 100644
--- a/core/src/main/java/org/jboss/jandex/Index.java
+++ b/core/src/main/java/org/jboss/jandex/Index.java
@@ -22,16 +22,20 @@
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
/**
* An index useful for quickly processing annotations. The index is read-only and supports
@@ -137,30 +141,50 @@ public static Index of(Class>... classes) throws IOException {
}
/**
- * Constructs an Index of class files found in the passed directories.
- * The directories are not scanned recursively.
+ * Constructs an Index of the passed files and directories. Files may be class files or JAR files.
+ * Directories are scanned for class files, but not recursively.
*
- * @param directories Directories containing class files to index
+ * @param files class files, JAR files or directories containing class files to index
* @return the index
- * @throws IllegalArgumentException if any passed {@code File} is null or not a directory
+ * @throws IllegalArgumentException if any passed {@code File} is null or not a class file, JAR file or directory
*/
- public static Index of(File... directories) throws IOException {
+ public static Index of(File... files) throws IOException {
Indexer indexer = new Indexer();
- for (File directory : directories) {
- if (directory == null || !directory.isDirectory()) {
- throw new IllegalArgumentException("not a directory: " + directory);
- }
+ for (File file : files) {
+ if (file == null) {
+ throw new IllegalArgumentException("File must not be null");
+ } else if (file.isDirectory()) {
+ File[] classFiles = file.listFiles(new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ return pathname.isFile() && pathname.getName().endsWith(".class");
+ }
+ });
- File[] sources = directory.listFiles(new FileFilter() {
- @Override
- public boolean accept(File pathname) {
- return pathname.isFile() && pathname.getName().endsWith(".class");
+ for (File classFile : classFiles) {
+ try (InputStream in = new FileInputStream(classFile)) {
+ indexer.index(in);
+ }
}
- });
-
- for (File source : sources) {
- indexer.index(new FileInputStream(source));
+ } else if (file.isFile() && file.getName().endsWith(".class")) {
+ try (InputStream in = new FileInputStream(file)) {
+ indexer.index(in);
+ }
+ } else if (file.isFile() && file.getName().endsWith(".jar")) {
+ try (JarFile jarFile = new JarFile(file)) {
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ if (entry.getName().endsWith(".class")) {
+ try (InputStream in = jarFile.getInputStream(entry)) {
+ indexer.index(in);
+ }
+ }
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Not a class file, JAR file or directory: " + file);
}
}
diff --git a/core/src/main/java/org/jboss/jandex/Indexer.java b/core/src/main/java/org/jboss/jandex/Indexer.java
index b5e9d64a..7a661b11 100644
--- a/core/src/main/java/org/jboss/jandex/Indexer.java
+++ b/core/src/main/java/org/jboss/jandex/Indexer.java
@@ -2030,8 +2030,9 @@ public ClassInfo indexClass(Class> clazz) throws IOException {
throw new IllegalArgumentException("clazz cannot be null");
}
String resourceName = '/' + clazz.getName().replace('.', '/') + ".class";
- InputStream resource = clazz.getResourceAsStream(resourceName);
- return index(resource);
+ try (InputStream resource = clazz.getResourceAsStream(resourceName)) {
+ return index(resource);
+ }
}
/**
@@ -2054,7 +2055,7 @@ public ClassInfo index(InputStream stream) throws IOException {
// Retroweaved classes may contain annotations
// Also, hierarchy info is needed regardless
- if (!isJDK11OrNewer(data))
+ if (!isJDK11OrNewer(data)) // refers to JDK 1.1, not JDK 11
return null;
initIndexMaps();
diff --git a/core/src/test/java/org/jboss/jandex/test/BasicTestCase.java b/core/src/test/java/org/jboss/jandex/test/BasicTestCase.java
index f5b75197..35fac03d 100644
--- a/core/src/test/java/org/jboss/jandex/test/BasicTestCase.java
+++ b/core/src/test/java/org/jboss/jandex/test/BasicTestCase.java
@@ -277,10 +277,19 @@ public boolean accept(File pathname) {
@Test
public void testIndexOfEmptyDirectory() throws IOException, URISyntaxException {
- URL testLocation = getClass().getResource(getClass().getSimpleName() + ".class");
- File testDirectory = new File(testLocation.toURI().resolve("../../../../"));
- Index index = Index.of(testDirectory);
- assertEquals(0, index.getKnownClasses().size());
+ File tempDir = null;
+
+ try {
+ tempDir = File.createTempFile("temp", ".dir");
+ tempDir.delete();
+ tempDir.mkdir();
+ Index index = Index.of(tempDir);
+ assertEquals(0, index.getKnownClasses().size());
+ } finally {
+ if (tempDir != null) {
+ tempDir.delete();
+ }
+ }
}
@Test
@@ -306,19 +315,43 @@ public void testIndexOfDirectoryNonClassFile() throws IOException, URISyntaxExce
}
@Test
- public void testIndexOfNonDirectory() throws IOException, URISyntaxException {
+ public void testIndexOfClassFile() throws IOException, URISyntaxException {
final URL testLocation = getClass().getResource(getClass().getSimpleName() + ".class");
final File thisClassFile = new File(testLocation.toURI());
- assertThrows(IllegalArgumentException.class, new ThrowingRunnable() {
- @Override
- public void run() throws Throwable {
- Index.of(thisClassFile);
+ Index index = Index.of(thisClassFile);
+ assertEquals(1, index.getKnownClasses().size());
+ }
+
+ @Test
+ public void testIndexOfNonClassFile() throws IOException {
+ File tempDir = null;
+ File tempFile = null;
+
+ try {
+ tempDir = File.createTempFile("temp", ".dir");
+ tempDir.delete();
+ tempDir.mkdir();
+ tempFile = File.createTempFile("dummy", ".tmp", tempDir);
+
+ File temp = tempFile;
+ assertThrows(IllegalArgumentException.class, new ThrowingRunnable() {
+ @Override
+ public void run() throws Throwable {
+ Index.of(temp);
+ }
+ });
+ } finally {
+ if (tempFile != null) {
+ tempFile.delete();
}
- });
+ if (tempDir != null) {
+ tempDir.delete();
+ }
+ }
}
@Test
- public void testIndexOfNullDirectory() throws IOException, URISyntaxException {
+ public void testIndexOfNullDirectory() {
assertThrows(IllegalArgumentException.class, new ThrowingRunnable() {
@Override
public void run() throws Throwable {