sbt / sbt

sbt, the interactive build tool
https://scala-sbt.org
Apache License 2.0
4.8k stars 935 forks source link

NullPointerException or ArrayIndexOutOfBoundsException launching sbt 1.5.0 #6432

Closed jgulotta closed 3 years ago

jgulotta commented 3 years ago

steps

  1. Start sbt. Can be in an empty directory - doesn't matter.

problem

NullPointerException or ArrayIndexOutOfBoundsException on launch

$ /usr/local/bin/sbt
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at sbt.internal.XMainConfiguration.makeConfiguration(XMainConfiguration.java:102)
    at sbt.internal.XMainConfiguration.run(XMainConfiguration.java:45)
    at sbt.xMain.run(Main.scala:46)
    at xsbt.boot.Launch$.$anonfun$run$1(Launch.scala:149)
    at xsbt.boot.Launch$.withContextLoader(Launch.scala:176)
    at xsbt.boot.Launch$.run(Launch.scala:149)
    at xsbt.boot.Launch$.$anonfun$apply$1(Launch.scala:44)
    at xsbt.boot.Launch$.launch(Launch.scala:159)
    at xsbt.boot.Launch$.apply(Launch.scala:44)
    at xsbt.boot.Launch$.apply(Launch.scala:21)
    at xsbt.boot.Boot$.runImpl(Boot.scala:78)
    at xsbt.boot.Boot$.run(Boot.scala:73)
    at xsbt.boot.Boot$.main(Boot.scala:21)
    at xsbt.boot.Boot.main(Boot.scala)
Caused by: java.lang.reflect.InvocationTargetException
    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:566)
    at sbt.internal.XMainConfiguration.makeConfiguration(XMainConfiguration.java:84)
    ... 13 more
Caused by: java.lang.NullPointerException
    at java.base/java.util.ArrayDeque.addLast(ArrayDeque.java:304)
    at java.base/java.util.ArrayDeque.add(ArrayDeque.java:495)
    at java.base/jdk.internal.loader.URLClassPath.<init>(URLClassPath.java:154)
    at java.base/jdk.internal.loader.URLClassPath.<init>(URLClassPath.java:171)
    at java.base/java.net.URLClassLoader.<init>(URLClassLoader.java:120)
    at sbt.internal.SbtInterfaceLoader.<init>(SbtInterfaceLoader.java:16)
    at sbt.internal.MetaBuildLoader.makeLoader(MetaBuildLoader.java:143)
    ... 18 more

The exception above occurs with SBT 1.5.0 on OpenJDK 15 and 11, and on all JDKs when setting sbt.version=1.4.9 via project/build.properties. With SBT 1.5.0 on OracleJDK 8 I get

$ JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0) /usr/local/bin/sbt
java.lang.RuntimeException: java.lang.NullPointerException
    at sbt.internal.XMainConfiguration$ModifiedConfiguration.provider(XMainConfiguration.java:295)
    at sbt.internal.XMainConfiguration.run(XMainConfiguration.java:48)
    at sbt.xMain.run(Main.scala:46)
    at xsbt.boot.Launch$.$anonfun$run$1(Launch.scala:149)
    at xsbt.boot.Launch$.withContextLoader(Launch.scala:176)
    at xsbt.boot.Launch$.run(Launch.scala:149)
    at xsbt.boot.Launch$.$anonfun$apply$1(Launch.scala:44)
    at xsbt.boot.Launch$.launch(Launch.scala:159)
    at xsbt.boot.Launch$.apply(Launch.scala:44)
    at xsbt.boot.Launch$.apply(Launch.scala:21)
    at xsbt.boot.Boot$.runImpl(Boot.scala:78)
    at xsbt.boot.Boot$.run(Boot.scala:73)
    at xsbt.boot.Boot$.main(Boot.scala:21)
    at xsbt.boot.Boot.main(Boot.scala)
Caused by: java.lang.NullPointerException
    at sun.net.util.URLUtil.urlNoFragString(URLUtil.java:50)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:512)
    at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:484)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:238)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:365)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sbt.internal.XMainConfiguration$ModifiedConfiguration$ModifiedAppProvider$1$1.<init>(XMainConfiguration.java:132)
    at sbt.internal.XMainConfiguration$ModifiedConfiguration$ModifiedAppProvider$1.<init>(XMainConfiguration.java:128)
    at sbt.internal.XMainConfiguration$ModifiedConfiguration$ModifiedAppProvider.<init>(XMainConfiguration.java:126)
    at sbt.internal.XMainConfiguration$ModifiedConfiguration.provider(XMainConfiguration.java:293)
    ... 13 more

