ClojureScript

The CLJS compiled uses deprecated modules on Java 9

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
    OSX Java 9
  • Patch:
    Code and Test
  • Approval:
    Accepted

Description

Running the shipping REPL fails with Java 9:

$ java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
$ java -jar cljs.jar -m cljs.repl.node
Exception in thread "main" java.lang.ExceptionInInitializerError
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at clojure.lang.RT.classForName(RT.java:2168)
	at clojure.lang.RT.classForName(RT.java:2177)
	at clojure.lang.RT.loadClassForName(RT.java:2196)
	at clojure.lang.RT.load(RT.java:443)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at cljs.repl.node$loading__5569__auto____6884.invoke(node.clj:9)
	at cljs.repl.node__init.load(Unknown Source)
	at cljs.repl.node__init.<clinit>(Unknown Source)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at clojure.lang.RT.classForName(RT.java:2168)
	at clojure.lang.RT.classForName(RT.java:2177)
	at clojure.lang.RT.loadClassForName(RT.java:2196)
	at clojure.lang.RT.load(RT.java:443)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at clojure.main$main_opt.invokeStatic(main.clj:314)
	at clojure.main$main_opt.invoke(main.clj:310)
	at clojure.main$main.invokeStatic(main.clj:421)
	at clojure.main$main.doInvoke(main.clj:384)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at clojure.lang.RT.classForName(RT.java:2168)
	at clojure.lang.RT.classForNameNonLoading(RT.java:2181)
	at cljs.util$loading__5569__auto____42.invoke(util.cljc:9)
	at cljs.util__init.load(Unknown Source)
	at cljs.util__init.<clinit>(Unknown Source)
	... 58 more

For Quick Start, the very first build command under "Let's build some ClojureScript" fails:

