summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-02-03 23:00:51 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2015-02-07 07:45:55 +0100
commitc283ce145a7b34f18deeeac5c3de2b102169e074 (patch)
tree70c31221356af895e3576c88792e3dae43386faa
parent357c15710d9db5d1a8a07cf91af7c24ae6ee884d (diff)
downloadscala-c283ce145a7b34f18deeeac5c3de2b102169e074.tar.gz
scala-c283ce145a7b34f18deeeac5c3de2b102169e074.tar.bz2
scala-c283ce145a7b34f18deeeac5c3de2b102169e074.zip
Test java reflection on scala library / reflect / compiler jars
Run a number of Java reflection operations on all classes in scala library / reflect / compiler. The test is based on a draft by Jason.
-rw-r--r--build-ant-macros.xml2
-rw-r--r--test/files/jvm/innerClassEnclMethodJavaReflection.scala65
-rw-r--r--versions.properties2
3 files changed, 68 insertions, 1 deletions
diff --git a/build-ant-macros.xml b/build-ant-macros.xml
index 609f106d09..259d6a6eb6 100644
--- a/build-ant-macros.xml
+++ b/build-ant-macros.xml
@@ -751,6 +751,7 @@
<attribute name="srcdir" default="files"/> <!-- TODO: make targets for `pending` and other subdirs -->
<attribute name="colors" default="${partest.colors}"/>
<attribute name="scalacOpts" default="${partest.scalac_opts} ${scalac.args.optimise}"/>
+ <attribute name="javaOpts" default="${env.ANT_OPTS}"/>
<attribute name="pcp" default="${toString:partest.compilation.path}"/>
<attribute name="kinds"/>
<sequential>
@@ -759,6 +760,7 @@
kinds="@{kinds}"
colors="@{colors}"
scalacOpts="@{scalacOpts}"
+ javaOpts="@{javaOpts}"
compilationpath="@{pcp}"/>
</sequential>
</macrodef>
diff --git a/test/files/jvm/innerClassEnclMethodJavaReflection.scala b/test/files/jvm/innerClassEnclMethodJavaReflection.scala
new file mode 100644
index 0000000000..ee39cb43bf
--- /dev/null
+++ b/test/files/jvm/innerClassEnclMethodJavaReflection.scala
@@ -0,0 +1,65 @@
+import scala.reflect.io._
+import java.net.URLClassLoader
+
+object Test extends App {
+ val jarsOrDirectories = Set("partest.lib", "partest.reflect", "partest.comp") map sys.props
+
+ object AllowedMissingClass {
+ // Some classes in scala-compiler.jar have references to jline / ant classes, which seem to be
+ // not on the classpath. We just skip over those classes.
+ // PENDING: for now we also allow missing $anonfun classes: the optimizer may eliminate some closures
+ // that are refferred to in EnclosingClass attributes. SI-9136
+ val allowedMissingPackages = Set("jline", "org.apache.tools.ant", "$anonfun")
+
+ def ok(t: Throwable) = {
+ allowedMissingPackages.exists(p => t.getMessage.replace('/', '.').contains(p))
+ }
+
+ def unapply(t: Throwable): Option[Throwable] = t match {
+ case _: NoClassDefFoundError | _: ClassNotFoundException | _: TypeNotPresentException if ok(t) => Some(t)
+ case _ => None
+ }
+ }
+
+ jarsOrDirectories foreach testClasses
+
+ def testClasses(jarOrDirectory: String): Unit = {
+ val classPath = AbstractFile.getDirectory(new java.io.File(jarOrDirectory))
+
+ def flatten(f: AbstractFile): Iterator[AbstractFile] =
+ if (f.isClassContainer) f.iterator.flatMap(flatten)
+ else Iterator(f)
+
+ val classFullNames = flatten(classPath).filter(_.hasExtension("class")).map(_.path.replace("/", ".").replaceAll(".class$", ""))
+
+ // it seems that Class objects can only be GC'd together with their class loader
+ // (http://stackoverflow.com/questions/2433261/when-and-how-are-classes-garbage-collected-in-java)
+ // if we just use the same class loader for the entire test (Class.forName), we run out of PermGen
+ // even with that, we still neeed a PermGen of 90M or so, the default 64 is not enough. I tried
+ // using one class loader per 100 classes, but that didn't help, the classes didn't get GC'd.
+ val classLoader = new URLClassLoader(Array(classPath.toURL))
+
+ val faulty = new collection.mutable.ListBuffer[(String, Throwable)]
+
+ def tryGetClass(name: String) = try {
+ Some[Class[_]](classLoader.loadClass(name))
+ } catch {
+ case AllowedMissingClass(_) => None
+ }
+
+ for (name <- classFullNames; cls <- tryGetClass(name)) {
+ try {
+ cls.getEnclosingMethod
+ cls.getEnclosingClass
+ cls.getEnclosingConstructor
+ cls.getDeclaredClasses
+ } catch {
+ case AllowedMissingClass(_) =>
+ case t: Throwable => faulty += ((name, t))
+ }
+ }
+
+ if (faulty.nonEmpty)
+ println(faulty.toList mkString "\n")
+ }
+}
diff --git a/versions.properties b/versions.properties
index 88271da4eb..64b5e51f32 100644
--- a/versions.properties
+++ b/versions.properties
@@ -27,7 +27,7 @@ actors-migration.version.number=1.1.0
jline.version=2.12
# external modules, used internally (not shipped)
-partest.version.number=1.0.3
+partest.version.number=1.0.5
scalacheck.version.number=1.11.4
# TODO: modularize the compiler