When setting sbt.version=1.3.13 via project/build.properties I get the following on all JDKs

$ /usr/local/bin/sbt
java.lang.reflect.InvocationTargetException
    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:566)
    at sbt.internal.XMainConfiguration.makeConfiguration(XMainConfiguration.scala:69)
    at sbt.internal.XMainConfiguration.run(XMainConfiguration.scala:36)
    at sbt.xMain.run(Main.scala:39)
    at xsbt.boot.Launch$.$anonfun$run$1(Launch.scala:149)
    at xsbt.boot.Launch$.withContextLoader(Launch.scala:176)
    at xsbt.boot.Launch$.run(Launch.scala:149)
    at xsbt.boot.Launch$.$anonfun$apply$1(Launch.scala:44)
    at xsbt.boot.Launch$.launch(Launch.scala:159)
    at xsbt.boot.Launch$.apply(Launch.scala:44)
    at xsbt.boot.Launch$.apply(Launch.scala:21)
    at xsbt.boot.Boot$.runImpl(Boot.scala:78)
    at xsbt.boot.Boot$.run(Boot.scala:73)
    at xsbt.boot.Boot$.main(Boot.scala:21)
    at xsbt.boot.Boot.main(Boot.scala)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 82 out of bounds for length 82
    at sbt.internal.MetaBuildLoader.makeLoader(MetaBuildLoader.java:73)
    ... 18 more

expectation

SBT should launch

notes

I run OS X 11.2.3 with SBT 1.5.0 installed via Homebrew, using JAVA_HOME to select various JDKs.

I have tried deleting $HOME/.sbt/boot as suggested on reddit, but the errors still occur.

eed3si9n commented 3 years ago

I actually have not been checking what Homebrew ships. Does this problem still occur if you downloaded .tgz file from https://www.scala-sbt.org/download.html and used the sbt script in it?

jgulotta commented 3 years ago

In as much as I can gather from their sbt.rb file, Homebrew does not do much more than download and extract the tgz for you.

It does happen for me too with a fresh download

$ ht -F -d https://github.com/sbt/sbt/releases/download/v1.5.0/sbt-1.5.0.tgz -o sbt.tgz && tar xf sbt.tgz && ./sbt/bin/sbt
HTTP/2.0 200 OK
accept-ranges: bytes
age: 0
content-disposition: attachment; filename=sbt-1.5.0.tgz
content-length: 19985381
content-type: application/octet-stream
date: Tue, 06 Apr 2021 21:16:07 GMT
etag: "4a9fd0b28bd80bf22bb50a65602f4517"
last-modified: Sun, 04 Apr 2021 18:06:16 GMT
server: AmazonS3
strict-transport-security: max-age=31536000
via: 1.1 varnish, 1.1 varnish
x-amz-id-2: iZjxeNtSRziKPrEIAfkiIUenDqYWj3Rc8JJP47wRT+6iCzrysQ31zIm3f0TblnA8Q5Fd90ye0/w=
x-amz-request-id: KVK9GBXQ5MAN3V4A
x-cache: MISS, MISS
x-cache-hits: 0, 0
x-fastly-request-id: f9fdf57d6bb3a20d0e74727e1ad0de4fc690354a
x-served-by: cache-dca17755-DCA, cache-sea4425-SEA

Downloading 19.06MB to "sbt.tgz"
  [00:00:01] [########################################] 19.06MB 10.15MB/s ETA 0s
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at sbt.internal.XMainConfiguration.makeConfiguration(XMainConfiguration.java:102)
    at sbt.internal.XMainConfiguration.run(XMainConfiguration.java:45)
    at sbt.xMain.run(Main.scala:46)
    at xsbt.boot.Launch$.$anonfun$run$1(Launch.scala:149)
    at xsbt.boot.Launch$.withContextLoader(Launch.scala:176)
    at xsbt.boot.Launch$.run(Launch.scala:149)
    at xsbt.boot.Launch$.$anonfun$apply$1(Launch.scala:44)
    at xsbt.boot.Launch$.launch(Launch.scala:159)
    at xsbt.boot.Launch$.apply(Launch.scala:44)
    at xsbt.boot.Launch$.apply(Launch.scala:21)
    at xsbt.boot.Boot$.runImpl(Boot.scala:78)
    at xsbt.boot.Boot$.run(Boot.scala:73)
    at xsbt.boot.Boot$.main(Boot.scala:21)
    at xsbt.boot.Boot.main(Boot.scala)
Caused by: java.lang.reflect.InvocationTargetException
    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:566)
    at sbt.internal.XMainConfiguration.makeConfiguration(XMainConfiguration.java:84)
    ... 13 more
