Skip to content
This repository has been archived by the owner on Mar 14, 2019. It is now read-only.

Commit

Permalink
Done load or define class.
Browse files Browse the repository at this point in the history
  • Loading branch information
zhongl committed Jun 2, 2012
1 parent 4621745 commit 85ffcf0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
29 changes: 21 additions & 8 deletions console/src/main/scala/com/github/zhongl/housemd/Reflections.scala
Expand Up @@ -39,6 +39,23 @@ object Reflections {
private val D = classOf[Double]
private val d = Double.TYPE

// FIXME this is ugly, because i don't know how to get class of byte[]
private lazy val defineClassMethod = {
val m = classOf[ClassLoader].getDeclaredMethods.find { m =>
m.getName == "defineClass" && (m.getParameterTypes match {
case Array(S, _, `i`, `i`) => true
case _ => false
})
}.get
m.setAccessible(true)
m
}

def is(m: java.lang.reflect.Method) = (m.getParameterTypes match {
case Array(S, _, `i`, `i`) => true
case _ => false
})

def convert(c: Class[_], s: String): AnyRef = {
c match {
case B | `b` => Boolean.valueOf(s)
Expand All @@ -53,7 +70,7 @@ object Reflections {
def nativeToStringOf(instance: AnyRef) = instance.getClass.getName + "@" + Integer
.toHexString(identityHashCode(instance))

/** see https://github.com/zhongl/HouseMD/issues/17 */
/**see https://github.com/zhongl/HouseMD/issues/17 */
def loadOrDefine(clazz: Class[_], inClassLoader: ClassLoader) = {
val name = clazz.getName
try {
Expand All @@ -62,17 +79,13 @@ object Reflections {
case _: ClassNotFoundException =>
import Utils._

val parameterTypes = Array(classOf[String], classOf[Array[Byte]], Integer.TYPE, Integer.TYPE)

val defineClass = inClassLoader.getClass.getDeclaredMethod("defineClass", parameterTypes: _*)
defineClass.setAccessible(true)

val bytes = toBytes(clazz.getResourceAsStream(name))
val bytes = toBytes(clazz.getResourceAsStream("/" + name.replace('.', '/') + ".class"))
val zero: java.lang.Integer = 0
val length: java.lang.Integer = bytes.length

defineClass.invoke(inClassLoader, name, bytes, zero, length).asInstanceOf[Class[_]]
defineClassMethod.invoke(inClassLoader, name, bytes, zero, length).asInstanceOf[Class[_]]
}
}


}
@@ -0,0 +1,24 @@
package com.github.zhongl.housemd

import org.scalatest.FunSpec
import org.scalatest.matchers.ShouldMatchers

/**
* @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
*/
class ReflectionsSpec extends FunSpec with ShouldMatchers {
describe("Reflection") {
it("should load Advice") {
Reflections.loadOrDefine(classOf[Advice], new ClassLoader(getClass.getClassLoader) {}) should be(classOf[Advice])
}
it("should define Advice") {
Reflections.loadOrDefine(classOf[Advice], new ClassLoader() {
override def loadClass(name: String) = {
if (name == classOf[Advice].getName) throw new ClassNotFoundException()
else super.loadClass(name)
}
})
}
}

}

0 comments on commit 85ffcf0

Please sign in to comment.