What about scalafx

Does anyone know whether scalafx is broken or whether it is just me?
the Quickstart guide says to add this line to build.sbt

libraryDependencies += "org.scalafx" %% "scalafx" % "8.0.144-R12"

but I get some errors when I try that.

[error] sbt.librarymanagement.ResolveException: Error downloading org.scalafx:scalafx_2.13:8.0.144-R12
[error]   Not found
[error]   Not found
[error]   not found: /Users/jnewton/.ivy2/local/org.scalafx/scalafx_2.13/8.0.144-R12/ivys/ivy.xml
[error]   not found: https://repo1.maven.org/maven2/org/scalafx/scalafx_2.13/8.0.144-R12/scalafx_2.13-8.0.144-R12.pom
[error] 	at lmcoursier.CoursierDependencyResolution.unresolvedWarningOrThrow(CoursierDependencyResolution.scala:249)
[error] 	at lmcoursier.CoursierDependencyResolution.$anonfun$update$35(CoursierDependencyResolution.scala:218)
[error] 	at scala.util.Either$LeftProjection.map(Either.scala:573)
[error] 	at lmcoursier.CoursierDependencyResolution.update(CoursierDependencyResolution.scala:218)
[error] 	at sbt.librarymanagement.DependencyResolution.update(DependencyResolution.scala:60)
[error] 	at sbt.internal.LibraryManagement$.resolve$1(LibraryManagement.scala:52)
[error] 	at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$12(LibraryManagement.scala:102)
[error] 	at sbt.util.Tracked$.$anonfun$lastOutput$1(Tracked.scala:69)
[error] 	at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$20(LibraryManagement.scala:115)
[error] 	at scala.util.control.Exception$Catch.apply(Exception.scala:228)
[error] 	at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$11(LibraryManagement.scala:115)
[error] 	at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$11$adapted(LibraryManagement.scala:96)
[error] 	at sbt.util.Tracked$.$anonfun$inputChanged$1(Tracked.scala:150)
[error] 	at sbt.internal.LibraryManagement$.cachedUpdate(LibraryManagement.scala:129)
[error] 	at sbt.Classpaths$.$anonfun$updateTask0$5(Defaults.scala:2950)
[error] 	at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] 	at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error] 	at sbt.std.Transform$$anon$4.work(Transform.scala:67)
[error] 	at sbt.Execute.$anonfun$submit$2(Execute.scala:281)
[error] 	at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19)
[error] 	at sbt.Execute.work(Execute.scala:290)
[error] 	at sbt.Execute.$anonfun$submit$1(Execute.scala:281)
[error] 	at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
[error] 	at sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
[error] 	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error] 	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
[error] 	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error] 	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[error] 	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[error] 	at java.base/java.lang.Thread.run(Thread.java:834)
[error] (update) sbt.librarymanagement.ResolveException: Error downloading org.scalafx:scalafx_2.13:8.0.144-R12
[error]   Not found
[error]   Not found
[error]   not found: /Users/jnewton/.ivy2/local/org.scalafx/scalafx_2.13/8.0.144-R12/ivys/ivy.xml
[error]   not found: https://repo1.maven.org/maven2/org/scalafx/scalafx_2.13/8.0.144-R12/scalafx_2.13-8.0.144-R12.pom
[error] Total time: 1 s, completed Mar 30, 2021, 2:26:14 PM
1 Like

Never touched it, but I always recommend trusting GitHub over hand-written documentation, since the latter tends to fall out of date. If you look at its GitHub repo, that lists 15.0.1-R21 as the current version – apparently vastly newer. (And gives slightly different instructions.)

So I would tend to assume that that website is just behind the times, and is probably referring you to a version that was never built for Scala 2.13…

Edit: ah, and reading further, it looks like the newest version for Java 8 is 8.0.192-R14.

4 Likes

Thanks for the advise. It seems (at first glace) to work much better. at least my the code compiles and runs.

You have an error since the old ScalaFX “8.0.144-R12” is not published for Scala 2.13. See published versions here: Maven Central Repository Search
The newest version is “15.0.1-R21”. That “Quick Start Guide” needs to be updated.

Take a look at GitHub - scalafx/scalafx-hello-world: Simple example of a ScalaFX application for simple example of ScalaFX project. It shows how to add dependencies for JavaFX that match ScalaFX version.

You can also create a new ScalaFX project using “sbt new scalafx/scalafx.g8”

2 Likes

@jpsacha
I’m trying to debug my ci/cd pipeline. Errors therewith tempted me to start updating the scalafx version.
When I run sbt test from a shell on my Mac laptop, the tests run (including initialisation of scalafx).
However, my ci/cd pipeline runs in a docker hseeberger/scala-sbt container running Debian linux, which I don’t have much understanding of. It seems the environment is running this version of java.

openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

