Search code examples
scalasbtlift

sbt unmanagedClasspath entry for lift compiles but not found at runtime


I have an unmanagedClasspath entry in my lift sbt file that points to the classes for an external java project. It compiles fine but I get a NoClassDefError when it runs. Below is the sbt entry followed by some of the trace of the NoClassDefError.

Any help much appreciated

Des

unmanagedClasspath in Compile += file("[Path to my project]/classes")

 ERROR n.liftweb.http.provider.HTTPProvider - Failed to Boot! Your application may not run properly
java.lang.NoClassDefFoundError: com/myproject/MyClass
    at bootstrap.liftweb.Boot.boot(Boot.scala:70) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_21]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_21]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_21]
    at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_21]
    at net.liftweb.util.ClassHelpers$$anonfun$createInvoker$1.apply(ClassHelpers.scala:364) ~[lift-util_2.9.1-2.5-RC2.jar:2.5-RC2]
    at net.liftweb.util.ClassHelpers$$anonfun$createInvoker$1.apply(ClassHelpers.scala:362) ~[lift-util_2.9.1-2.5-RC2.jar:2.5-RC2]
    at net.liftweb.http.DefaultBootstrap$$anonfun$boot$1.apply(LiftRules.scala:1999) ~[lift-webkit_2.9.1-2.5-RC2.jar:2.5-RC2]
    at net.liftweb.http.DefaultBootstrap$$anonfun$boot$1.apply(LiftRules.scala:1999) ~[lift-webkit_2.9.1-2.5-RC2.jar:2.5-RC2]
    at net.liftweb.common.Full.map(Box.scala:553) ~[lift-common_2.9.1-2.5-RC2.jar:2.5-RC2]

Solution

  • unmanagedJars in Compile is used as base for the same key in Runtime and Test, so its content is inherited by Runtime, but this is not the case for unmanagedClasspath. That's why you should prefer unmanagedJars when possible.

    You can explicitly add your folder to both configurations:

    val additionalClasses = file("[Path to my project]/classes")
    
    unmanagedClasspath in Compile += additionalClasses
    
    unmanagedClasspath in Runtime += additionalClasses
    

    Note: sbt < 0.13 doesn't support val in build.sbt, so you have to duplicate its content in both settings, or switch to a full Build.scala.

    See the Classpaths docs and this anwser for more details on what the classpath settings do and how they are inherited between configurations.

    I could not think of a way to add it to both at the same time though...