2

My question is: Why can't I publish from SBT to my server via SSH?

Context:

I am developing a scala library and I want to publish it to a remote repository with SBT v0.12.3 over SSH (using an SFTP resolver). The relevant portion of my project/Build.scala SBT settings file is configured as prescribed by https://github.com/harrah/xsbt/wiki/Resolvers:

publishTo <<= version { v =>
    Some(Resolver.sftp(
        "My Repository",
        "example.com",
        "/var/www/public_html/repositories/" + (
            if (v.trim.endsWith("SNAPSHOT")) { "snapshots" } else { "releases" }
        )
    ))
},
resolvers ++= Seq(
    {
        import java.io.File
        val privateKeyFile: File = new File(sys.env("HOME") + "/.ssh/id_rsa")
        Resolver.ssh("scala-sh", "example.com") as("my-username", privateKeyFile) withPermissions("0644")
    },
    ...
),

When I run sbt publish, things go fine until the authorization, where it still attempts to prompt me for login/password. When I run it locally, it brings up the username/password prompt, and when I try to publish remotely while SSH'd in to a machine it fails with a java.awt.HeadlessException. The result appears to be that the desired private-key type of authentication is not being attempted.

Here is a log of the remote session publish attempt:

> sbt-version
[info] 0.12.3

> publish
[info] Packaging /home/me/my-lib/target/scala-2.10.1/my-lib_2.10.1-SNAPSHOT-sources.jar ...
[info] Done packaging.
[info] Wrote /home/me/my-lib/target/scala-2.10.1/my-lib_2.10.1-SNAPSHOT.pom
[info] :: delivering :: org.example#my-lib_2.10.1;SNAPSHOT :: SNAPSHOT :: release :: Sun Apr 21 12:48:59 PDT 2013
[info]  delivering ivy file to /home/me/my-lib/target/scala-2.10.1/ivy-SNAPSHOT.xml
[info] Generating API documentation for main sources...
model contains 75 documentable templates
[info] API documentation generation successful.
[info] Packaging /home/me/my-lib/target/scala-2.10.1/my-lib_2.10.1-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
[info] Packaging my-lib-SNAPSHOT.jar ...
[info] Done packaging.
[trace] Stack trace suppressed: run last *:publish for the full output.
[error] (*:publish) java.awt.HeadlessException:
[error] No X11 DISPLAY variable was set, but this program performed an operation which requires it.
[error] Total time: 35 s, completed Apr 21, 2013 12:49:33 PM

It fails because there is no X11 display. This is unexpected behavior because the SBT project configuration is set to use private key authentication (see resolvers above).

So far I can think of 2 possible causes for the problem, detailed below.

Possible cause #1: Misconfiguration of SBT

Is there a problem in my configuration above?

Possible cause #2: Hitting an Ivy bug from an old version

At time of writing, I am using the latest SBT, 0.12.3. Maybe the version of Ivy being used by SBT is old. The more I think about it, the less likely this seems, but I haven't been able to rule it out yet.

How can I find out what version of Ivy SBT is using?

and then..

IF it is old, is there a way to get SBT to use a newer version of ivy?

There is another relevant question, see ivy ssh publisher, which references[0] an Old Ivy bug which caused java.awt.HeadlessExceptions.

[0] ivy ssh publisher

  • "Which version of Ivy are you using? There is a Jira Bug for Version 2.0 : issues.apache.org/jira/browse/IVY-783 which should be fixed now."

  • "Seems like if I upgrade to ivy 2.3 rc-2. SSH publish works."

Community
  • 1
  • 1
Jay Taylor
  • 13,185
  • 11
  • 60
  • 85
  • The full stack trace would probably help a lot to diagnose this. Can you grab it Does `Stack trace suppressed: run last *:publish for the full output` give you enough info to recover it? – Andrew Janke Apr 22 '13 at 10:42

1 Answers1

1

It may after all be an Ivy version related bug. I am using SBT 0.12.2, which AFAIK is using Ivy 2.0. I am looking at the Ivy cache, located in ~/.ivy2/cache/, where Ivy creates a bunch of XML log files for the dependencies it has resolved, and I can see Ivy module version 2.0 in every XML file generated.

I don't know of a way to update the Ivy version used by SBT, but judging by the default SBT documentation, a possible solution is to manually upgrade Ivy and make sure the default machine wide path points to the right Ivy version.

Then run sbt clean or sbt update to re-fetch dependencies and allow Ivy to regenerate XML config files, etc. for the new Ivy version. More on SBT dependency management HERE:

Ivy Home Directory

By default, sbt uses the standard Ivy home directory location ${user.home}/.ivy2/. This can be configured machine-wide, for use by both the sbt launcher and by projects, by setting the system property sbt.ivy.home in the sbt startup script (described in Setup).

For example:

java -Dsbt.ivy.home=/tmp/.ivy2/ ...

Update

By checking the SBT Scala source code for the latest version, the version issue is confirmed again. Even SBT 0.13 appears to be using Ivy version 2.0.0, not 2.3. Have a look at the SBT source code, specifically the last few lines of THIS file.

flavian
  • 28,161
  • 11
  • 65
  • 105
  • I've reproduced you're observations by removing my ~/.ivy2 directory and running ``sbt clean``. This displayed ``org.apache.ivy#ivy;2.2.0!ivy.jar (542ms)`` when it grabbed the ivy library. At any rate, I'll file this as a bug with the SBT project. Thank you for your help alex23. – Jay Taylor Apr 22 '13 at 16:43
  • I did the override like you said, and renamed all ivy-*2.3* to ivy-*2.2*, but I still saw ``delivering ivy file to /Users/me/my-lib/target/scala-2.10.1/ivy-2.1.22-SNAPSHOT.xml`` when I ran ``sbt publish``, and it still prompted me for username/password. – Jay Taylor Apr 22 '13 at 17:26