scala 如何让 sbt 使用本地 Maven 代理存储库(Nexus)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3770125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:26:19  来源:igfitidea点击:

how do I get sbt to use a local maven proxy repository (Nexus)?

scalamavenivynexussbt

提问by Harlan

I've got an sbt (Scala) project that currently pulls artifacts from the web. We'd like to move towards a corporate-standardized Nexus repository that would cache artifacts. From the Nexus documentation, I understand how to do that for Maven projects. But sbt obviously uses a different approach. (I understand Ivy is involved somehow, but I've never used it and don't understand how it works.)

我有一个 sbt (Scala) 项目,它目前从网上提取工件。我们希望转向可以缓存工件的企业标准化 Nexus 存储库。从 Nexus 文档中,我了解如何为 Maven 项目做到这一点。但是 sbt 显然使用了不同的方法。(我知道 Ivy 以某种方式参与其中,但我从未使用过它,也不了解它是如何工作的。)

How do I tell sbt and/or the underlying Ivy to use the corporate Nexus repository system for all dependencies? I'd like the answer to use some sort of project-level configuration file, so that new clones of our source repository will automatically use the proxy. (I.e., mucking about with per-user config files in a dot-directory is not viable.)

我如何告诉 sbt 和/或底层 Ivy 将企业 Nexus 存储库系统用于所有依赖项?我想要使​​用某种项目级配置文件的答案,以便我们源存储库的新克隆将自动使用代理。(即,在点目录中处理每个用户的配置文件是不可行的。)

Thanks!

谢谢!

回答by Robin Green

Step 1: Follow the instructions at Detailed Topics: Proxy Repositories, which I have summarised and added to below:

步骤 1:按照详细主题:代理存储库中的说明进行操作,我已将其总结并添加到以下内容中:

  1. (If you are using Artifactory, you can skip this step.) Create an entirely separateMaven proxy repository (or group) on your corporate Maven repository, to proxy ivy-stylerepositories such as these two important ones:

    This is needed because some repository managers cannot handle Ivy-style and Maven-style repositories being mixed together.

  2. Create a file repositories, listing both your main corporate repository and any extra one that you created in step 1, in the format shown below:

    [repositories]
      my-maven-proxy-releases: http://repo.example.com/maven-releases/
      my-ivy-proxy-releases: http://repo.example.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
    
  3. Either save that file in the .sbtdirectory inside your home directory, or specify it on the sbt command line:

    sbt -Dsbt.repository.config=<path-to-your-repo-file>
    
  1. (如果您使用的是 Artifactory,则可以跳过此步骤。)在您的公司 Maven 存储库上创建一个完全独立的Maven 代理存储库(或组),以代理常春藤风格的存储库,例如以下两个重要的存储库:

    这是必需的,因为一些存储库管理器无法处理混合在一起的 Ivy 风格和 Maven 风格的存储库。

  2. 创建一个文件repositories,列出您的主要公司存储库和您在步骤 1 中创建的任何额外存储库,格式如下:

    [repositories]
      my-maven-proxy-releases: http://repo.example.com/maven-releases/
      my-ivy-proxy-releases: http://repo.example.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
    
  3. 将该文件保存.sbt在您的主目录中的目录中,或者在 sbt 命令行中指定它:

    sbt -Dsbt.repository.config=<path-to-your-repo-file>
    

Good news for those using older versions of sbt: Even though, in the sbt 0.12.0 launcher jar at least, the boot properties files for older sbt versions don't contain the required line (the one that mentions repository.config), it will still work for those versions of sbt if you edit those files to add the required line, and repackage them into the sbt 0.12.0 launcher jar! This is because the feature is implemented in the launcher, not in sbt itself. And the sbt 0.12.0 launcher is claimed to be able to launch all versions of sbt, right back to 0.7!

对于使用旧版本 sbt 的人来说是个好消息:尽管至少在 sbt 0.12.0 启动器 jar 中,旧 sbt 版本的引导属性文件不包含所需的行(提到的那一行repository.config),它仍然可以工作对于那些版本的 sbt,如果您编辑这些文件以添加所需的行,并将它们重新打包到 sbt 0.12.0 启动器 jar 中!这是因为该功能是在启动器中实现的,而不是在 sbt 本身中实现。并且 sbt 0.12.0 启动器据称能够启动所有版本的 sbt,直接回到 0.7!

Step 2: To make sure external repositories are not being used, remove the default repositories from your resolvers. This can be done in one of two ways:

第 2 步:为确保未使用外部存储库,请从解析器中删除默认存储库。这可以通过以下两种方式之一完成:

  1. Add the command line option -Dsbt.override.build.repos=truementioned on the Detailed Topics page above. This will cause the repositories you specified in the file to override any repositories specified in any of your sbt files. This might only work in sbt 0.12 and above, though - I haven't tried it yet.
  2. Use fullResolvers := Seq(resolver(s) for your corporate maven repositories)in your build files, instead of resolvers ++=or resolvers :=or whatever you used to use.
  1. 添加-Dsbt.override.build.repos=true上面详细主题页面中提到的命令行选项。这将导致您在文件中指定的存储库覆盖在您的任何 sbt 文件中指定的任何存储库。不过,这可能仅适用于 sbt 0.12 及更高版本 - 我还没有尝试过。
  2. 使用fullResolvers := Seq(解析器(S)为您的企业Maven仓库)在你的构建文件,而不是resolvers ++=resolvers :=任何你曾经使用或。

回答by Harlan

OK, with some help from Mark Harrah on the sbt mailing list, I have an answer that works.

好的,在 sbt 邮件列表上 Mark Harrah 的帮助下,我有一个有效的答案。

My build class now looks like the following (plus some other repos):

我的构建类现在如下所示(加上一些其他存储库):

import sbt._

//By extending DefaultWebProject, we get Jetty support
class OurApplication(info: ProjectInfo) extends DefaultWebProject(info) {

  // This skips adding the default repositories and only uses the ones you added
  // explicitly. --Mark Harrah
  override def repositories = Set("OurNexus" at "http://our.nexus.server:9001/nexus/content/groups/public/") 
  override def ivyRepositories = Seq(Resolver.defaultLocal(None)) ++ repositories

  /* Squeryl */
  val squeryl = "org.squeryl" % "squeryl_2.8.0.RC3" % "0.9.4beta5"

  /* DATE4J */
  val date4j = "hirondelle.date4j" % "date4j" % "1.0" from "http://www.date4j.net/date4j.jar"

  // etc
}

Now, if I delete the Squeryl tree from my machine's .ivy2/cachedirectory, sbt tries to grab it from the Nexus tree with the appropriate URL. Problem solved!

现在,如果我从我机器的.ivy2/cache目录中删除 Squeryl 树,sbt 会尝试使用适当的 URL 从 Nexus 树中获取它。问题解决了!

回答by VonC

All you need is to define a property file sbt.boot.propertieswhich will allow you to:

您所需要的只是定义一个属性文件sbt.boot.properties,它允许您:

  • redefine the ivy cache location (I need that because it would be otherwise part of our roaming Windows profile, which is severely limited in disk space in our shop. See Issue 74)
  • define any other Maven repo you want
  • 重新定义常春藤缓存位置(我需要它,因为否则它会成为我们漫游 Windows 配置文件的一部分,这在我们商店的磁盘空间中受到严重限制。请参阅第 74 期
  • 定义您想要的任何其他 Maven 存储库
    C:\HOMEWARE\apps\sbt-0.74\sbt.boot.properties

    [scala]
      version: 2.7.7
    #  classifiers: sources, javadoc

    [app]
      org: org.scala-tools.sbt
      name: sbt
      version: read(sbt.version)
      class: sbt.xMain
      components: xsbti
      cross-versioned: true
      classifiers: sources, javadoc

    [repositories]
      local
      my-nexus: http://my.nexus/nexus/content/repositories/scala-tools/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
      maven-local
    #  sbt-db: http://databinder.net/repo/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
    #  maven-central
    #  scala-tools-releases
    #  scala-tools-snapshots

    [boot]
     directory: project/boot
     properties: project/build.properties
     prompt-create: Project does not exist, create new project?
     prompt-fill: true
     quick-option: true

    [log]
     level: debug

    [app-properties]
     project.name: quick=set(test), new=prompt(Name)[p], fill=prompt(Name)
     project.organization: new=prompt(Organization)[org.vonc]
     project.version: quick=set(1.0), new=prompt(Version)[1.0], fill=prompt(Version)[1.0]
     build.scala.versions: quick=set(2.8.0.RC2), new=prompt(Scala version)[2.8.0.RC2], fill=prompt(Scala version)[2.8.0.RC2]
     sbt.version: quick=set(0.7.4), new=prompt(sbt version)[0.7.4], fill=prompt(sbt version)[0.7.4]
     project.scratch: quick=set(true)
     project.initialize: quick=set(true), new=set(true)

    [ivy]
     cache-directory: C:\HOMEWARE\projects\.ivy2\cache

Note: this sbt.boot.propertiesfile is inspired from:

注意:此sbt.boot.properties文件的灵感来自:

I have commented any externalMaven repository definition, and added a reference to my own Nexus Maven repo.

我已经评论了任何外部Maven 存储库定义,并添加了对我自己的 Nexus Maven 存储库的引用。

The launcher may be configured in one of the following ways in increasing order of precedence:

  • Replace the /sbt/sbt.boot.propertiesfile in the jar.
  • Put a configuration file named sbt.boot.propertieson the classpath. Put it in the classpath root without the /sbtprefix.
  • Specify the location of an alternate configuration on the command line. This can be done by:
    • either specifying the location as the system property sbt.boot.properties
    • or as the first argument to the launcher prefixed by '@'.

The system property has lower precedence.
Resolution of a relative path is:

  • first attempted against the current working directory,
  • then against the user's home directory,
  • and then against the directory containing the launcher jar.

An error is generated if none of these attempts succeed.

启动器可以按以下方式之一按优先级递增的方式进行配置:

  • 替换/sbt/sbt.boot.properties的文件jar
  • sbt.boot.properties在类路径上放置一个名为的配置文件。将它放在没有/sbt前缀的类路径根中。
  • 在命令行上指定备用配置的位置。这可以通过以下方式完成:
    • 要么将位置指定为系统属性 sbt.boot.properties
    • 或作为以“ @”为前缀的启动器的第一个参数。

系统属性的优先级较低。
相对路径的解析为:

  • 首先尝试针对当前工作目录,
  • 然后针对用户的主目录,
  • 然后针对包含启动器 jar 的目录。

如果这些尝试均未成功,则会生成错误。



Define a sbt.bat wrapper (in order to be sure to specify yoursbt.boot.properties) like:

定义一个 sbt.bat 包装器(为了确保指定您的sbt.boot.properties),例如:

C:\HOMEWARE>more C:\HOMEWARE\bin\sbt.BAT
@echo off
set t=%~dp0
set adp0=%t:C:\="%"

set SBT_DIR=%adp0%..\apps\sbt-0.74
dir C:\%SBT_DIR%\sbt-launch-0.7.4.jar
# if needed, add your proxy settings
set PROXY_OPTIONS=-Dhttp.proxyHost=my.proxy -Dhttp.proxyPort=80xx -Dhttp.proxyUser=auser -Dhttp.proxyPassword=yyyy
set JAVA_OPTIONS=-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -Xmx512M -cp C:\HOMEWARE\apps\sbt-0.74\sbt-launch-0.7.4
set SBT_BOOT_PROPERTIES=-Dsbt.boot.properties="sbt.boot.properties"
cmd /C C:\HOMEWARE\apps\jdk4eclipse\bin\java.exe %PROXY_OPTIONS% %JAVA_OPTIONS% %SBT_BOOT_PROPERTIES% -jar C:\HOMEWARE\apps\sbt-0.74\sbt-launch-0.7.4.jar %*

And your sbt will download artifacts onlyfrom:

和你的SBT会下载神器从:

  • your Nexus
  • your local Maven repo.
  • 你的 Nexus
  • 您本地的 Maven 存储库。


Just tested at home with an old Nexus opensource 1.6 I had running, java 1.6, sbt07.4

刚刚在家里用我运行的旧 Nexus 开源 1.6、java 1.6、sbt07.4 进行了测试

C:\Prog\Java\jdk1.6.0_18\jre\bin\java  -Xmx512M -Dsbt.boot.properties=sbt.boot.properties - jar "c:\Prog\Scala\sbt\sbt-launch-0.7.4.jar"  

That gives:

这给出了:

[success] Build completed successfully.
C:\Prog\Scala\tests\pp>sbt
Getting Scala 2.8.0 ...
downloading http://localhost:8081/nexus/content/repositories/scala/org/scala-lang/scala-compiler/2.8.0/scala-compiler-2.
8.0.jar ...
        [SUCCESSFUL ] org.scala-lang#scala-compiler;2.8.0!scala-compiler.jar (311ms)
downloading http://localhost:8081/nexus/content/repositories/scala/org/scala-lang/scala-library/2.8.0/scala-library-2.8.
0.jar ...
        [SUCCESSFUL ] org.scala-lang#scala-library;2.8.0!scala-library.jar (185ms)
:: retrieving :: org.scala-tools.sbt#boot-scala
        confs: [default]
        2 artifacts copied, 0 already retrieved (14484kB/167ms)
[info] Building project test 0.1 against Scala 2.8.0
[info]    using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7

If I try a funny value in the sbt.boot.properties file:

如果我在 sbt.boot.properties 文件中尝试一个有趣的值:

C:\Prog\Scala\tests\pp>sbt
Getting Scala 2.9.7 ...

:: problems summary ::
:::: WARNINGS
                module not found: org.scala-lang#scala-compiler;2.9.7
        ==== nexus: tried
          http://localhost:8081/nexus/content/repositories/scala/org/scala-lang/scala-compiler/2.9.7/scala-compiler-2.9.7.pom
          -- artifact org.scala-lang#scala-compiler;2.9.7!scala-compiler.jar:
          http://localhost:8081/nexus/content/repositories/scala/org/scala-lang/scala-compiler/2.9.7/scala-compiler-2.9.7.jar

So it does limit itself to the two repo I defined:

所以它确实将自己限制在我定义的两个 repo 中:

[repositories]
nexus:  http://localhost:8081/nexus/content/repositories/scala
nexus2: http://localhost:8081/nexus/content/repositories/scala, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]

(I commented everything else: local, maven-local, ...)

(我评论的一切:localmaven-local,...)

If I comment allrepositories and put a funny value (2.7.9) for the scala version in the sbt.boot.properties, I do get (like the OP did)

如果我评论的所有存储库,并把一个有趣的值(2.7.9)在阶的版本sbt.boot.properties,我得到(如OP一样)

C:\Prog\Scala\tests\pp>sbt
Error during sbt execution: No repositories defined.

If I put 2.7.7 (while still having allrepo commented), yes, it won't generate an error:

如果我放了 2.7.7(同时仍然对所有repo 进行了评论),是的,它不会产生错误:

C:\Prog\Scala\tests\pp>sbt
[info] Building project test 0.1 against Scala 2.8.0
[info]    using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7

But that's only because it already had downloaded scala2.8.0 during my previous tries.
If I remove that library from my project/bootdirectory, then it will throw an Exception:

但这只是因为它在我之前的尝试中已经下载了 scala2.8.0。
如果我从我的project/boot目录中删除那个库,那么它会抛出一个异常:

[info]    using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7
> C:\Prog\Scala\tests\pp>sbt
Error during sbt execution: No repositories defined.
        at xsbt.boot.Pre$.error(Pre.scala:18)
        at xsbt.boot.Update.addResolvers(Update.scala:197)
...
        at xsbt.boot.Boot$.main(Boot.scala:15)
        at xsbt.boot.Boot.main(Boot.scala)
Error loading project: Error during sbt execution: No repositories defined.

回答by foxundermon

edit the config file in sbt_home/conf "sbtconfig.txt"

编辑 sbt_home/conf 中的配置文件“sbtconfig.txt”

add two line

添加两行

-Dsbt.override.build.repos=true
-Dsbt.repository.config="C:/Program Files (x86)/sbt/conf/repo.properties"

the repo.properties content is

repo.properties 内容是

[repositories]
    local
    public: http://222.vvfox.com/public  <-fix this ,write your local nexus group url

回答by ozone

Well this has bugged me for a while so I found a guy that has written an SBT plugin for maven out on github called maven-sbtso all you have to do is include it in your plugins project and make your project mixin with maven.MavenDependencies and all your operations like update and publish-local work with your local maven. The nice thing about that is if you are like me, your org is all maven. So, all you libs are in you local maven repo but if for some reason you build with sbt first, then you start getting a bunch or jars in ivy too. What a waste of space, and time since you will still need to get them for your maven builds.

嗯,这让我困扰了一段时间,所以我找到了一个人,他在 github 上为 maven 编写了一个 SBT 插件,名为maven-sbt,所以你要做的就是将它包含在你的插件项目中,并使你的项目与 maven.MavenDependencies 混合并且您的所有操作(例如更新和发布本地)都与您的本地 Maven 一起工作。这样做的好处是,如果你像我一样,你的组织都是 maven。所以,你所有的库都在你本地的 maven 仓库中,但如果出于某种原因你首先用 sbt 构建,那么你也开始在常春藤中获得一堆或罐子。多么浪费空间和时间,因为您仍然需要为您的 Maven 构建获取它们。

That said, I wish this were built into sbt so I would not need to add it to every project. Maybe as a processor at least. He mentioned in one thing I read that he would like to add it to 0.9 but I have not been able to find it.

也就是说,我希望它被内置到 sbt 中,这样我就不需要将它添加到每个项目中。也许至少作为处理器。他在我读到的一件事中提到他想将其添加到 0.9,但我找不到它。

回答by mehtunguh

I got this error because I had a blank file in ~/.sbt/repositories. Both adding repositories to the file and removing the file solved the problem.

我收到此错误是因为我在~/.sbt/repositories. 向文件添加存储库和删除文件都解决了问题。