ring-clojure / ring

Clojure HTTP server abstraction
MIT License
3.75k stars 519 forks source link

multipart-params not compatible with GraalVM native-image #430

Closed chrysophylax closed 1 year ago

chrysophylax commented 3 years ago

Hi,

Trying to use a simple ring-app with ring.middleware.multipart-params on a native image generated by GraalVM 21's native-image tool fails because the Clojure classloader cannot find a generated class for ring.middleware.multipart-params/temp_file.clj.

Would it be possible to make it AOT-friendly?

It'd be lovely if we could use this middleware with GraalVM as it speeds up start-up time for clojure from ~1-3s down to 2-5 ms.

ring-core version: 1.8.2 GraalVM version: 21.0-Community Clojure: 1.10.2

Error:

$ ./app init
2021-02-01 07:44:08.554:INFO:oejs.Server:main: jetty-9.4.31.v20200723; built: 2020-07-23T17:57:36.812Z; git: 450ba27947e13e66baa8cd1ce7e85a4461cacc1d; jvm 11.0.10
2021-02-01 07:44:08.555:INFO:oejs.AbstractConnector:main: Started ServerConnector@4a157aae{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-02-01 07:44:08.555:INFO:oejs.Server:main: Started @2ms
2021-02-01 07:44:11.356:WARN:oejs.HttpChannel:qtp417260920-72: handleException /files java.io.FileNotFoundException: Could not locate ring/middleware/multipart_params/temp_file__init.class, ring/middleware/multipart_params/temp_file.clj or ring/middleware/multipart_params/temp_file.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.

It's first compiled into an uberjar using hf.depstar/uberjar :aot true :compile-ns :all and then I run

native-image -cp app.jar -jar app.jar \
-H:Name=app -H:+ReportExceptionStackTraces -J-Dclojure.spec.skip.macros=true \
-J-Dclojure.compiler.direct-linking=true --initialize-at-build-time --enable-http \
--verbose --no-fallback --no-server --report-unsupported-elements-at-runtime \
--initialize-at-build-time --verbose --native-image-info --verbose 
weavejester commented 3 years ago

Does it fail even if you explicitly set the multipart store?

chrysophylax commented 3 years ago

Thanks. It works if it's set explicitly. I guess it couldn't figure it out from the default behaviour. This is great. :D

quatrix commented 2 years ago

Hi,

I'm having the same issue when using ring-clojure + graalvm, without explicitly using ring.middleware.multipart-params.

requiring [ring.middleware.multipart-params.temp-file :refer [temp-file-store]] seems to work around it.

FieryCod commented 2 years ago

@weavejester @quatrix @chrysophylax Would you please provide a minimal repro to this? I'm happy to do a PR with the fix :)