boot
boot copied to clipboard
Prefix string too short
Describe the bug
Attempting to build an uberjar with Selenium as a dependency raises the following exception:
clojure.lang.ExceptionInfo: Prefix string "9" too short: length must be at least 3
To Reproduce
build.boot
:
(set-env!
:resource-paths #{"."}
:dependencies '[[org.clojure/clojure "1.10.1"]
[org.seleniumhq.selenium/selenium-support "3.141.59"]
[org.seleniumhq.selenium/selenium-remote-driver "3.141.59"]])
(task-options!
pom {:project 'selenium :version "0.1.0-SNAPSHOT"}
aot {:namespace #{'selenium}}
jar {:main 'selenium})
boot.properties
:
BOOT_VERSION=2.8.3
BOOT_CLOJURE_VERSION=1.10.1
BOOT_CLOJURE_NAME=org.clojure/clojure
selenium.clj
:
(ns selenium (:gen-class))
(defn -main [& args] ())
Run boot aot pom uber jar target
Expected behavior
Successful build and jar written to disk.
Actual behavior
Compiling 1/1 selenium...
Writing pom.xml and pom.properties...
Adding uberjar entries...
java.lang.Thread.run Thread.java: 832
java.util.concurrent.ThreadPoolExecutor$Worker.run ThreadPoolExecutor.java: 630
java.util.concurrent.ThreadPoolExecutor.runWorker ThreadPoolExecutor.java: 1130
java.util.concurrent.FutureTask.run FutureTask.java: 264
...
clojure.core/binding-conveyor-fn/fn core.clj: 2030
boot.core/boot/fn core.clj: 1031
boot.core/run-tasks core.clj: 1022
boot.task.built-in/eval2944/fn/fn/fn built_in.clj: 800
boot.task.built-in/eval2662/fn/fn/fn built_in.clj: 576
boot.task.built-in/eval2828/fn/fn/fn built_in.clj: 753
clojure.core/reduce core.clj: 6828
clojure.core.protocols/fn/G protocols.clj: 13
clojure.core.protocols/fn protocols.clj: 75
clojure.core.protocols/seq-reduce protocols.clj: 31
clojure.core.protocols/fn/G protocols.clj: 19
clojure.core.protocols/fn protocols.clj: 168
boot.task.built-in/eval2828/fn/reducer built_in.clj: 733
...
boot.core/add-cached-resource core.clj: 622
boot.core/add-cached-resource core.clj: 632
boot.tmpdir.TmpFileSet/add-cached tmpdir.clj: 308
boot.tmpdir/merge-trees! tmpdir.clj: 187
boot.tmpdir/apply-mergers! tmpdir.clj: 148
java.io.File.createTempFile File.java: 2083
java.lang.IllegalArgumentException: Prefix string "9" too short: length must be at least 3
clojure.lang.ExceptionInfo: Prefix string "9" too short: length must be at least 3
line: 15
Desktop:
I used a container to run the above i.e.
docker run -it --rm -v "$PWD":/usr/src/app -w /usr/src/app clojure:openjdk-15-boot-2.8.3-alpine boot aot pom uber jar target
Running boot -vv ...
provides ALOT more information... but it mentions a "duplicate entry":
Adding uberjar entries...
Adding cached fileset cdc814c87d5e7bbc0165371795a51643...
Adding cached fileset 957c53796f5c1649094808dddcb9dd27...
Adding cached fileset 45dc4650fe3a118fc0016597faefdd6b...
Adding cached fileset 18b6e7cc2e8fc01a92506fae0fe01e41...
Adding cached fileset 12927bfd657ccc3745660f1c6f748665...
Adding cached fileset 30885522678e56bcd4a6569c4280f2b7...
Adding cached fileset 8c0236e54e32978531eea3a62d67160a...
Merging META-INF/versions/9...
Merging duplicate entry (META-INF/versions/9)
clojure.lang.ExceptionInfo: Prefix string "9" too short: length must be at least 3 {:line 16}
at boot.main$_main$fn__1630.invoke(main.clj:222)
at boot.main$_main.invokeStatic(main.clj:216)
at boot.main$_main.invoke(main.clj:123)
at clojure.lang.Var.invoke(Var.java:399)
at org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke(ClojureRuntimeShimImpl.java:154)
at org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke(ClojureRuntimeShimImpl.java:145)
at boot.App.runBoot(App.java:407)
at boot.App.main(App.java:500)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at Boot.main(Boot.java:257)
Caused by: java.lang.IllegalArgumentException: Prefix string "9" too short: length must be at least 3
at java.base/java.io.File.createTempFile(File.java:2083)
at boot.tmpdir$apply_mergers_BANG_.invoke(tmpdir.clj:148)
at boot.tmpdir$merge_trees_BANG_.invoke(tmpdir.clj:187)
at boot.tmpdir.TmpFileSet.add_cached(tmpdir.clj:308)
at boot.core$add_cached_resource.invokeStatic(core.clj:632)
at boot.core$add_cached_resource.doInvoke(core.clj:622)
at clojure.lang.RestFn.invoke(RestFn.java:731)
at boot.task.built_in$eval2828$fn__2829$reducer__2840.invoke(built_in.clj:733)
at clojure.core.protocols$fn__8159.invokeStatic(protocols.clj:168)
at clojure.core.protocols$fn__8159.invoke(protocols.clj:124)
at clojure.core.protocols$fn__8114$G__8109__8123.invoke(protocols.clj:19)
at clojure.core.protocols$seq_reduce.invokeStatic(protocols.clj:31)
at clojure.core.protocols$fn__8146.invokeStatic(protocols.clj:75)
at clojure.core.protocols$fn__8146.invoke(protocols.clj:75)
at clojure.core.protocols$fn__8088$G__8083__8101.invoke(protocols.clj:13)
at clojure.core$reduce.invokeStatic(core.clj:6828)
at clojure.core$reduce.invoke(core.clj:6810)
at boot.task.built_in$eval2828$fn__2829$fn__2844$fn__2845.invoke(built_in.clj:753)
at boot.task.built_in$eval2662$fn__2663$fn__2678$fn__2679.invoke(built_in.clj:576)
at boot.task.built_in$eval2944$fn__2945$fn__2954$fn__2955.invoke(built_in.clj:800)
at boot.core$run_tasks.invokeStatic(core.clj:1022)
at boot.core$run_tasks.invoke(core.clj:1016)
at boot.core$boot$fn__1281.invoke(core.clj:1031)
at clojure.core$binding_conveyor_fn$fn__5754.invoke(core.clj:2030)
at clojure.lang.AFn.call(AFn.java:18)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
Can I work-around the problem with some :exclusions
in the dependencies?
So the versions directory has something to do with multi-release jars, and in my case it's empty so I was able to work-around the issue by adding an extra exclude pattern to the uber task, i.e.
(task-options!
uber {:exclude #{#"(?i)^META-INF/INDEX.LIST$"
#"(?i)^META-INF/[^/]*\.(MF|SF|RSA|DSA)$"
#"(?i)^META-INF/versions/.$"}}
...)
But in general I suppose that the apply-mergers!
will want to deal with one (and two) character directory names.