Help with org.reflections api

If you do

val refl = new org.reflections.Reflections()

instead of

val refl = new org.reflections.Reflections("")

then it also works.

Looks like using empty string there introduces undefined behavior. Perhaps depending on JVM version and/or ClassLoaders which happen to be used.

2 Likes

Yes, an empty string just does not make sense here. It’s still puzzling that it works sometimes…

1 Like

I don’t understand the meaning of the argument to Reflections(...). What should I be using?

When I use Reflections() in reflections release 0.9.12, then I get a runtime error


Scanner SubTypesScanner was not configured
org.reflections.ReflectionsException: Scanner SubTypesScanner was not configured
	at org.reflections.Store.get(Store.java:39)
	at org.reflections.Store.get(Store.java:61)
	at org.reflections.Store.get(Store.java:46)
	at org.reflections.Store.getAll(Store.java:93)
	at org.reflections.Reflections.getSubTypesOf(Reflections.java:404)

And if I revert to 0.9.11, I get again get the behavior that it is unable to find the subtypes/subclasses of List[Any].

It’s all documented here

public Reflections(String prefix,
                   Scanner... scanners)

a convenient constructor for scanning within a package prefix.

this actually create a Configuration with:
- urls that contain resources with name prefix
- filterInputsBy where name starts with the given prefix
- scanners set to the given scanners, otherwise defaults to TypeAnnotationsScanner and SubTypesScanner.

That depends on your use case. If you want to scan the whole classpath, just use the zero argument constructor, otherwise use a non-empty string.

Try to create a reproducible example and give us more details about your environment.

I think I saw that, but I didn’t understand what a “package prefix” is. That’s why I originally chose “” because empty string is a prefix of every string.

I just noticed this could be a Scala / Java interop problem. What happens if you call it this way:

val refl = new org.reflections.Reflections(Array.empty[AnyRef]: _*)

?

working on a small test case. I have noticed that the same test which fails when I run the tests from within IntelliJ succeeds when I run from sbt at the unix command line.

I tried your suggested test:

  test("reflect.getSubTypesOf"){
    //val reflect = new org.reflections.Reflections()
    val reflect = new org.reflections.Reflections(Array.empty[AnyRef]: _*)
    assert(reflect.getSubTypesOf(classOf[List[Any]]).toArray.contains(List(1,2,3).getClass))
    assert(reflect.getSubTypesOf(classOf[List[Any]]).toArray.contains(List.empty.getClass))
  }

I get the following error very similar to before.


Scanner SubTypesScanner was not configured
org.reflections.ReflectionsException: Scanner SubTypesScanner was not configured
	at org.reflections.Store.get(Store.java:39)
	at org.reflections.Store.get(Store.java:61)
	at org.reflections.Store.get(Store.java:46)
	at org.reflections.Store.getAll(Store.java:93)
	at org.reflections.Reflections.getSubTypesOf(Reflections.java:404)
	at genus.TypesTest.$anonfun$new$1(TypesTest.scala:32)
	at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
	at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
	at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
	at org.scalatest.Transformer.apply(Transformer.scala:22)
	at org.scalatest.Transformer.apply(Transformer.scala:20)
	at org.scalatest.funsuite.AnyFunSuiteLike$$anon$1.apply(AnyFunSuiteLike.scala:189)
	at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
	at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)

If I downgrade to “reflections” % “0.9.11”, I get a different error which is just the test assertion failing.


Array() did not contain class scala.collection.immutable.$colon$colon
ScalaTestFailureLocation: genus.TypesTest at (TypesTest.scala:31)
org.scalatest.exceptions.TestFailedException: Array() did not contain class scala.collection.immutable.$colon$colon
	at org.scalatest.Assertions.newAssertionFailedException(Assertions.scala:472)
	at org.scalatest.Assertions.newAssertionFailedException$(Assertions.scala:471)

However, this test passes when running sbt from unix command line.

BTW I don’t see the only person seeing an issue with Scanner SubTypesScanner was not configured. After migrating to 0.9.12, Getting exception : org.reflections.RflectionException: Scanner SubTypeScanner was not configured , even after configuring the scanner. · Issue #273 · ronmamo/reflections · GitHub

I tried this on a different laptop which is IntelliJ Ultimate Edition. The test passes.

I believe IntelliJ gives me the java command line which runs the tests. In the IntelliJ which fails, he is what IntelliJ claims to be the command line