Caused by: java.lang.NullPointerException
    at java.base/java.util.ArrayDeque.addLast(ArrayDeque.java:304)
    at java.base/java.util.ArrayDeque.add(ArrayDeque.java:495)
    at java.base/jdk.internal.loader.URLClassPath.<init>(URLClassPath.java:154)
    at java.base/jdk.internal.loader.URLClassPath.<init>(URLClassPath.java:171)
    at java.base/java.net.URLClassLoader.<init>(URLClassLoader.java:120)
    at sbt.internal.SbtInterfaceLoader.<init>(SbtInterfaceLoader.java:16)
    at sbt.internal.MetaBuildLoader.makeLoader(MetaBuildLoader.java:143)
    ... 18 more
[error] [launcher] error during sbt launcher: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
eed3si9n commented 3 years ago

There's a lot of String comparison and regex going on in https://github.com/sbt/sbt/blob/develop/main/src/main/java/sbt/internal/MetaBuildLoader.java, so it's possible we're missing something when launcher was switched to use Coursier to download the sbt and Scala artifacts.

What do you see for $ ls $HOME/.sbt/boot/scala-2.12.13/org.scala-sbt/sbt/1.5.0/? There should be compiler-interface-1.5.0.jar and test-interface-1.0.jar. If there aren't, that could cause the NPE.

jgulotta commented 3 years ago

Ah that seems the likely culprit.

$ ls $HOME/.sbt/boot/scala-2.12.13/org.scala-sbt/sbt/1.5.0/
actions_2.12-1.5.0.jar                                         launcher-interface-1.3.0.jar             sjson-new-scalajson_2.12-0.9.1.jar
caffeine-2.8.5.jar                                             librarymanagement-core_2.12-1.5.0.jar    slf4j-api-1.7.26.jar
checker-qual-3.4.1.jar                                         librarymanagement-ivy_2.12-1.5.0.jar     ssl-config-core_2.12-0.4.0.jar
collections_2.12-1.5.0.jar                                     lm-coursier-shaded_2.12-2.0.8.jar        task-system_2.12-1.5.0.jar
command_2.12-1.5.0.jar                                         log4j-api-2.11.2.jar                     tasks_2.12-1.5.0.jar
compiler-bridge_2.12-1.5.0.jar                                 log4j-core-2.11.2.jar                    template-resolver.jar
compiler-interface-1.5.0.jar                                   log4j-slf4j-impl-2.11.2.jar              test-agent-1.5.0.jar
completion_2.12-1.5.0.jar                                      logic_2.12-1.5.0.jar                     test-interface.jar
config-1.3.3.jar                                               main-settings_2.12-1.5.0.jar             testing_2.12-1.5.0.jar
core-macros_2.12-1.5.0.jar                                     main_2.12-1.5.0.jar                      util-cache_2.12-1.5.0.jar
disruptor.jar                                                  okhttp-3.14.2.jar                        util-control_2.12-1.5.0.jar
error_prone_annotations-2.4.0.jar                              okhttp-urlconnection.jar                 util-interface-1.5.0.jar
file-tree-views-2.1.6.jar                                      okio-1.17.2.jar                          util-logging_2.12-1.5.0.jar
gigahorse-core_2.12-0.5.0.jar                                  protocol_2.12-1.5.0.jar                  util-position_2.12-1.5.0.jar
gigahorse-okhttp_2.12-0.5.0.jar                                reactive-streams-1.0.2.jar               util-relation_2.12-1.5.0.jar
io_2.12-1.5.0.jar                                              run_2.12-1.5.0.jar                       util-tracking_2.12-1.5.0.jar
ipcsocket-1.3.0.jar                                            sbinary_2.12-0.5.1.jar                   zero-allocation-hashing-0.10.1.jar
ivy-2.3.0-sbt-fbc4f586aeeb1591710b14eb4f41b94880dcd745.jar     sbt-1.5.0.jar                            zinc-apiinfo_2.12-1.5.0.jar
jansi-2.1.0.jar                                                scala-collection-compat_2.12-2.4.2.jar   zinc-classfile_2.12-1.5.0.jar
jline-2.14.7-sbt-a1b0ffbb8f64bb820f4f84a0c07a0c0964507493.jar  scala-compiler-2.12.13.jar               zinc-classpath_2.12-1.5.0.jar
jline-builtins-3.19.0.jar                                      scala-library-2.12.13.jar                zinc-compile-core_2.12-1.5.0.jar
jline-reader-3.19.0.jar                                        scala-parser-combinators_2.12-1.1.2.jar  zinc-compile_2.12-1.5.0.jar
jline-style-3.19.0.jar                                         scala-reflect-2.12.13.jar                zinc-core_2.12-1.5.0.jar
jline-terminal-3.19.0.jar                                      scala-xml_2.12-1.3.0.jar                 zinc-lm-integration_2.12-1.5.0.jar
jline-terminal-jansi-3.19.0.jar                                scripted-plugin_2.12-1.5.0.jar           zinc-persist-core-assembly-1.5.0.jar
jline-terminal-jna-3.19.0.jar                                  shaded-jawn-parser_2.12-0.9.1.jar        zinc-persist_2.12-1.5.0.jar
jna-5.5.0.jar                                                  shaded-scalajson_2.12.jar                zinc_2.12-1.5.0.jar
jna-platform-5.5.0.jar                                         sjson-new-core_2.12-0.9.1.jar
jsch.jar                                                       sjson-new-murmurhash_2.12-0.9.1.jar

It has compiler-interface-1.5.0.jar but test-interface.jar has no version suffix.

lespea commented 3 years ago

I'm seeing the same problem; I also have the un-versioned test-interface. I removed that directory completely, re-ran sbt, and it recreated it the same way.

adpi2 commented 3 years ago

The test-interface.jar is also cached by Coursier. You can locate it with the cs fetch org.scala-sbt:test-interface:1.0 command. (Coursier installation instruction is here)

In my case I have:

> cs fetch org.scala-sbt:test-interface:1.0
/home/piquerez/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-sbt/test-interface/1.0/test-interface-1.0.jar

Can you share what you get? Also you can try to delete that file and run cs fetch again, it could help.

eed3si9n commented 3 years ago

https://github.com/sbt/sbt/blob/34a52a40f114474c4bac80c80cc6e38ba8089929/main/src/main/java/sbt/internal/MetaBuildLoader.java#L68

https://github.com/sbt/sbt/blob/34a52a40f114474c4bac80c80cc6e38ba8089929/main/src/main/java/sbt/internal/MetaBuildLoader.java#L89-L90

so I guess test-interface.jar would pass the contains test but fail the regex?

In https://github.com/sbt/launcher/pull/86 I wrote: https://github.com/sbt/launcher/blob/bb9921817b209d02ba456d40c8dac041c1c0fec4/launcher-implementation/src/main/scala/xsbt/boot/CoursierUpdate.scala#L156-L157

      val t =
        if (isScala) ....
        else new File(retrieveDir, downloaded.getName)
      Files.copy(downloaded.toPath, t.toPath, StandardCopyOption.REPLACE_EXISTING)

with the assumption that Coursier caches the file with specific pattern in the file name, but maybe it changed over the course of releases? A quick workaround might be to change the regex to accommodate test-interface.jar since some % of users will hit this.

adpi2 commented 3 years ago

Yes that will fix the problem for 1.5.x. But don't we need to do the same in 1.4.x and 1.3.x? That's why I think it would be interesting to understand why test-interface is not versioned in some cases.

jgulotta commented 3 years ago

I can confirm the naming difference was the root issue for me. Coursier had test-interface cached for me as test-interface-1.0.jar. My test-interface.jar under $HOME/.sbt/boot had the same sha256 as the one Coursier cached, so I renamed test-interface.jar to test-interface-1.0.jar and SBT works again.

I'm not sure if the bug is that the file is created without the version information in the first place or if allowing it to exist without the version information is correct, but renaming was a simple enough workaround that I can get around to work again.