The code seems to compile, but I get a run-time class loading error. Does this point to an error in my code? Or my build.sbt, or is it an error in the docker image? Or am I using the wrong java version? Or any other clue you might give would be great.

[info]   java.lang.UnsupportedClassVersionError: javafx/scene/image/Image has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
175[info]   at java.lang.ClassLoader.defineClass1(Native Method)
176[info]   at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
177[info]   at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
178[info]   at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
179[info]   at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
180[info]   at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
181[info]   at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
182[info]   at java.security.AccessController.doPrivileged(Native Method)
183[info]   at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
184[info]   at sbt.internal.ManagedClassLoader.findClass(ManagedClassLoader.java:98)
185[info]   ...

Looks that you are using JavaFX binary incompatible with Java 8. In my experience recent versions of JavaFX (tested up to 15) work fine with Java 11 and newer.

To work with Java 8 you will need older version of ScalaFX (“8.0.181-R13”). Keep in mind that those older versions work with Scala 2.10, 2.11, and 2.12, but not 2.13.

2 Likes

ahhh. so my docker image has an old java version? Any idea how to do that?
I’m asking my sys-admin in the mean time?

That appears to be behind the times – as I mentioned upthread, the current version appears to be 8.0.192-R14. But I agree that, based on Maven, there doesn’t appear to be a Scala 2.13 version published for JVM 8. Looks like you need at least JVM 12…

1 Like

on my laptop it seems to work with java 11. At least I think I’m using java 11.

Okay – quite possible that it just works. My impression from the ScalaFX repo is that it is built with 15, but JVM versions tend to be pretty compatible with each other.

As for the docker image: definitely not my area of expertise, but the discussion on the image’s page does show how to build what looks like it’s probably a JVM 11 image, albeit not a Debian one…

Yes I saw that on the image page. I don’t understand however, if that is the mortal user who needs to build that, or whether it is the person who maintains the docker image on the serving running the ci/cd pipelines for gitlab? I’m not the sysadmin. Step #1, Install Docker, seems to imply these are instructions for the sysadmin, not the mortal user.

Current ScalaFX releases are tested with Java 11 as it is the current “Long-Time-Support” Java version

3 Likes

What are most people using to run scala tests as part of ci/cd pipelines ?

I’m not sure what you mean by that. You meant what build tool do they use? What testing library do they use? Or something else?

Are you asking this about JavaFX or ScalaFX projects specifically, or just Scala testing generally?

1 Like

Just use the proper tag of the docker image:

hseeberger/scala-sbt:11.0.10_1.4.9_2.13.5

That is Java 11, sbt 1.4.9 and the obvious scala version.

1 Like

how did you know that magic?

Great, so scalafx seems to be happier with java 11. However, there’s still a weird problem. I get a java.lang.UnsatisfiedLinkError exception.

/usr/local/openjdk-11/bin/java
openjdk version "11.0.10" 2021-01-19
OpenJDK Runtime Environment 18.9 (build 11.0.10+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.10+9, mixed mode, sharing)
Loading library prism_es2 from resource failed: java.lang.UnsatisfiedLinkError: /root/.openjfx/cache/14.0.1/libprism_es2.so: libX11.so.6: cannot open shared object file: No such file or directory
java.lang.UnsatisfiedLinkError: /root/.openjfx/cache/14.0.1/libprism_es2.so: libX11.so.6: cannot open shared object file: No such file or directory
	at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
	at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)
	at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)
	at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2627)
	at java.base/java.lang.Runtime.load0(Runtime.java:768)
	at java.base/java.lang.System.load(System.java:1837)
	at com.sun.glass.utils.NativeLibLoader.installLibraryFromResource(NativeLibLoader.java:214)
	at com.sun.glass.utils.NativeLibLoader.loadLibraryFromResource(NativeLibLoader.java:194)
	at com.sun.glass.utils.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:135)
	at com.sun.glass.utils.NativeLibLoader.loadLibrary(NativeLibLoader.java:53)
	at com.sun.prism.es2.ES2Pipeline.lambda$static$0(ES2Pipeline.java:68)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at com.sun.prism.es2.ES2Pipeline.<clinit>(ES2Pipeline.java:50)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:315)
	at com.sun.prism.GraphicsPipeline.createPipeline(GraphicsPipeline.java:218)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:91)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
	at java.base/java.lang.Thread.run(Thread.java:834)

The reason is that the Linux version in VM does not have X11 installed i.e no GUI.

Note that when testing GUI stuff you should use a headless version of JFX. Consider for example TestFX (don’t know how that fits into ScalFX). Such frameworks allow you to send user actions to the GUI widgets and check the output.

That being said, I don’t think you can actually test the visualization of the images. You could however use Java to generate the images and then compare those against a golden standard.

HTHs

Sorry, I don’t exactly understand the comment. I am not testing visualization. At least not intentionally. I’m testing a project which has some functions in it which create images and sometimes display them.