ClassNotFoundException when parsing in sbt test #52

Open
yuki24 opened this Issue Apr 13, 2012 · 4 comments

Projects

None yet

4 participants

@yuki24
yuki24 commented Apr 13, 2012

When I run this spec with sbt test:

case class Child(id: Int)
case class Parent(child: Child)

class FooSpecs extends Specification {
  var bar = parse[Parent]("""{"child":{"id":1}}""")

  // some tests...

}

I get ClassNotFoundException:

java.lang.ClassNotFoundException: <empty>.Child
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at com.codahale.jerkson.util.CaseClassSigParser$.loadClass(CaseClassSigParser.scala:153)
    at com.codahale.jerkson.util.CaseClassSigParser$.typeRef2JavaType(CaseClassSigParser.scala:111)
    at com.codahale.jerkson.util.CaseClassSigParser$$anonfun$parse$2.apply(CaseClassSigParser.scala:86)
    at com.codahale.jerkson.util.CaseClassSigParser$$anonfun$parse$2.apply(CaseClassSigParser.scala:84)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:200)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:200)
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
    at scala.collection.immutable.List.foreach(List.scala:45)
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:200)
    at scala.collection.immutable.List.flatMap(List.scala:45)
    at com.codahale.jerkson.util.CaseClassSigParser$.parse(CaseClassSigParser.scala:84)
    at com.codahale.jerkson.deser.CaseClassDeserializer.<init>(CaseClassDeserializer.scala:20)
    at com.codahale.jerkson.deser.ScalaDeserializers.findBeanDeserializer(ScalaDeserializers.scala:94)
    at org.codehaus.jackson.map.deser.BeanDeserializerFactory._findCustomBeanDeserializer(BeanDeserializerFactory.java:482)
    at org.codehaus.jackson.map.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:599)
    at org.codehaus.jackson.map.deser.StdDeserializerProvider._createDeserializer(StdDeserializerProvider.java:401)
    at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:310)
    at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:290)
    at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:159)
    at org.codehaus.jackson.map.deser.StdDeserializerProvider.findTypedValueDeserializer(StdDeserializerProvider.java:180)
    at org.codehaus.jackson.map.ObjectMapper._findRootDeserializer(ObjectMapper.java:2829)
    at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2699)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315)
    at com.codahale.jerkson.Parser$class.parse(Parser.scala:83)
    at com.codahale.jerkson.Json$.parse(Json.scala:6)
    at com.codahale.jerkson.Parser$class.parse(Parser.scala:14)
    at com.codahale.jerkson.Json$.parse(Json.scala:6)
    at FooSpecs.<init>(hoge.scala:8)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.specs2.reflect.Classes$class.createInstanceFor(Classes.scala:98)
    at org.specs2.reflect.Classes$.createInstanceFor(Classes.scala:130)
    at org.specs2.reflect.Classes$$anonfun$create$1.apply(Classes.scala:19)
    at org.specs2.control.Exceptions$class.trye(Exceptions.scala:82)
    at org.specs2.control.Exceptions$.trye(Exceptions.scala:98)
    at org.specs2.reflect.Classes$class.create(Classes.scala:19)
    at org.specs2.reflect.Classes$.create(Classes.scala:130)
    at org.specs2.runner.TestInterfaceRunner.toRun(TestInterfaceRunner.scala:69)
    at org.specs2.runner.TestInterfaceRunner.runSpecification(TestInterfaceRunner.scala:58)
    at org.specs2.runner.TestInterfaceRunner.run(TestInterfaceRunner.scala:54)
    at sbt.TestRunner.delegateRun(TestFramework.scala:61)
    at sbt.TestRunner.run(TestFramework.scala:55)
    at sbt.TestRunner.runTest$1(TestFramework.scala:75)
    at sbt.TestRunner.run(TestFramework.scala:84)
    at sbt.TestFramework$$anonfun$6$$anonfun$apply$8$$anonfun$7$$anonfun$apply$9.apply(TestFramework.scala:183)
    at sbt.TestFramework$$anonfun$6$$anonfun$apply$8$$anonfun$7$$anonfun$apply$9.apply(TestFramework.scala:183)
    at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:195)
    at sbt.TestFramework$$anonfun$6$$anonfun$apply$8$$anonfun$7.apply(TestFramework.scala:183)
    at sbt.TestFramework$$anonfun$6$$anonfun$apply$8$$anonfun$7.apply(TestFramework.scala:183)
    at sbt.Tests$$anonfun$makeParallel$1$$anonfun$apply$7.apply(Tests.scala:113)
    at sbt.Tests$$anonfun$makeParallel$1$$anonfun$apply$7.apply(Tests.scala:113)
    at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:47)
    at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:47)
    at sbt.std.Transform$$anon$5.work(System.scala:67)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:221)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:221)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
    at sbt.Execute.work(Execute.scala:227)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:221)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:221)
    at sbt.CompletionService$$anon$1$$anon$2.call(CompletionService.scala:26)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)

But when I do the exactly same on sbt console like this:

scala> import com.codahale.jerkson.Json._
import com.codahale.jerkson.Json._

scala> import com.foo.bar._
import com.foo.bar._ // This contains Parent and Child class

scala> parse[Parent]("""{"child":{"id":1}}""")
res1: com.foo.bar.Parent = Parent(Child(1))

It just works! I don't know why this doesn't fail in sbt console and it does in sbt test. I've tried @softprops' solution described on #38 but still no luck. The version of Scala is 2.9.1 and sbt is 0.11.2. Any advice/solutions?

@softprops

This ones a toughy. I have think I have fixed most cases in ls-sbt with this workaround but it feels like a fickle solution. I don't think its jerkson's fault that it doesn't work in another library's runtime. One thing to note in my class loader loan workaround is that you only want to steal it for the shortest amount of time possible before returning the current class loader to its original state. This trick is very sleight-of-hand so I don't expect it to work all the time though I'd like it too :) If you come up with a good solution, plz also let me know. I prefer jerkson but this issue sometimes leads me towards wanting to choose a different library for json parsing solely in sbt's runtime.

@yuki24
yuki24 commented Apr 13, 2012

yeah, this doesn't jerkson's fault and probably sbt-related problem(sorry for raising this kind of problem on this repo). It looks like setting class loader like #25 might help, but I'm not sure what happens if I switch the class loader for the long amount of time.
What I did now(which is silly) is to change nested classes to Map[String, Any]...

@jirijakes

I had similar problem with Maven. I got this exception only when the case classes were in a default package. Once I moved them to another package, it worked.

@dkristian

In case it helps anyone, I had a similar problem trying to parse into a case class that was nested inside a scala object. Moving the case class up to the package level got around the problem I was having.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment