magnars / optimus

A Ring middleware for frontend performance optimization.
364 stars 23 forks source link

Issue locating assets in jar file #35

Closed andyparsons closed 9 years ago

andyparsons commented 9 years ago

Optimus is working nicely in our dev environment, but in packages builds we see exceptions like the one below. I've verified, in this case that the jar does contain the indicated file a the expected path.

Exception in thread "main" java.lang.ExceptionInInitializerError
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:344)
    at clojure.lang.RT.loadClassForName(RT.java:2093)
    at clojure.lang.RT.load(RT.java:430)
    at clojure.lang.RT.load(RT.java:411)
    at clojure.core$load$fn__5066.invoke(core.clj:5641)
    at clojure.core$load.doInvoke(core.clj:5640)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5446)
    at clojure.core$load_lib$fn__5015.invoke(core.clj:5486)
    at clojure.core$load_lib.doInvoke(core.clj:5485)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$load_libs.doInvoke(core.clj:5524)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$require.doInvoke(core.clj:5607)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at ring.server.leiningen$load_var.invoke(leiningen.clj:7)
    at ring.server.leiningen$serve.invoke(leiningen.clj:14)
    at clojure.lang.Var.invoke(Var.java:379)
    at gropius.handler.main$_main.invoke(main.clj:1)
    at clojure.lang.AFn.applyToHelper(AFn.java:152)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at gropius.handler.main.main(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Not a file: jar:file:/Users/andy/code/kontor/gropius/target/gropius.jar!/public/sass/admin/admin.scss
    at clojure.java.io$fn__8588.invoke(io.clj:63)
    at clojure.java.io$fn__8572$G__8556__8577.invoke(io.clj:35)
    at clojure.java.io$file.invoke(io.clj:414)
    at optimus_sass.core$load_sass_asset.invoke(core.clj:18)
    at optimus_sass.core$fn__9064$fn__9065.invoke(core.clj:27)
    at clojure.lang.MultiFn.invoke(MultiFn.java:231)
    at optimus.assets.creation$load_asset_and_refs.invoke(creation.clj:71)
    at optimus.assets.creation$load_assets$fn__3613.invoke(creation.clj:99)
    at clojure.core$map$fn__4245.invoke(core.clj:2557)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.core$seq.invoke(core.clj:133)
    at clojure.core$apply.invoke(core.clj:624)
    at clojure.core$mapcat.doInvoke(core.clj:2586)
    at clojure.lang.RestFn.invoke(RestFn.java:423)
    at optimus.assets.creation$load_assets.invoke(creation.clj:98)
    at optimus.assets.creation$load_bundle.invoke(creation.clj:104)
    at optimus.assets.creation$load_bundles$fn__3625.invoke(creation.clj:113)
    at clojure.core$map$fn__4245.invoke(core.clj:2559)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.core$seq.invoke(core.clj:133)
    at clojure.core$apply.invoke(core.clj:624)
    at clojure.core$mapcat.doInvoke(core.clj:2586)
    at clojure.lang.RestFn.invoke(RestFn.java:423)
    at optimus.assets.creation$load_bundles.invoke(creation.clj:112)
    at gropius.middleware$get_assets.invoke(middleware.clj:21)
    at optimus.strategies$serve_frozen_assets.invoke(strategies.clj:40)
    at optimus.prime$wrap.doInvoke(prime.clj:4)
    at clojure.lang.RestFn.invoke(RestFn.java:470)
    at gropius.middleware$fn__9403.invoke(middleware.clj:34)
    at noir.util.middleware$wrap_middleware.invoke(middleware.clj:138)
    at noir.util.middleware$app_handler.doInvoke(middleware.clj:184)
    at clojure.lang.RestFn.invoke(RestFn.java:713)
    at gropius.handler__init.load(Unknown Source)
    at gropius.handler__init.<clinit>(Unknown Source)
    ... 25 more
magnars commented 9 years ago

Hi!

In one of the projects I'm using Optimus, everything is bundled in an uberjar, and that works fine. It took some effort to get there, though, so might have left something out. It's been a while, so I'll have to look into it. How are you organising your jars?

Two things I notice:

  1. You're looking for a .scss file. I guess you are using optimus-sass? Are you using some form of includes? Maybe optimus-sass or the library it delegates to are looking for files on the file system?
  2. There are no optimus libraries in the stack trace. Why not?
andyparsons commented 9 years ago

Correct, I am using optimus-sass and there are includes. But doesn't optimus-less have a similar issue, then? I wonder if your uberjar project makes use of optikus-less?

I've edited the stack trace above to include the full trace, which does show references to Optimus.

magnars commented 9 years ago

Yeah, you can see the code here:

https://github.com/DomKM/optimus-sass/blob/master/src/optimus_sass/core.clj#L18

(defn- load-sass-asset [public-dir path]
  (let [resource (existing-resource public-dir path)
        css (-> resource io/file compile-file)
        css-asset (create-css-asset (str/replace path #"\.sass\z|\.scss\z" ".css")
                                    css
                                    (last-modified resource))]
    (assoc css-asset :original-path path)))

It loads the scss with io/file. That won't work in a jar. This is why Optimus uses io/resource to load files.

I suggest you open an issue with optimus-sass to get this fixed.

andyparsons commented 9 years ago

Thanks for the diagnosis!

andyparsons commented 9 years ago

FYI we have switched to optimus-less and everything is working nicely. This can be closed.

magnars commented 9 years ago

:+1: