Skip to content

Commit

Permalink
Merge pull request #10253 from som-snytt/issue/12705-repl-reflective-…
Browse files Browse the repository at this point in the history
…class-load

Avoid name check when loading repl products
  • Loading branch information
lrytz committed Jan 6, 2023
2 parents 83908d9 + 70862c4 commit 91f0f66
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/repl/scala/tools/nsc/interpreter/IMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -347,15 +347,23 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade
override def translateEnclosingClass(n: String): Option[String] = symbolOfTerm(n).enclClass.toOption map flatPath

/** If unable to find a resource foo.class, try taking foo as a symbol in scope
* and use its java class name as a resource to load.
*
* \$intp.classLoader classBytes "Bippy" or \$intp.classLoader getResource "Bippy.class" just work.
*/
* and use its java class name as a resource to load.
*
* \$intp.classLoader classBytes "Bippy" or \$intp.classLoader getResource "Bippy.class" just work.
*/
private class TranslatingClassLoader(parent: ClassLoader) extends AbstractFileClassLoader(replOutput.dir, parent) {
override protected def findAbstractFile(name: String): AbstractFile = super.findAbstractFile(name) match {
case null if _initializeComplete => translateSimpleResource(name).map(super.findAbstractFile).orNull
case file => file
}
// if the name was mapped by findAbstractFile, supply null name to avoid name check in defineClass
override protected def findClass(name: String): Class[_] = {
val bytes = classBytes(name)
if (bytes.length == 0)
throw new ClassNotFoundException(name)
else
defineClass(/*name=*/null, bytes, 0, bytes.length, protectionDomain)
}
}
private def makeClassLoader(): AbstractFileClassLoader =
new TranslatingClassLoader({
Expand Down
11 changes: 11 additions & 0 deletions test/files/run/t12705.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

scala> case class Person(name: String)
class Person

scala> $intp.classLoader.getResource("Person.class")
val res0: java.net.URL = memory:(memory)/Person.class

scala> $intp.classLoader.loadClass("Person")
val res1: Class[_] = class Person

scala> :quit
20 changes: 20 additions & 0 deletions test/files/run/t12705.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

import scala.tools.partest.ReplTest

object Test extends ReplTest {
def code =
"""|case class Person(name: String)
|$intp.classLoader.getResource("Person.class")
|$intp.classLoader.loadClass("Person")""".stripMargin
//|classOf[Person].getClassLoader.loadClass("Person")""".stripMargin
}

/*
java.lang.NoClassDefFoundError: Person (wrong name: Person)
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1013)
at scala.reflect.internal.util.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:77)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 76 elided
*/

0 comments on commit 91f0f66

Please sign in to comment.