scalasbtjnr

App running under SBT doesn't find a class from Classpath jar


I have a Scala project using sbt. It runs perfectly well under Eclipse, however, trying to run it under sbt (sbt 'run mount 1440' — including the parameters I need) leads to a ClassNotFoundException — it can not find jnr.ffi.provider.jffi.NativeClosureProxy class. However, running sbt 'last run' shows me that jnr-ffi-2.0.3.jar file (which includes the said class) is actually included in the classpath. Any suggestions on what's happening?

Sources available on github: https://github.com/FileJunkie/vkfs


Solution

  • Your build sbt is invalid.

    First, you need to have empty lines between the libraryDependecys.

    lazy val root = (project in file(".")).
      settings(
        name := "vkfs",
        version := "1.0",
        scalaVersion := "2.11.7"
      )
    
    libraryDependencies += "org.scalaj" %% "scalaj-http" % "1.1.6"
    
    libraryDependencies += "org.json4s" %% "json4s-jackson" % "3.2.11"
    
    libraryDependencies += "com.github.serceman" % "jnr-fuse" % "0.1"
    

    Second, the dependency "com.github.serceman" can not be resolved. This means either that

    So in summary, it seems that Eclipse does something automatically, so your program runs. When it comes to your build.sbt it is not valid (empty lines missing) and does not resolve dependencies properly. I wonder, how you could start via sbt 'run mount 1440' at all.

    After correcting the empty lines and running sbt 'run mount 1440' I obtain

    Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256M; support was removed in 8.0
    [info] Set current project to vkfs (in build file:/home/.../IdeaProjects/vkfs/)
    [info] Updating {file:/home/.../IdeaProjects/vkfs/}root...
    [info] Resolving com.github.serceman#jnr-fuse;0.1 ...
    [warn]  module not found: com.github.serceman#jnr-fuse;0.1
    [warn] ==== local: tried
    [warn]   /home/.../.ivy2/local/com.github.serceman/jnr-fuse/0.1/ivys/ivy.xml
    [warn] ==== public: tried
    [warn]   http://repo1.maven.org/maven2/com/github/serceman/jnr-fuse/0.1/jnr-fuse-0.1.pom
    [info] Resolving jline#jline;2.12.1 ...
    [warn]  ::::::::::::::::::::::::::::::::::::::::::::::
    [warn]  ::          UNRESOLVED DEPENDENCIES         ::
    [warn]  ::::::::::::::::::::::::::::::::::::::::::::::
    [warn]  :: com.github.serceman#jnr-fuse;0.1: not found
    [warn]  ::::::::::::::::::::::::::::::::::::::::::::::
    sbt.ResolveException: unresolved dependency: com.github.serceman#jnr-fuse;0.1: not found
    at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:213)
    at sbt.IvyActions$$anonfun$update$1.apply(IvyActions.scala:122)
    at sbt.IvyActions$$anonfun$update$1.apply(IvyActions.scala:121)
    [ ... truncated ... ]
    

    Edit (concerning dependency from jcenter)

    Add the following line to your build.sbt (remember extra empty line)

    resolvers += Resolver.jcenterRepo
    

    to add jcenter to your resolver list.

    Edit 2

    Resolver.jcenterRepo is not available in SBT 0.13.5, thus

    resolvers += "jcenter" at "https://jcenter.bintray.com/"
    

    is required.

    After successful compilation and run the relevant error is

    java.lang.RuntimeException: java.lang.NoClassDefFoundError: jnr/ffi/provider/jffi/NativeClosureProxy
    at jnr.ffi.provider.jffi.NativeClosureProxy.newProxyFactory(NativeClosureProxy.java:220)
    

    Final result

    The library "com.github.serceman" in v 0.1 seems to be problematic, as it can not properly instantiate some class via reflection.

    Solution

    Problem solved by adding fork in run := true to build.sbt.