0

Using Scala version 2.12.4, when deploying a project using a fat jar, which contains the scala standard library, for loops still do not work, giving the following error:

java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)[Ljava/lang/Object;

My build.sbt file is as follows:

name := "PixelMCDonations"

version := "0.1"

scalaVersion := "2.12.4"

resolvers += "sponge" at "https://repo.spongepowered.org/maven"

libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.25"

libraryDependencies += "org.spongepowered" % "spongeapi" % "7.0.0"

libraryDependencies += "me.lucko.luckperms" % "luckperms-api" % "4.0"

libraryDependencies += "org.scala-lang" % "scala-library" % scalaVersion.value

libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value

The code snippet is:

val ranks: Array[Rank] = ...
for (e: Rank <- ranks){
      if (value > e.lowerBound && value < e.upperbound){
        return e
      }
    }
    return null

I am not sure what I am missing as I am using the same scala version for both deploying and development and all other advanced features that I have tried work bar for loops.

Ryan Leach
  • 4,262
  • 5
  • 34
  • 71
mysterymyster
  • 43
  • 1
  • 8
  • What you need here is a minimal example. Just create a fat jar of the simplest scala project with the offending code. Then include full source code of that Scala project along with details about the process of creating fat jar. The how exactly are you trying to use your fat jar when "it does not work for you" – sarveshseri Jan 12 '18 at 13:30
  • along with this error line java.lang.NoSuchMethodError, you also get the full path of class name with the method name, may be just above or below of that particular line, so find that jar & just copy that jar file to some test directory and by using gui-jd.jar you can view and validate the class and check for the method, that error method is not there inside the class, or sometimes you are using a wrong version dependency jar or many version jar is there inside lib directory. – ArifMustafa Jan 12 '18 at 13:30
  • As a side note, you may want to use the `find` method: `ranks.find(value => value > e.lowerBound && value < e.upperbound).orNull` – stefanobaghino Jan 12 '18 at 13:48
  • What is probably happening is that some component of Minecraft depends on an older Scala version. So now there are two incompatible Scala libraries on your classpath. – Jasper-M Jan 12 '18 at 14:02
  • Minecraft is entirely using java code, I am just writing a plugin in scala – mysterymyster Jan 12 '18 at 14:06
  • @Jasper-M If he compiles and builds a fat JAR that carries along Scala itself there should not be any problem. But you are right, perhaps it would be interesting to see if by chance the Scala library is not already provided by Minecraft itself, in which case mysterymyster would have to abide by the provided version and not include its own. – stefanobaghino Jan 12 '18 at 14:12
  • Only 1 library in the entire minecraft ecosystem has to have some transitive dependency on Scala for you to be screwed. – Jasper-M Jan 12 '18 at 14:12
  • To support this claim: `Predef.refArrayOps` changed type signatures between 2.11.x and 2.12.x – Jasper-M Jan 12 '18 at 14:18
  • So if I changed my scala version to 2.11.X in theory it should fix the issue? – mysterymyster Jan 12 '18 at 14:19
  • @mysterymyster Probably. There's a tiny chance you might need 2.10.x but probably not. – Jasper-M Jan 12 '18 at 14:21
  • https://stackoverflow.com/questions/75947449/run-a-scala-code-jar-appear-nosuchmethoderrorscala-predef-refarrayops – Dmytro Mitin Apr 07 '23 at 04:59

1 Answers1

0

Presumably you are not shading Scala, as Minecraft Forge has had an outdated version of Scala included as a dependency, that they desperately want to get rid of, as they can't bump the version without annoying people, and can't remove it without annoying people.

You need to create a 'fat jar' including the scala release you wish to use.

I also recommend shading it, and including it as an external library for your plugin / mod, so that if you create other plugins / mods that rely on it, you can reduce the size of the jar's you package, and the amount of duplicated classes.

It should also help to make your plugins compatible with each other.

Ryan Leach
  • 4,262
  • 5
  • 34
  • 71