"/Applications/IntelliJ IDEA CE.app/Contents/jbr/Contents/Home/bin/java" "-javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=50543:/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Users/jnewton/Library/Application Support/JetBrains/IdeaIC2021.1/plugins/Scala/lib/runners.jar:/Users/jnewton/Repos/regular-type-expression/cl-robdd-scala/target/scala-2.13/test-classes:/Users/jnewton/Repos/regular-type-expression/cl-robdd-scala/target/scala-2.13/classes:/Users/jnewton/.ivy2/cache/com.google.guava/guava/bundles/guava-20.0.jar:/Users/jnewton/.ivy2/cache/org.javassist/javassist/bundles/javassist-3.21.0-GA.jar:/Users/jnewton/.ivy2/cache/org.reflections/reflections/jars/reflections-0.9.11.jar:/Users/jnewton/.ivy2/cache/org.scala-lang.modules/scala-xml_2.13/bundles/scala-xml_2.13-1.2.0.jar:/Users/jnewton/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.13.3.jar:/Users/jnewton/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.13.3.jar:/Users/jnewton/.ivy2/cache/org.scalactic/scalactic_2.13/bundles/scalactic_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-compatible/bundles/scalatest-compatible-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-core_2.13/bundles/scalatest-core_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-diagrams_2.13/bundles/scalatest-diagrams_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-featurespec_2.13/bundles/scalatest-featurespec_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-flatspec_2.13/bundles/scalatest-flatspec_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-freespec_2.13/bundles/scalatest-freespec_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-funspec_2.13/bundles/scalatest-funspec_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-funsuite_2.13/bundles/scalatest-funsuite_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-matchers-core_2.13/bundles/scalatest-matchers-core_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-mustmatchers_2.13/bundles/scalatest-mustmatchers_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-propspec_2.13/bundles/scalatest-propspec_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-refspec_2.13/bundles/scalatest-refspec_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-shouldmatchers_2.13/bundles/scalatest-shouldmatchers_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest-wordspec_2.13/bundles/scalatest-wordspec_2.13-3.2.0.jar:/Users/jnewton/.ivy2/cache/org.scalatest/scalatest_2.13/bundles/scalatest_2.13-3.2.0.jar" org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner -s genus.TypesTest -testName reflect.getSubTypesOf -showProgressMessages true
Testing started at 12:23 ...

In the IntelliJ where the test works correctly, here is the supposed command line

/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/bin/java -Dvisualvm.id=214826607905091 "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=50780:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Users/jimka/Library/Application Support/JetBrains/IntelliJIdea2021.1/plugins/Scala/lib/runners.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/lib/tools.jar:/Users/jimka/Repos/regular-type-expression/cl-robdd-scala/target/scala-2.13/test-classes:/Users/jimka/Repos/regular-type-expression/cl-robdd-scala/target/scala-2.13/classes:/Users/jimka/.ivy2/cache/com.google.guava/guava/bundles/guava-20.0.jar:/Users/jimka/.ivy2/cache/org.javassist/javassist/bundles/javassist-3.21.0-GA.jar:/Users/jimka/.ivy2/cache/org.reflections/reflections/jars/reflections-0.9.11.jar:/Users/jimka/.ivy2/cache/org.scala-lang.modules/scala-xml_2.13/bundles/scala-xml_2.13-1.2.0.jar:/Users/jimka/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.13.3.jar:/Users/jimka/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.13.3.jar:/Users/jimka/.ivy2/cache/org.scalactic/scalactic_2.13/bundles/scalactic_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-compatible/bundles/scalatest-compatible-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-core_2.13/bundles/scalatest-core_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-diagrams_2.13/bundles/scalatest-diagrams_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-featurespec_2.13/bundles/scalatest-featurespec_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-flatspec_2.13/bundles/scalatest-flatspec_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-freespec_2.13/bundles/scalatest-freespec_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-funspec_2.13/bundles/scalatest-funspec_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-funsuite_2.13/bundles/scalatest-funsuite_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-matchers-core_2.13/bundles/scalatest-matchers-core_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-mustmatchers_2.13/bundles/scalatest-mustmatchers_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-propspec_2.13/bundles/scalatest-propspec_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-refspec_2.13/bundles/scalatest-refspec_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-shouldmatchers_2.13/bundles/scalatest-shouldmatchers_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest-wordspec_2.13/bundles/scalatest-wordspec_2.13-3.2.0.jar:/Users/jimka/.ivy2/cache/org.scalatest/scalatest_2.13/bundles/scalatest_2.13-3.2.0.jar" org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner -s genus.TypesTest -testName reflect.getSubTypesOf -showProgressMessages true
Testing started at 12:32 ...

So, the failing one uses the internal Jetbrains Java runtime, the other some system JDK, probably Oracle.

And there seem to be unresolved issues with the library you’re using, which is apparently unmaintained, currently.

You could try to use a fork of the library and add this to your project via https://jitpack.io/

Any idea why IntelliJ is using /Applications/IntelliJ IDEA CE.app/Contents/jbr/Contents/Home/bin/java ?

There is a JDK selection in the Preferences dialog. But changing the JDK selection seems to have no effect on which have path is used when launching the tests.

I’ve posted a question here. JetBrains/intellij-scala - Gitter

You’re editing the JDK used for the Scala compile server. The runtime used when running an application is configured in its run configuration – next to the green play button open the dropdown and select “Edit configuration…”

OK, I managed to change the java version to /Library/Java/JavaVirtualMachines/openjdk8/Contents/Home/bin/java and the tests pass, but with java /Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/bin/java they fail.


Array() did not contain class scala.collection.immutable.$colon$colon
ScalaTestFailureLocation: genus.TypesTest at (TypesTest.scala:30)
org.scalatest.exceptions.TestFailedException: Array() did not contain class scala.collection.immutable.$colon$colon
	at org.scalatest.Assertions.newAssertionFailedException(Assertions.scala:472)

Here is the code that fails/succeeds.

  test("reflect.getSubTypesOf"){
    val reflect = new org.reflections.Reflections()
    assert(reflect.getSubTypesOf(classOf[List[Any]]).toArray.contains(List(1,2,3).getClass))
    assert(reflect.getSubTypesOf(classOf[List[Any]]).toArray.contains(List.empty.getClass))
  }

I have reported this as an issue on GitHub, but I don’t know if my explanation will be useful as it describes the use of the api via Scala. If the maintainers are not Scala Users, then my explanation perhaps makes no sense.

How can I know whether this issue is a bug in the reflections library, or a bug in Scala, or a bug in Java, or a bug in IntelliJ?