eed3si9n commented 3 years ago

Yes that will fix the problem for 1.5.x. But don't we need to do the same in 1.4.x and 1.3.x?

Good point.

That's why I think it would be interesting to understand why test-interface is not versioned in some cases.

I'm guessing it's just the way older Coursier used to store files.

We might be able to guess the version number from the parent directory name?

lespea commented 3 years ago

I just deleted my entire $HOME/.sbt directory and it worked after that.

SandroGrzicic commented 3 years ago

Just to add a data point, I had the same issue, then copied the test-interface.jar file to test-interface-1.0.jar and SBT now starts up normally.

Previous SBT version (worked fine): 1.4.8; new SBT version: 1.5.0

JDK version: AdoptOpenJDK 15.0.2+7, MacOS 10.15.7

sbt -V output:

sbt version in this project: 1.5.0
sbt script version: 1.5.0
seoh commented 3 years ago

I had same issue. I got some hint from lespea's comment, I deleted a directory in ~/.sbt and run test one by one. I'm not sure why but my sbt works after deleting ~/.sbt/boot/scala-2.12.13. it could be a cache problem maybe or not.

eed3si9n commented 3 years ago

I'm reopening since older sbt would still have this issue.

agemooij commented 3 years ago

I ran into this problem as well and luckily found this issue. Everything worked again after deleting ~/.sbt/boot.

tpolecat commented 3 years ago

Yeah I think we need to keep this open. I had to delete ~/.sbt to get it working.

adpi2 commented 3 years ago

Thanks @eed3si9n for fixing this!

izzyreal commented 1 year ago

A similar issue cropped up on my system. I can reproduce it by running sbt in a directory where there's a project/build.properties that specifies sbt.version = 1.9.6. Other sbt versions work fine.

/Users/izmar.verhage/Library/Java/JavaVirtualMachines/corretto-17.0.5/Contents/Home/bin/java -Djline.terminal=jline.UnsupportedTerminal -Dsbt.log.noformat=true -Dfile.encoding=UTF-8 -Didea.managed=true -Dfile.encoding=UTF-8 -Didea.installation.dir=/Applications/IntelliJ IDEA 2023.3 EAP.app/Contents -jar /Users/izmar.verhage/Library/Application Support/JetBrains/IntelliJIdea2023.3/plugins/Scala/launcher/sbt-launch.jar
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at sbt.internal.XMainConfiguration.makeConfiguration(XMainConfiguration.java:105)
at sbt.internal.XMainConfiguration.run(XMainConfiguration.java:48)
at sbt.xMain.run(Main.scala:47)
at xsbt.boot.Launch$.$anonfun$run$1(Launch.scala:149)
at xsbt.boot.Launch$.withContextLoader(Launch.scala:176)
at xsbt.boot.Launch$.run(Launch.scala:149)
at xsbt.boot.Launch$.$anonfun$apply$1(Launch.scala:44)
at xsbt.boot.Launch$.launch(Launch.scala:159)
at xsbt.boot.Launch$.apply(Launch.scala:44)
at xsbt.boot.Launch$.apply(Launch.scala:21)
at xsbt.boot.Boot$.runImpl(Boot.scala:78)
at xsbt.boot.Boot$.run(Boot.scala:73)
at xsbt.boot.Boot$.main(Boot.scala:21)
at xsbt.boot.Boot.main(Boot.scala)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at sbt.internal.XMainConfiguration.makeConfiguration(XMainConfiguration.java:87)
... 13 more
Caused by: java.lang.NullPointerException
at java.base/java.util.ArrayDeque.addLast(ArrayDeque.java:303)
at java.base/java.util.ArrayDeque.add(ArrayDeque.java:494)
at java.base/jdk.internal.loader.URLClassPath.<init>(URLClassPath.java:159)
at java.base/jdk.internal.loader.URLClassPath.<init>(URLClassPath.java:176)
at java.base/java.net.URLClassLoader.<init>(URLClassLoader.java:116)
at sbt.internal.SbtInterfaceLoader.<init>(SbtInterfaceLoader.java:17)
at sbt.internal.MetaBuildLoader.makeLoader(MetaBuildLoader.java:152)
... 18 more
[error] [launcher] error during sbt launcher: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException

I'll keep the offending ~/.sbt directory around rather than removing it from my system completely, in case someone is interested in further analysis.