Repository: jtablesaw/tablesaw
Pull request #505 (2019-03-30 23:44:10)

Switch from reflections to classgraph
Thanks for contributing.

- [X] Tick to sign-off your agreement to the [Developer Certificate of Origin (DCO) 1.1](https://developercertificate.org)

## Description

Closes https://github.com/jtablesaw/tablesaw/issues/503

It turns out reflections is unmaintained. I switched to another library, which is better maintained and solves the log issue

## Testing

Covered by existing tests



Patch:
diff --git a/core/pom.xml b/core/pom.xml
index a68b1ec8..859c4055 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -111,9 +111,9 @@
             <version>2.7.5</version>
         </dependency>
         <dependency>
-            <groupId>org.reflections</groupId>
-            <artifactId>reflections</artifactId>
-            <version>0.9.11</version>
+            <groupId>io.github.classgraph</groupId>
+            <artifactId>classgraph</artifactId>
+            <version>4.8.22</version>
         </dependency>
         <dependency>
             <groupId>com.github.haifengl</groupId>
diff --git a/core/src/main/java/tech/tablesaw/api/Table.java b/core/src/main/java/tech/tablesaw/api/Table.java
index 35f2be47..d49180aa 100644
--- a/core/src/main/java/tech/tablesaw/api/Table.java
+++ b/core/src/main/java/tech/tablesaw/api/Table.java
@@ -23,15 +23,14 @@ import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 
-import org.reflections.Reflections;
-
 import com.google.common.base.Preconditions;
 import com.google.common.primitives.Ints;
 
+import io.github.classgraph.ClassGraph;
+import io.github.classgraph.ScanResult;
 import it.unimi.dsi.fastutil.ints.IntArrays;
 import it.unimi.dsi.fastutil.ints.IntComparator;
 import tech.tablesaw.aggregate.AggregateFunction;
@@ -117,23 +116,16 @@ public class Table extends Relation implements Iterable<Row> {
     }
 
     private static void autoRegisterReadersAndWriters() {
-        Reflections reflections = new Reflections("tech.tablesaw.io");
-        @SuppressWarnings("rawtypes")
-        Set<Class<? extends DataWriter>> writerClasses = reflections.getSubTypesOf(DataWriter.class);
-        for (Class<?> clazz : writerClasses) {
-            try {
-                Class.forName(clazz.getCanonicalName());
-            } catch (ClassNotFoundException e) {
-                new IllegalStateException(e);
-            }
-        }
-        @SuppressWarnings("rawtypes")
-        Set<Class<? extends DataReader>> readerClasses = reflections.getSubTypesOf(DataReader.class);
-        for (Class<?> clazz : readerClasses) {
-            try {
-                Class.forName(clazz.getCanonicalName());
-            } catch (ClassNotFoundException e) {
-                new IllegalStateException(e);
+        try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("tech.tablesaw.io").scan()) {
+            List<String> classes = new ArrayList<>();
+            classes.addAll(scanResult.getClassesImplementing(DataWriter.class.getName()).getNames());
+            classes.addAll(scanResult.getClassesImplementing(DataReader.class.getName()).getNames());
+            for (String clazz : classes) {
+                try {
+                    Class.forName(clazz);
+                } catch (ClassNotFoundException e) {
+                    new IllegalStateException(e);
+                }
             }
         }
     }
diff --git a/core/src/main/java/tech/tablesaw/columns/datetimes/DateTimeParser.java b/core/src/main/java/tech/tablesaw/columns/datetimes/DateTimeParser.java
index 7d330a88..5c6feda2 100644
--- a/core/src/main/java/tech/tablesaw/columns/datetimes/DateTimeParser.java
+++ b/core/src/main/java/tech/tablesaw/columns/datetimes/DateTimeParser.java
@@ -58,7 +58,7 @@ public class DateTimeParser extends AbstractColumnParser<LocalDateTime> {
 
     public DateTimeParser(DateTimeColumnType dateTimeColumnType, ReadOptions readOptions) {
         super(dateTimeColumnType);
-        DateTimeFormatter readCsvFormatter = readOptions.dateFormatter();
+        DateTimeFormatter readCsvFormatter = readOptions.dateTimeFormatter();
         if (readCsvFormatter != null) {
             formatter = readCsvFormatter;
         }


Test patch:
diff --git a/core/src/test/java/tech/tablesaw/io/csv/CsvReaderTest.java b/core/src/test/java/tech/tablesaw/io/csv/CsvReaderTest.java
index fcc4c87e..dd312e40 100644
--- a/core/src/test/java/tech/tablesaw/io/csv/CsvReaderTest.java
+++ b/core/src/test/java/tech/tablesaw/io/csv/CsvReaderTest.java
@@ -70,7 +70,7 @@ public class CsvReaderTest {
                         + "1234567890" + LINE_END);
 
         final int maxCharsPerColumn = 12;
-        
+
         Table result = Table.read().csv(CsvReadOptions.builder(reader).maxCharsPerColumn(maxCharsPerColumn));
         assertEquals(2, result.rowCount());
     }
@@ -208,26 +208,18 @@ public class CsvReaderTest {
     }
 
     @Test
-    public void testLocalDateTimeDetectionEnglish() {
+    public void testDateTimeDetection() {
 
         final Reader reader = new StringReader(
               "Date" + LINE_END
-            + "09-Nov-2014 13:03" + LINE_END
-            + "09-Oct-2014 13:03" + LINE_END
-            + "09-Sep-2014 13:03" + LINE_END
-            + "09-Aug-2014 13:03" + LINE_END
-            + "09-Jul-2014 13:03" + LINE_END
-            + "09-Jun-2014 13:03" + LINE_END);
+            + "09-Nov-2014 13:03:04" + LINE_END
+            + "09-Oct-2014 13:03:56" + LINE_END);
 
         final boolean header = true;
-        final char delimiter = ',';
-        final boolean useSampling = true;
 
         CsvReadOptions options = CsvReadOptions.builder(reader)
                 .header(header)
-                .separator(delimiter)
-                .sample(useSampling)
-                .locale(Locale.ENGLISH)
+                .dateTimeFormat("dd-MMM-yyyy HH:mm:ss")
                 .build();
 
         final List<ColumnType> actual = asList(new CsvReader().detectColumnTypes(reader, options));