$ java -cp cljs.jar:src clojure.main build.clj
Exception in thread "main" java.lang.ExceptionInInitializerError, compiling:(/Users/mfikes/Desktop/hello_world/build.clj:1:1)
	at clojure.lang.Compiler.load(Compiler.java:7391)
	at clojure.lang.Compiler.loadFile(Compiler.java:7317)
	at clojure.main$load_script.invokeStatic(main.clj:275)
	at clojure.main$script_opt.invokeStatic(main.clj:335)
	at clojure.main$script_opt.invoke(main.clj:330)
	at clojure.main$main.invokeStatic(main.clj:421)
	at clojure.main$main.doInvoke(main.clj:384)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.lang.Var.invoke(Var.java:379)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Caused by: java.lang.ExceptionInInitializerError
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at clojure.lang.RT.classForName(RT.java:2168)
	at clojure.lang.RT.classForName(RT.java:2177)
	at clojure.lang.RT.loadClassForName(RT.java:2196)
	at clojure.lang.RT.load(RT.java:443)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at cljs.build.api$loading__5569__auto____2609.invoke(api.clj:8)
	at cljs.build.api__init.load(Unknown Source)
	at cljs.build.api__init.<clinit>(Unknown Source)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at clojure.lang.RT.classForName(RT.java:2168)
	at clojure.lang.RT.classForName(RT.java:2177)
	at clojure.lang.RT.loadClassForName(RT.java:2196)
	at clojure.lang.RT.load(RT.java:443)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at clojure.core$require.doInvoke(core.clj:5796)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at user$eval1.invokeStatic(build.clj:1)
	at user$eval1.invoke(build.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	... 11 more
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at clojure.lang.RT.classForName(RT.java:2168)
	at clojure.lang.RT.classForNameNonLoading(RT.java:2181)
	at cljs.util$loading__5569__auto____42.invoke(util.cljc:9)
	at cljs.util__init.load(Unknown Source)
	at cljs.util__init.<clinit>(Unknown Source)
	... 66 more

The javax.xml.bind package was deprecated in Java 9 and moved to a module, which requires adding --add-modules java.xml.bind to your REPL command line. It would be great if clojurescript didn't depend on the deprecated javax.xml.bind package in the first place.

  1. 0001-CLJS-2377-Remove-usage-of-java.xml.bind.DatatypeConv.patch
    06/Oct/17 4:22 PM
    2 kB
    Erik Assum
  2. CLJS-2377.patch
    15/Nov/17 9:56 AM
    4 kB
    Mike Fikes
  3. CLJS-2377-2.patch
    17/Nov/17 9:22 AM
    4 kB
    Mike Fikes
  4. CLJS-2377-3.patch
    17/Nov/17 3:44 PM
    4 kB
    Mike Fikes

Activity

Hide
Thomas Heller added a comment -

Since Closure now depends on JDK 8 anyways it should probably use java.util.Base64 instead.

Show
Thomas Heller added a comment - Since Closure now depends on JDK 8 anyways it should probably use java.util.Base64 instead.
Hide
David Nolen added a comment -

I agree with Thomas, let's get an updated patch thanks.

Show
David Nolen added a comment - I agree with Thomas, let's get an updated patch thanks.
Hide
Nikita Prokopov added a comment - - edited

Even URL-safe version of Base64 uses hyphen, underscore and equality sign, and is also case-sensitive. I see content-sha being used for namespace names, method names and file paths. Considering most filesystems are case-insensitive, and CLJS translating both hyphen and underscore to underscore when compiling namespace, this might lead to unwanted collisions. Are we happy with that?

Show
Nikita Prokopov added a comment - - edited Even URL-safe version of Base64 uses hyphen, underscore and equality sign, and is also case-sensitive. I see content-sha being used for namespace names, method names and file paths. Considering most filesystems are case-insensitive, and CLJS translating both hyphen and underscore to underscore when compiling namespace, this might lead to unwanted collisions. Are we happy with that?
Hide
Thomas Heller added a comment -

I might have confused the issue. The patch only fixes cljs.util but cljs.repl is also using DatatypeConverter.

cljs.util however only wants to print a hex string, which the java.util.Base64 class I suggested doesn't do.

So the fix is fine, cljs.repl just should use the Base64 class?

Show
Thomas Heller added a comment - I might have confused the issue. The patch only fixes cljs.util but cljs.repl is also using DatatypeConverter. cljs.util however only wants to print a hex string, which the java.util.Base64 class I suggested doesn't do. So the fix is fine, cljs.repl just should use the Base64 class?
Hide
Mike Fikes added a comment -

Attached a patch (CLJS-2377.patch) which addresses an issue (extra argument) in previous patch, adds tests, and covers both places where the DatatypeConverter code was being used.

Show
Mike Fikes added a comment - Attached a patch (CLJS-2377.patch) which addresses an issue (extra argument) in previous patch, adds tests, and covers both places where the DatatypeConverter code was being used.
Hide
Mike Fikes added a comment -

I'm a bit concerned about the perf of bytes-to-hex-str in the previous CLJS-2377.patch because it is about 200 times slower than DatatypeConverter/printHexBinary and it can used by content-sha on fairly large strings (source files, for example). Attaching a revision CLJS-2377-2.patch which falls within a factor of 5 of DatatypeConverter/printHexBinary.

Show
Mike Fikes added a comment - I'm a bit concerned about the perf of bytes-to-hex-str in the previous CLJS-2377.patch because it is about 200 times slower than DatatypeConverter/printHexBinary and it can used by content-sha on fairly large strings (source files, for example). Attaching a revision CLJS-2377-2.patch which falls within a factor of 5 of DatatypeConverter/printHexBinary.
Hide
Mike Fikes added a comment - - edited

Attached a CLJS-2377-3.patch that further brings the perf of bytes-to-hex-str to less than a factor of 2 of DatatypeConverter/printHexBinary.

Show
Mike Fikes added a comment - - edited Attached a CLJS-2377-3.patch that further brings the perf of bytes-to-hex-str to less than a factor of 2 of DatatypeConverter/printHexBinary.
Hide
Mike Fikes added a comment -

Confirmed fixed with downstream project and Java 9.

Show
Mike Fikes added a comment - Confirmed fixed with downstream project and Java 9.

People

Vote (7)
Watch (6)

Dates

  • Created:
    Updated:
    Resolved: